diff options
author | Shireesh Anjal <shireesh@gluster.com> | 2011-11-25 20:13:35 +0530 |
---|---|---|
committer | Shireesh Anjal <shireesh@gluster.com> | 2011-11-25 20:13:35 +0530 |
commit | 1142b0e41de39010de7845cf70d71dbb001fc1dc (patch) | |
tree | 3513487f65c1a7df47996bd2852393aceaac1b8a /src/org.gluster.storage.management.gateway.scripts/src | |
parent | 92c52d8edf285945d31e446503fc742fde9dcc49 (diff) |
Renamed projects / packages com.gluster.* to org.gluster.*
Diffstat (limited to 'src/org.gluster.storage.management.gateway.scripts/src')
48 files changed, 3983 insertions, 0 deletions
diff --git a/src/org.gluster.storage.management.gateway.scripts/src/backend/DiskUtils.py b/src/org.gluster.storage.management.gateway.scripts/src/backend/DiskUtils.py new file mode 100644 index 00000000..4d1b701a --- /dev/null +++ b/src/org.gluster.storage.management.gateway.scripts/src/backend/DiskUtils.py @@ -0,0 +1,198 @@ +#!/usr/bin/python +# Copyright (C) 2011 Gluster, Inc. <http://www.gluster.com> +# This file is part of Gluster Management Gateway. +# + +import os +import sys +p1 = os.path.abspath(os.path.dirname(sys.argv[0])) +p2 = "%s/common" % os.path.dirname(p1) +if not p1 in sys.path: + sys.path.append(p1) +if not p2 in sys.path: + sys.path.append(p2) +import glob +import Globals +import Utils +import FsTabUtils + +def _stripDev(device): + if Utils.isString(device) and device.startswith("/dev/"): + return device[5:] + return device + + +def _addDev(deviceName): + if Utils.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 Utils.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 getDiskPartitionByLabel(label): + ## TODO: Finding needs to be enhanced + labelFile = "/dev/disk/by-label/%s" % label + if os.path.exists(labelFile): + if os.path.islink(labelFile): + return getDeviceName(os.path.realpath(labelFile)) + return None + + +def getDiskPartitionLabel(device): + rv = Utils.runCommand("e2label %s" % device, output=True, root=True) + if rv["Status"] == 0: + return rv["Stdout"].strip() + return False + + +def getDiskInfo(diskNameList=None): + procPartitionsDict = getProcPartitions() + diskDict = {} + for name, values in procPartitionsDict.iteritems(): + values["Description"] = None + values["Uuid"] = None + values["FsType"] = None + values["MountPoint"] = None + values["SpaceInUse"] = None + values["Member"] = None + ## extras ?!?! + values["Init"] = False + values["Status"] = None + values["Interface"] = None + values["DriveType"] = None + values["Type"] = None + values["FsVersion"] = None + values["ReadOnlyAccess"] = None + + device = getDevice(name) + values["Uuid"] = getUuidByDiskPartition(device) + rv = Utils.runCommand("blkid -c /dev/null -o value %s" % device, output=True, root=True) + if rv["Status"] == 0: + lines = rv["Stdout"].strip().split("\n") + values["FsType"] = lines[-1].strip() + values["MountPoint"] = getDeviceMountPoint(device) + if values["FsType"]: + values["Init"] = True + if values["MountPoint"]: + rv = Utils.runCommand(["df", values["MountPoint"]], output=True) + if rv["Status"] == 0: + try: + values["SpaceInUse"] = long(rv["Stdout"].split("\n")[1].split()[2]) + except IndexError, e: + pass + except ValueError, e: + pass + if os.path.isdir("/sys/block/%s" % name): + model = Utils.readFile("/sys/block/%s/device/model" % name) + vendor = Utils.readFile("/sys/block/%s/device/vendor" % name) + values["Description"] = "%s %s" % (model.strip(), vendor.strip()) + values["Partitions"] = {} + diskDict[name] = values + + for diskName in diskDict.keys(): + del procPartitionsDict[diskName] + for partName, values in procPartitionsDict.iteritems(): + if os.path.isdir("/sys/block/%s/%s" % (diskName, partName)): + diskDict[diskName]["Partitions"][partName] = values + + procMdstatDict = getProcMdstat() + for name, values in procMdstatDict.iteritems(): + try: + diskDict[name]["Description"] = "Software Raid Array - %s - %s" % (values["Type"], values["Status"]) + diskDict[name]["Member"] = values["Member"] + except KeyError, e: + pass + + diskNameList = getDeviceName(diskNameList) + if Utils.isString(diskNameList): + diskNameList = [diskNameList] + + if not diskNameList: + return diskDict + + outputDict = {} + for diskName in list(set(diskDict.keys()).intersection(set(diskNameList))): + outputDict[diskName] = diskDict[diskName] + return outputDict + + +def isDataDiskPartitionFormatted(device): + rv = Utils.runCommand("blkid -c /dev/null -o value %s" % device, output=True, root=True) + if rv["Status"] != 0: + return False + + uuid = getUuidByDiskPartition(device) + if not uuid: + return False + + for fsTabEntry in FsTabUtils.readFsTab(): + if fsTabEntry["Device"] == ("UUID=%s" % uuid) or fsTabEntry["Device"] == device: + return True + return False + + +def isDiskInFormatting(device): + DEVICE_FORMAT_LOCK_FILE = "/var/lock/%s.lock" % device + return os.path.exists(DEVICE_FORMAT_LOCK_FILE) + + +def getDeviceMountPoint(device): + lines = Utils.readFile("/proc/mounts", lines=True) + uuid = getUuidByDiskPartition(device) + for line in lines: + tokens = line.split() + if tokens[0] == device or (uuid and tokens[0].endswith(uuid)): + return tokens[1] + return None + +def getProcPartitions(): + procPartitionsDict = {} + s = Utils.readFile("/proc/partitions", lines=True) + for line in s[2:]: + tokens = line.strip().split() + procPartitionsDict[tokens[3]] = {"Size" : long(tokens[2])} + return procPartitionsDict + +def getProcMdstat(): + raidArrayDict = {} + lines = Utils.readFile("/proc/mdstat", lines=True) + for line in lines[1:]: + tokens = line.strip().split() + if not tokens: + continue + if tokens[0].startswith("md"): + raidArrayDict[tokens[0]] = {"Status" : tokens[2], "Type" : tokens[3], "Member" : [token.split('[')[0] for token in tokens[4:]]} + return raidArrayDict diff --git a/src/org.gluster.storage.management.gateway.scripts/src/backend/FsTabUtils.py b/src/org.gluster.storage.management.gateway.scripts/src/backend/FsTabUtils.py new file mode 100644 index 00000000..653d0dda --- /dev/null +++ b/src/org.gluster.storage.management.gateway.scripts/src/backend/FsTabUtils.py @@ -0,0 +1,83 @@ +#!/usr/bin/python +# Copyright (C) 2011 Gluster, Inc. <http://www.gluster.com> +# This file is part of Gluster Management Gateway. +# + +import os +import sys +p1 = os.path.abspath(os.path.dirname(sys.argv[0])) +p2 = "%s/common" % os.path.dirname(p1) +if not p1 in sys.path: + sys.path.append(p1) +if not p2 in sys.path: + sys.path.append(p2) +import Utils +import Globals + +def readFsTab(fsTabFile=Globals.FSTAB_FILE): + lines = Utils.readFile(fsTabFile) + + fsTabEntryList = [] + for line in lines: + 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, e: + pass + if fsTabEntry["Device"] and fsTabEntry["MountPoint"] and fsTabEntry["FsType"] and fsTabEntry["Options"]: + fsTabEntryList.append(fsTabEntry) + return fsTabEntryList + +def writeFsTab(fsTabEntryList, fsTabFile=Globals.FSTAB_FILE): + try: + fsTabfp = open(fsTabFile, "w") + for fsTabEntry in fsTabEntryList: + fsTabfp.write("%s\t%s\t%s\t%s\t%s\t%s\n" % + (fsTabEntry["Device"], fsTabEntry["MountPoint"], + fsTabEntry["FsType"], fsTabEntry["Options"], + fsTabEntry["DumpOption"], fsTabEntry["fsckOrder"])) + fsTabfp.close() + except IOError, e: + log("writeFsTab(): " + str(e)) + return False + return True + +def addFsTabEntry(fsTabEntry, fsTabFile=Globals.FSTAB_FILE): + try: + fsTabfp = open(fsTabFile, "a") + fsTabfp.write("%s\t%s\t%s\t%s\t%s\t%s\n" % + (fsTabEntry["Device"], fsTabEntry["MountPoint"], + fsTabEntry["FsType"], fsTabEntry["Options"], + fsTabEntry["DumpOption"], fsTabEntry["fsckOrder"])) + fsTabfp.close() + except IOError, e: + log("addFsTabEntry(): " + str(e)) + return False + return True + +def removeFsTabEntry(fsTabEntry, fsTabFile=Globals.FSTAB_FILE): + fsTabEntryList = readFsTab(fsTabFile) + if not fsTabEntryList: + return False + + try: + fsTabEntryList.remove(fsTabEntry) + except ValueError, e: + return False + + return writeFsTab(fsTabEntryList, fsTabFile) + diff --git a/src/org.gluster.storage.management.gateway.scripts/src/backend/NetworkUtils.py b/src/org.gluster.storage.management.gateway.scripts/src/backend/NetworkUtils.py new file mode 100755 index 00000000..ff73af6f --- /dev/null +++ b/src/org.gluster.storage.management.gateway.scripts/src/backend/NetworkUtils.py @@ -0,0 +1,152 @@ +# Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> +# This file is part of Gluster Storage Platform. +# + +import os +import sys +p1 = os.path.abspath(os.path.dirname(sys.argv[0])) +p2 = "%s/common" % os.path.dirname(p1) +if not p1 in sys.path: + sys.path.append(p1) +if not p2 in sys.path: + sys.path.append(p2) +import Globals +import Utils + +def readResolvConfFile(fileName=None): + nameServerList = [] + domain = None + searchDomain = None + if not fileName: + fileName = Globals.RESOLV_CONF_FILE + lines = Utils.readFile(fileName, lines=True) + for line in lines: + tokens = line.split("#")[0].strip().split() + if len(tokens) < 2: + continue + if tokens[0].upper() == "NAMESERVER": + 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 + + +def readIfcfgConfFile(deviceName, root=""): + conf = {} + fileName = "%s%s/ifcfg-%s" % (root, Globals.SYSCONFIG_NETWORK_DIR, deviceName) + lines = Utils.readFile(fileName, lines=True) + for line in lines: + tokens = line.split("#")[0].split("=") + if len(tokens) != 2: + continue + conf[tokens[0].strip().lower()] = tokens[1].strip() + return conf + + +def getBondMode(deviceName, fileName=None): + if not fileName: + fileName = Globals.MODPROBE_CONF_FILE + lines = Utils.readFile(fileName, lines=True) + for line in lines: + 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 + + +def getNetDeviceList(root=""): + netDeviceList = {} + for deviceName in os.listdir("/sys/class/net/"): + netDevice = {} + netDevice["description"] = None + netDevice["hwaddr"] = None + netDevice["type"] = None + netDevice["onboot"] = None + netDevice["bootproto"] = 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["speed"] = None + netDevice["device"] = deviceName + netDevice["description"] = deviceName + netDevice["ipaddr"] = None + netDevice["netmask"] = None + netDevice["hwaddr"] = Utils.readFile("/sys/class/net/%s/address" % deviceName).strip() + + rv = Utils.runCommand("ifconfig %s" % deviceName, output=True) + if rv["Status"] == 0: + for line in rv["Stdout"].split("\n"): + if line.find("Link encap:") != -1: + netDevice["type"] = line.split("Link encap:")[1].split()[0] + continue + if line.find("inet addr:") != -1: + tokens = line.split("inet addr:")[1].split() + netDevice["ipaddr"] = tokens[0] + if line.find("Mask:") != -1: + netDevice["netmask"] = line.split("Mask:")[1].split()[0] + #print tokens[1].split(":")[1] + + rv = Utils.runCommand("ethtool %s" % deviceName, output=True, root=True) + if rv["Status"] == 0: + for line in rv["Stdout"].split("\n"): + if line.find("Speed: ") != -1: + netDevice["speed"] = line.split("Speed: ")[1].upper().split("MB")[0] + elif line.find("Link detected: ") != -1: + netDevice["link"] = line.split("Link detected: ")[1] + + rv = Utils.runCommand("route -n", output=True, root=True) + if rv["Status"] == 0: + for line in rv["Stdout"].split("\n"): + tokens = line.split() + if len(tokens) == 8 and tokens[-1] == deviceName and tokens[3] == "UG": + netDevice["gateway"] = tokens[1] + + netDevice["mode"] = getBondMode(deviceName, root + Globals.MODPROBE_CONF_FILE) + + netDeviceList[deviceName] = netDevice + + conf = readIfcfgConfFile(deviceName, root) + if not conf: + continue + try: + if not netDevice["ipaddr"]: + netDevice["ipaddr"] = conf["ipaddr"] + if not netDevice["netmask"]: + netDevice["netmask"] = conf["netmask"] + if not netDevice["gateway"]: + netDevice["gateway"] = conf["gateway"] + netDevice["onboot"] = conf["onboot"] + netDevice["bootproto"] = conf["bootproto"] + netDevice["peerdns"] = conf["peerdns"] + netDevice["autodns"] = conf["autodns"] + netDevice["dns1"] = conf["dns1"] + netDevice["dns2"] = conf["dns2"] + netDevice["dns3"] = conf["dns3"] + netDevice["master"] = conf["master"] + netDevice["slave"] = conf["slave"] + netDevice["nmcontrolled"] = conf["nmcontrolled"] + except KeyError, e: + pass + return netDeviceList diff --git a/src/org.gluster.storage.management.gateway.scripts/src/backend/VolumeUtils.py b/src/org.gluster.storage.management.gateway.scripts/src/backend/VolumeUtils.py new file mode 100644 index 00000000..5476e090 --- /dev/null +++ b/src/org.gluster.storage.management.gateway.scripts/src/backend/VolumeUtils.py @@ -0,0 +1,95 @@ +# Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> +# This file is part of Gluster Storage Platform. +# + +import os +import sys +p1 = os.path.abspath(os.path.dirname(sys.argv[0])) +p2 = "%s/common" % os.path.dirname(p1) +if not p1 in sys.path: + sys.path.append(p1) +if not p2 in sys.path: + sys.path.append(p2) +import Globals +import Utils + + +def readVolumeSmbConfFile(fileName=Globals.VOLUME_SMBCONF_FILE): + entryList = [] + lines = Utils.readFile(fileName, lines=True) + for line in lines: + 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()) + 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: + Utils.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) + Utils.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: + Utils.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) + return True + except OSError, e: + Utils.log("Failed to remove file %s: %s" % (volumeFile, str(e))) + return False + diff --git a/src/org.gluster.storage.management.gateway.scripts/src/backend/add_user_cifs.py b/src/org.gluster.storage.management.gateway.scripts/src/backend/add_user_cifs.py new file mode 100755 index 00000000..2e1a1574 --- /dev/null +++ b/src/org.gluster.storage.management.gateway.scripts/src/backend/add_user_cifs.py @@ -0,0 +1,65 @@ +#!/usr/bin/python +# Copyright (C) 2011 Gluster, Inc. <http://www.gluster.com> +# This file is part of Gluster Management Gateway. +# + +import os +import sys +p1 = os.path.abspath(os.path.dirname(sys.argv[0])) +p2 = "%s/common" % os.path.dirname(p1) +if not p1 in sys.path: + sys.path.append(p1) +if not p2 in sys.path: + sys.path.append(p2) +import grp +import pwd +import Globals +import Utils + +def main(): + if len(sys.argv) < 4: + sys.stderr.write("usage: %s UID USERNAME PASSWORD\n" % os.path.basename(sys.argv[0])) + sys.exit(-1) + + try: + uid = int(sys.argv[1]) + except ValueError, e: + sys.stderr.write("invalid uid %s\n" % sys.argv[1]) + sys.exit(-2) + userName = sys.argv[2] + password = sys.argv[3] + + try: + groupInfo = grp.getgrnam(userName) + if uid != groupInfo.gr_gid: + Utils.log("group %s exists with different gid %s\n" % (userName, groupInfo.gr_gid)) + sys.stderr.write("Group %s exists with different gid %s\n" % (userName, groupInfo.gr_gid)) + sys.exit(1) + except KeyError, e: + if Utils.runCommand("groupadd -g %s %s" % (uid, userName)) != 0: + Utils.log("failed to add group %s gid %s\n" % (userName, uid)) + sys.stderr.write("Failed to add group %s gid %s\n" % (userName, uid)) + sys.exit(2) + try: + userInfo = pwd.getpwnam(userName) + if uid != userInfo.pw_uid: + Utils.log("user %s exists with different uid %s\n" % (userName, userInfo.pw_uid)) + sys.stderr.write("User %s exists with different uid %s\n" % (userName, userInfo.pw_uid)) + sys.exit(3) + except KeyError, e: + command = ["useradd", "-c", Globals.VOLUME_USER_DESCRIPTION, "-M", "-d", "/", "-s", "/sbin/nologin", "-u", str(uid), "-g", str(uid), userName] + if Utils.runCommand(command) != 0: + Utils.log("failed to add user %s uid %s\n" % (userName, uid)) + sys.stderr.write("Failed to add user %s uid %s\n" % (userName, uid)) + sys.exit(4) + + if Utils.runCommand("smbpasswd -s -a %s" % userName, + input="%s\n%s\n" % (password, password)) != 0: + Utils.log("failed to set smbpassword of user %s\n" % userName) + sys.stderr.write("Failed to set smbpassword of user %s\n" % userName) + sys.exit(5) + sys.exit(0) + + +if __name__ == "__main__": + main() diff --git a/src/org.gluster.storage.management.gateway.scripts/src/backend/clear_volume_directory.py b/src/org.gluster.storage.management.gateway.scripts/src/backend/clear_volume_directory.py new file mode 100755 index 00000000..374a7e9c --- /dev/null +++ b/src/org.gluster.storage.management.gateway.scripts/src/backend/clear_volume_directory.py @@ -0,0 +1,48 @@ +#!/usr/bin/python +# Copyright (C) 2011 Gluster, Inc. <http://www.gluster.com> +# This file is part of Gluster Management Gateway. +# + +import os +import sys +p1 = os.path.abspath(os.path.dirname(sys.argv[0])) +p2 = "%s/common" % os.path.dirname(p1) +if not p1 in sys.path: + sys.path.append(p1) +if not p2 in sys.path: + sys.path.append(p2) +import time +import Utils +from optparse import OptionParser + +def main(): + parser = OptionParser() + parser.add_option("-d", "--delete", dest="todelete", action="store_true", default=False, help="force delete") + (options, args) = parser.parse_args() + + if len(args) != 1: + sys.stderr.write("usage: %s [-d | --delete] VOLUME_PATH\n" % os.path.basename(sys.argv[0])) + sys.exit(-1) + + volumeDirectory = args[0] + if not os.path.exists(volumeDirectory): + sys.stderr.write("Given volume directory path:%s does not exists\n" % volumeDirectory) + sys.exit(1) + + if '/' == volumeDirectory[-1]: + volumeDirectory = volumeDirectory[:-1] + + newVolumeDirectoryName = "%s_%s" % (volumeDirectory, time.time()) + if Utils.runCommand("mv -f %s %s" % (volumeDirectory, newVolumeDirectoryName), root=True) != 0: + sys.stderr.write("Failed to rename volume directory\n") + sys.exit(2) + + if options.todelete: + process = Utils.runCommandBG("rm -fr %s" % newVolumeDirectoryName, root=True) + if not process: + sys.exit(3) + sys.exit(0) + + +if __name__ == "__main__": + main() diff --git a/src/org.gluster.storage.management.gateway.scripts/src/backend/create_volume_cifs.py b/src/org.gluster.storage.management.gateway.scripts/src/backend/create_volume_cifs.py new file mode 100755 index 00000000..5a27ab87 --- /dev/null +++ b/src/org.gluster.storage.management.gateway.scripts/src/backend/create_volume_cifs.py @@ -0,0 +1,47 @@ +#!/usr/bin/python +# Copyright (C) 2011 Gluster, Inc. <http://www.gluster.com> +# This file is part of Gluster Management Gateway. +# + +import os +import sys +p1 = os.path.abspath(os.path.dirname(sys.argv[0])) +p2 = "%s/common" % os.path.dirname(p1) +if not p1 in sys.path: + sys.path.append(p1) +if not p2 in sys.path: + sys.path.append(p2) +import Globals +import Utils +import VolumeUtils + +def main(): + if len(sys.argv) < 3: + sys.stderr.write("usage: %s VOLUME_NAME USER1 USER2 ...\n" % os.path.basename(sys.argv[0])) + sys.exit(-1) + + volumeName = sys.argv[1] + userList = sys.argv[2:] + + volumeMountDirName = "%s/%s" % (Globals.REEXPORT_DIR, volumeName) + try: + if not os.path.exists(volumeMountDirName): + os.mkdir(volumeMountDirName) + except OSError, e: + Utils.log("failed creating %s: %s\n" % (volumeMountDirName, str(e))) + sys.stderr.write("Failed creating %s: %s\n" % (volumeMountDirName, str(e))) + sys.exit(1) + + if not VolumeUtils.writeVolumeCifsConfiguration(volumeName, userList): + sys.stderr.write("Failed to write volume cifs configuration\n") + sys.exit(2) + + if Utils.runCommand("service smb reload") != 0: + Utils.log("Failed to reload smb service") + sys.stderr.write("Failed to reload smb service\n") + sys.exit(3) + sys.exit(0) + + +if __name__ == "__main__": + main() diff --git a/src/org.gluster.storage.management.gateway.scripts/src/backend/delete_user_cifs.py b/src/org.gluster.storage.management.gateway.scripts/src/backend/delete_user_cifs.py new file mode 100755 index 00000000..aeda989f --- /dev/null +++ b/src/org.gluster.storage.management.gateway.scripts/src/backend/delete_user_cifs.py @@ -0,0 +1,31 @@ +#!/usr/bin/python +# Copyright (C) 2011 Gluster, Inc. <http://www.gluster.com> +# This file is part of Gluster Management Gateway. +# + +import os +import sys +p1 = os.path.abspath(os.path.dirname(sys.argv[0])) +p2 = "%s/common" % os.path.dirname(p1) +if not p1 in sys.path: + sys.path.append(p1) +if not p2 in sys.path: + sys.path.append(p2) +import Utils + +def main(): + if len(sys.argv) < 2: + sys.stderr.write("usage: %s USERNAME\n" % os.path.basename(sys.argv[0])) + sys.exit(-1) + + userName = sys.argv[1] + + if Utils.runCommand("userdel %s" % userName) != 0: + Utils.log("failed to remove user name:%s\n" % userName) + sys.stderr.write("Failed to remove user name:%s\n" % userName) + sys.exit(1) + sys.exit(0) + + +if __name__ == "__main__": + main() diff --git a/src/org.gluster.storage.management.gateway.scripts/src/backend/delete_volume_cifs.py b/src/org.gluster.storage.management.gateway.scripts/src/backend/delete_volume_cifs.py new file mode 100755 index 00000000..572d819c --- /dev/null +++ b/src/org.gluster.storage.management.gateway.scripts/src/backend/delete_volume_cifs.py @@ -0,0 +1,40 @@ +#!/usr/bin/python +# Copyright (C) 2011 Gluster, Inc. <http://www.gluster.com> +# This file is part of Gluster Management Gateway. +# + +import os +import sys +p1 = os.path.abspath(os.path.dirname(sys.argv[0])) +p2 = "%s/common" % os.path.dirname(p1) +if not p1 in sys.path: + sys.path.append(p1) +if not p2 in sys.path: + sys.path.append(p2) +import Globals +import Utils +import VolumeUtils + +def main(): + if len(sys.argv) != 2: + sys.stderr.write("usage: %s VOLUME_NAME\n" % os.path.basename(sys.argv[0])) + sys.exit(-1) + + volumeName = sys.argv[1] + + volumeMountDirName = "%s/%s" % (Globals.REEXPORT_DIR, volumeName) + try: + os.rmdir(volumeMountDirName) + except OSError, e: + Utils.log("failed deleting %s: %s\n" % (volumeMountDirName, str(e))) + sys.stderr.write("Failed deleting %s: %s\n" % (volumeMountDirName, str(e))) + sys.exit(1) + + if VolumeUtils.removeVolumeCifsConfiguration(volumeName): + sys.exit(0) + sys.stderr.write("Unable to remove volume cifs configuration\n") + sys.exit(2) + + +if __name__ == "__main__": + main() diff --git a/src/org.gluster.storage.management.gateway.scripts/src/backend/format_device.py b/src/org.gluster.storage.management.gateway.scripts/src/backend/format_device.py new file mode 100755 index 00000000..8630635c --- /dev/null +++ b/src/org.gluster.storage.management.gateway.scripts/src/backend/format_device.py @@ -0,0 +1,108 @@ +#!/usr/bin/python +# Copyright (C) 2011 Gluster, Inc. <http://www.gluster.com> +# This file is part of Gluster Storage Platform. +# + +import os +import sys +import stat +p1 = os.path.abspath(os.path.dirname(sys.argv[0])) +p2 = "%s/common" % os.path.dirname(p1) +if not p1 in sys.path: + sys.path.append(p1) +if not p2 in sys.path: + sys.path.append(p2) +import Globals +import Utils +import DiskUtils + +SIZE_TB_16 = 17179869184L + +def main(): + if Utils.runCommand("wget -t 1 -T 1 -q -O /dev/null %s" % Globals.AWS_WEB_SERVICE_URL) == 0: + sys.stderr.write("format device unsupported\n") + sys.exit(1) + + if len(sys.argv) != 4: + sys.stderr.write("usage: %s FSTYPE MOUNT_POINT DEVICE_NAME\n" % os.path.basename(sys.argv[0])) + sys.exit(-1) + + fsType = sys.argv[1] + mountPoint = sys.argv[2] + device = DiskUtils.getDevice(sys.argv[3]) + deviceName = DiskUtils.getDeviceName(sys.argv[3]) + + if not os.path.exists(device): + sys.stderr.write("device %s not found\n" % sys.argv[3]) + sys.exit(2) + + try: + if not stat.S_ISBLK(os.stat(device).st_mode): + sys.stderr.write("%s is not a block device\n" % sys.argv[3]) + sys.exit(3) + except OSError, e: + Utils.log("unable to get device %s mode: %s" % (device, str(e))) + sys.stderr.write("unable to get device %s mode\n" % sys.argv[3]) + sys.exit(-2) + + if fsType in ['ext3', 'ext4', 'ext4dev']: + deviceSize = DiskUtils.getProcPartitions()[deviceName]['Size'] + if deviceSize >= SIZE_TB_16: + Utils.log("device %s, size %s is greater than %s size for fstype %s" % (device, deviceSize, SIZE_TB_16, fsType)) + sys.stderr.write("size of device %s is unsupported for fstype %s\n" % (sys.argv[3], fsType)) + sys.exit(4) + + if DiskUtils.isDataDiskPartitionFormatted(device): + sys.stderr.write("device %s already formatted\n" % sys.argv[3]) + sys.exit(5) + + if os.path.exists(mountPoint): + if not os.path.isdir(mountPoint): + sys.stderr.write("mount point %s exists but not a directory" % mountPoint) + sys.exit(6) + procMounts = Utils.readFile("/proc/mounts") + if procMounts.find(" %s " % mountPoint) != -1: + sys.stderr.write("mount point %s already has a mount\n" % mountPoint) + sys.exit(7) + if procMounts.find(" %s/" % mountPoint) != -1: + sys.stderr.write("mount point %s has a submount\n" % mountPoint) + sys.exit(8) + else: + status = Utils.runCommand("mkdir -p %s" % mountPoint, output=True, root=True) + if status["Status"] != 0: + sys.stderr.write("failed to create mount point %s\n" % mountPoint) + sys.exit(9) + + if fsType not in Utils.getFileSystemType(): + sys.stderr.write("unsupported file system type %s\n" % fsType) + sys.exit(10) + + deviceFormatLockFile = Utils.getDeviceFormatLockFile(device) + deviceFormatStatusFile = Utils.getDeviceFormatStatusFile(device) + deviceFormatOutputFile = Utils.getDeviceFormatOutputFile(device) + + if os.path.exists(deviceFormatStatusFile): + Utils.log("format status file %s exists" % deviceFormatStatusFile) + line = Utils.readFile(deviceFormatStatusFile) + if not line: + sys.stderr.write("failed to read format status file %s\n" % deviceFormatStatusFile) + sys.exit(-3) + if line.strip().upper() == "COMPLETED": + sys.stderr.write("Device %s already formatted\n" % sys.argv[3]) + sys.exit(11) + else: + sys.stderr.write("Formatting device %s already running\n" % sys.argv[3]) + sys.exit(12) + + if os.path.exists(deviceFormatLockFile): + Utils.log("lock file %s exists" % deviceFormatLockFile) + sys.stderr.write("Formatting device %s already running\n" % sys.argv[3]) + sys.exit(13) + + command = ["%s/format_device_background.py" % p1, fsType, mountPoint, sys.argv[3]] + Utils.runCommandBG(command) + sys.exit(0) + + +if __name__ == "__main__": + main() diff --git a/src/org.gluster.storage.management.gateway.scripts/src/backend/format_device_background.py b/src/org.gluster.storage.management.gateway.scripts/src/backend/format_device_background.py new file mode 100755 index 00000000..a804a59c --- /dev/null +++ b/src/org.gluster.storage.management.gateway.scripts/src/backend/format_device_background.py @@ -0,0 +1,128 @@ +#!/usr/bin/python +# Copyright (C) 2011 Gluster, Inc. <http://www.gluster.com> +# This file is part of Gluster Storage Platform. +# + +import os +import sys +p1 = os.path.abspath(os.path.dirname(sys.argv[0])) +p2 = "%s/common" % os.path.dirname(p1) +if not p1 in sys.path: + sys.path.append(p1) +if not p2 in sys.path: + sys.path.append(p2) +import Utils +import FsTabUtils +import DiskUtils + +def writeStatus(deviceFormatStatusFile, message): + try: + fp = open(deviceFormatStatusFile, "w") + fp.write(message) + fp.close() + except IOError, e: + Utils.log("Failed to update log file %s: %s" % (deviceFormatStatusFile, str(e))) + return False + return True + +def main(): + if len(sys.argv) != 4: + sys.stderr.write("usage: %s FSTYPE MOUNT_POINT DEVICE_NAME\n" % os.path.basename(sys.argv[0])) + sys.exit(-1) + + fsType = sys.argv[1] + mountPoint = sys.argv[2] + device = DiskUtils.getDevice(sys.argv[3]) + + deviceFormatLockFile = Utils.getDeviceFormatLockFile(device) + deviceFormatStatusFile = Utils.getDeviceFormatStatusFile(device) + deviceFormatOutputFile = Utils.getDeviceFormatOutputFile(device) + + if os.path.exists(deviceFormatStatusFile): + Utils.log("device format status file %s exists" % deviceFormatStatusFile) + sys.exit(1) + + if os.path.exists(deviceFormatLockFile): + Utils.log("device format lock file %s exists" % deviceFormatLockFile) + sys.exit(2) + + try: + fp = open(deviceFormatLockFile, "w") + fp.close() + except OSError, e: + Utils.log("failed to create lock file %s: %s" % (deviceFormatLockFile, str(e))) + writeStatus(deviceFormatStatusFile, "Lock file creation failed\n") + sys.exit(-2) + + try: + fptr = open(deviceFormatOutputFile, 'w') + except IOError, e: + Utils.log("failed to create output file %s" % deviceFormatOutputFile) + writeStatus(deviceFormatStatusFile, "Output file creation failed\n") + Utils.removeFile(deviceFormatLockFile) + sys.exit(-3) + + if fsType in ['ext3', 'ext4', 'ext4dev']: + command = "/sbin/mkfs.%s -F -I 512 %s" % (fsType, device) + elif fsType == "xfs": + command = "/sbin/mkfs.%s -f -i size=512 %s" % (fsType, device) + else: + command = "/sbin/mkfs.%s %s" % (fsType, device) + + status = Utils.runCommand(command, output=True, root=True) + if status["Status"] != 0: + Utils.removeFile(deviceFormatOutputFile) + Utils.removeFile(deviceFormatLockFile) + writeStatus(deviceFormatStatusFile, "Device format failed\n") + sys.exit(3) + + if Utils.runCommand("udevadm trigger") != 0: + Utils.log("failed running udevadm trigger") + + if Utils.runCommand("/usr/bin/lshal") != 0: + Utils.log("failed running /usr/bin/lshal") + + deviceUuid = DiskUtils.getUuidByDiskPartition(device) + if not deviceUuid: + Utils.removeFile(deviceFormatOutputFile) + Utils.removeFile(deviceFormatLockFile) + Utils.log("UUID not found after device %s formatted" % device) + writeStatus(deviceFormatStatusFile, "UUID not found after device %s formatted\n" % sys.argv[3]) + sys.exit(4) + + if DiskUtils.isDataDiskPartitionFormatted(device): + Utils.removeFile(deviceFormatOutputFile) + Utils.removeFile(deviceFormatLockFile) + Utils.log("UUID device %s already has an entry in fstab" % device) + writeStatus(deviceFormatStatusFile, "UUID device %s already has an entry in fstab\n" % sys.argv[3]) + sys.exit(5) + + newFsTabEntry = {"Device" : "UUID=%s" % deviceUuid, + "MountPoint" : mountPoint, + "FsType" : fsType, + "Options" : "defaults", + "DumpOption" : "0", + "fsckOrder" : "2"} + if fsType in ['ext3', 'ext4', 'ext4dev']: + newFsTabEntry["Options"] = "defaults,user_xattr" + if not FsTabUtils.addFsTabEntry(newFsTabEntry): + Utils.removeFile(deviceFormatOutputFile) + Utils.removeFile(deviceFormatLockFile) + writeStatus(deviceFormatStatusFile, "failed to update fstab") + sys.exit(6) + + status = Utils.runCommand("mount %s" % mountPoint, output=True, root=True) + if status["Status"] != 0: + Utils.removeFile(deviceFormatOutputFile) + Utils.removeFile(deviceFormatLockFile) + Utils.log("Mounting device %s on %s failed" % (device, mountPoint)) + writeStatus(deviceFormatStatusFile, "Mounting device %s on %s failed\n" % (sys.argv[3], mountPoint)) + sys.exit(7) + + writeStatus(deviceFormatStatusFile, "Completed\n") + Utils.removeFile(deviceFormatOutputFile) + Utils.removeFile(deviceFormatLockFile) + sys.exit(0) + +if __name__ == "__main__": + main() diff --git a/src/org.gluster.storage.management.gateway.scripts/src/backend/get_brick_status.py b/src/org.gluster.storage.management.gateway.scripts/src/backend/get_brick_status.py new file mode 100755 index 00000000..b72321d7 --- /dev/null +++ b/src/org.gluster.storage.management.gateway.scripts/src/backend/get_brick_status.py @@ -0,0 +1,46 @@ +#!/usr/bin/python +# Copyright (C) 2011 Gluster, Inc. <http://www.gluster.com> +# This file is part of Gluster Management Console. +# + +import os +import sys +p1 = os.path.abspath(os.path.dirname(sys.argv[0])) +p2 = "%s/common" % os.path.dirname(p1) +if not p1 in sys.path: + sys.path.append(p1) +if not p2 in sys.path: + sys.path.append(p2) +import Utils + +def main(): + if len(sys.argv) != 3: + sys.stderr.write("usage: %s VOLUME_NAME BRICK_NAME\n" % os.path.basename(sys.argv[0])) + sys.exit(-1) + + volumeName = sys.argv[1] + brickName = sys.argv[2] + pidFile = "/etc/glusterd/vols/%s/run/%s.pid" % (volumeName, brickName.replace(":", "").replace("/", "-")) + + if not os.path.exists(pidFile): + print "OFFLINE" + sys.exit(0) + + lines = Utils.readFile(pidFile) + if not lines: + print "UNKNOWN" + sys.exit(0) + try: + pidString = lines[0] + os.getpgid(int(pidString)) + print "ONLINE" + except ValueError, e: + Utils.log("invalid pid %s in file %s: %s" % (pidString, pidFile, str(e))) + print "UNKNOWN" + except OSError, e: + #Utils.log("failed to get process detail of pid %s: %s" % (pidString, str(e))) + print "OFFLINE" + sys.exit(0) + +if __name__ == "__main__": + main() diff --git a/src/org.gluster.storage.management.gateway.scripts/src/backend/get_filesystem_type.py b/src/org.gluster.storage.management.gateway.scripts/src/backend/get_filesystem_type.py new file mode 100755 index 00000000..de4b4bb0 --- /dev/null +++ b/src/org.gluster.storage.management.gateway.scripts/src/backend/get_filesystem_type.py @@ -0,0 +1,22 @@ +#!/usr/bin/python +# Copyright (C) 2011 Gluster, Inc. <http://www.gluster.com> +# This file is part of Gluster Storage Platform. +# + +import os +import sys +p1 = os.path.abspath(os.path.dirname(sys.argv[0])) +p2 = "%s/common" % os.path.dirname(p1) +if not p1 in sys.path: + sys.path.append(p1) +if not p2 in sys.path: + sys.path.append(p2) +import Utils + +SUPPORTED_FSTYPE = ['ext3', 'ext4', 'ext4dev', 'xfs'] + +def main(): + print "\n".join(list(set(Utils.getFileSystemType()).intersection(set(SUPPORTED_FSTYPE)))) + +if __name__ == "__main__": + main() diff --git a/src/org.gluster.storage.management.gateway.scripts/src/backend/get_format_device_status.py b/src/org.gluster.storage.management.gateway.scripts/src/backend/get_format_device_status.py new file mode 100755 index 00000000..532f1585 --- /dev/null +++ b/src/org.gluster.storage.management.gateway.scripts/src/backend/get_format_device_status.py @@ -0,0 +1,93 @@ +#!/usr/bin/python +# Copyright (C) 2011 Gluster, Inc. <http://www.gluster.com> +# This file is part of Gluster Storage Platform. +# + +import os +import sys +p1 = os.path.abspath(os.path.dirname(sys.argv[0])) +p2 = "%s/common" % os.path.dirname(p1) +if not p1 in sys.path: + sys.path.append(p1) +if not p2 in sys.path: + sys.path.append(p2) +import time +import Utils +import DiskUtils +from XmlHandler import ResponseXml + +def main(): + if len(sys.argv) != 2: + sys.stderr.write("usage: %s DEVICE_NAME\n" % os.path.basename(sys.argv[0])) + sys.exit(-1) + + device = DiskUtils.getDevice(sys.argv[1]) + + deviceFormatLockFile = Utils.getDeviceFormatLockFile(device) + deviceFormatStatusFile = Utils.getDeviceFormatStatusFile(device) + deviceFormatOutputFile = Utils.getDeviceFormatOutputFile(device) + + time.sleep(1) + if not os.path.exists(deviceFormatLockFile): + if not os.path.exists(deviceFormatStatusFile): + sys.stderr.write("Device format not initiated\n") + sys.exit(1) + + if os.path.exists(deviceFormatStatusFile): + line = Utils.readFile(deviceFormatStatusFile) + line = line.strip() + + Utils.removeFile(deviceFormatOutputFile) + Utils.removeFile(deviceFormatStatusFile) + + responseDom = ResponseXml() + responseDom.appendTagRoute("device", sys.argv[1]) + responseDom.appendTagRoute("completedBlocks", "0") + responseDom.appendTagRoute("totalBlocks", "0") + responseDom.appendTagRoute("message", line) + if line.upper() == "COMPLETED": + responseDom.appendTagRoute("formatStatus", "COMPLETED") + else: + responseDom.appendTagRoute("formatStatus", "NOT_RUNNING") + print responseDom.toxml() + sys.exit(0) + + content = Utils.readFile(deviceFormatOutputFile, lines=True) + if not content: + responseDom = ResponseXml() + responseDom.appendTagRoute("device", sys.argv[1]) + responseDom.appendTagRoute("completedBlocks", "0") + responseDom.appendTagRoute("totalBlocks", "0") + responseDom.appendTagRoute("message", None) + responseDom.appendTagRoute("formatStatus", "IN_PROGRESS") + print responseDom.toxml() + sys.exit(0) + + lines = [line for line in content + if "Writing inode tables" in line] + if not lines: + responseDom = ResponseXml() + responseDom.appendTagRoute("device", sys.argv[1]) + responseDom.appendTagRoute("completedBlocks", "0") + responseDom.appendTagRoute("totalBlocks", "0") + responseDom.appendTagRoute("message", content[-1]) + responseDom.appendTagRoute("formatStatus", "IN_PROGRESS") + print responseDom.toxml() + sys.exit(0) + + tokens = [token for token in lines[-1].split("\x08") if token] + if "done" in tokens[-1]: + values = tokens[-2].split(':')[-1].strip().split('/') + else: + values = tokens[-1].split(':')[-1].strip().split('/') + + responseDom.appendTagRoute("device", sys.argv[1]) + responseDom.appendTagRoute("completedBlocks", values[0]) + responseDom.appendTagRoute("totalBlocks", values[1]) + responseDom.appendTagRoute("message", lines[-1]) + responseDom.appendTagRoute("formatStatus", "IN_PROGRESS") + print responseDom.toxml() + sys.exit(0) + +if __name__ == "__main__": + main() diff --git a/src/org.gluster.storage.management.gateway.scripts/src/backend/get_rrd_cpu_details.py b/src/org.gluster.storage.management.gateway.scripts/src/backend/get_rrd_cpu_details.py new file mode 100755 index 00000000..da08fde1 --- /dev/null +++ b/src/org.gluster.storage.management.gateway.scripts/src/backend/get_rrd_cpu_details.py @@ -0,0 +1,47 @@ +#!/usr/bin/python +# Copyright (C) 2011 Gluster, Inc. <http://www.gluster.com> +# This file is part of Gluster Management Gateway. +# + +import os +import sys +p1 = os.path.abspath(os.path.dirname(sys.argv[0])) +p2 = "%s/common" % os.path.dirname(p1) +if not p1 in sys.path: + sys.path.append(p1) +if not p2 in sys.path: + sys.path.append(p2) +import Utils + +CPU_RRD_FILE = "/var/lib/rrd/cpu.rrd" + +def main(): + if len(sys.argv) != 2: + sys.stderr.write("usage: %s DURATION\n" % os.path.basename(sys.argv[0])) + sys.exit(-1) + + period = sys.argv[1] + + command = "rrdtool xport --start -%s \ + DEF:cpuuser=%s:user:AVERAGE \ + DEF:cpusystem=%s:system:AVERAGE \ + DEF:cpuidle=%s:idle:AVERAGE \ + CDEF:total=cpuuser,cpusystem,cpuidle,+,+ \ + CDEF:userpct=100,cpuuser,total,/,* \ + CDEF:systempct=100,cpusystem,total,/,* \ + CDEF:idlepct=100,cpuidle,total,/,* \ + CDEF:totalpct=userpct,systempct,+ \ + XPORT:userpct:userpct \ + XPORT:systempct:systempct \ + XPORT:totalpct:totalpct" % (period, CPU_RRD_FILE, CPU_RRD_FILE, CPU_RRD_FILE) + + rv = Utils.runCommand(command, output=True, root=True) + if rv["Status"] != 0: + sys.stderr.write("Failed to get RRD data of CPU\n") + sys.exit(rv["Status"]) + + print rv["Stdout"] + sys.exit(0) + +if __name__ == "__main__": + main() diff --git a/src/org.gluster.storage.management.gateway.scripts/src/backend/get_rrd_memory_details.py b/src/org.gluster.storage.management.gateway.scripts/src/backend/get_rrd_memory_details.py new file mode 100755 index 00000000..07a9d7d0 --- /dev/null +++ b/src/org.gluster.storage.management.gateway.scripts/src/backend/get_rrd_memory_details.py @@ -0,0 +1,48 @@ +#!/usr/bin/python +# Copyright (C) 2011 Gluster, Inc. <http://www.gluster.com> +# This file is part of Gluster Management Gateway. +# + +import os +import sys +p1 = os.path.abspath(os.path.dirname(sys.argv[0])) +p2 = "%s/common" % os.path.dirname(p1) +if not p1 in sys.path: + sys.path.append(p1) +if not p2 in sys.path: + sys.path.append(p2) +import Utils + +MEMORY_RRD_FILE = "/var/lib/rrd/mem.rrd" + +def main(): + if len(sys.argv) != 2: + sys.stderr.write("usage: %s DURATION\n" % os.path.basename(sys.argv[0])) + sys.exit(-1) + + period = sys.argv[1] + + command = "rrdtool xport --start -%s \ + DEF:free=%s:memfree:AVERAGE \ + DEF:used=%s:memused:AVERAGE \ + DEF:cache=%s:memcache:AVERAGE \ + DEF:buffer=%s:membuffer:AVERAGE \ + CDEF:total1=used,free,+ \ + CDEF:used1=used,buffer,cache,-,- \ + CDEF:total=total1,used1,+ \ + XPORT:used:memoryUsed \ + XPORT:free:memoryFree \ + XPORT:cache:memoryCache \ + XPORT:buffer:memoryBuffer \ + XPORT:total:totalMemory" % (period, MEMORY_RRD_FILE, MEMORY_RRD_FILE, MEMORY_RRD_FILE, MEMORY_RRD_FILE) + + rv = Utils.runCommand(command, output=True, root=True) + if rv["Status"] != 0: + sys.stderr.write("Failed to get RRD data of memory usage\n") + sys.exit(rv["Status"]) + + print rv["Stdout"] + sys.exit(0) + +if __name__ == "__main__": + main() diff --git a/src/org.gluster.storage.management.gateway.scripts/src/backend/get_rrd_net_details.py b/src/org.gluster.storage.management.gateway.scripts/src/backend/get_rrd_net_details.py new file mode 100755 index 00000000..ee28ca13 --- /dev/null +++ b/src/org.gluster.storage.management.gateway.scripts/src/backend/get_rrd_net_details.py @@ -0,0 +1,41 @@ +#!/usr/bin/python +# Copyright (C) 2011 Gluster, Inc. <http://www.gluster.com> +# This file is part of Gluster Management Gateway. +# + +import os +import sys +p1 = os.path.abspath(os.path.dirname(sys.argv[0])) +p2 = "%s/common" % os.path.dirname(p1) +if not p1 in sys.path: + sys.path.append(p1) +if not p2 in sys.path: + sys.path.append(p2) +import Utils + +def main(): + if len(sys.argv) != 3: + sys.stderr.write("usage: %s DEVICE DURATION\n" % os.path.basename(sys.argv[0])) + sys.exit(-1) + + device = sys.argv[1] + period = sys.argv[2] + + command = "rrdtool xport --start -%s \ + DEF:received=/var/lib/rrd/network-%s.rrd:received:AVERAGE \ + DEF:transmitted=/var/lib/rrd/network-%s.rrd:transmitted:AVERAGE \ + CDEF:total=received,transmitted,+ \ + XPORT:received:received \ + XPORT:transmitted:transmitted \ + XPORT:total:total" % (period, device, device) + + rv = Utils.runCommand(command, output=True, root=True) + if rv["Status"] != 0: + sys.stderr.write("Failed to get RRD information of device %s\n" % device) + sys.exit(rv["Status"]) + + print rv["Stdout"] + sys.exit(0) + +if __name__ == "__main__": + main() diff --git a/src/org.gluster.storage.management.gateway.scripts/src/backend/get_server_details.py b/src/org.gluster.storage.management.gateway.scripts/src/backend/get_server_details.py new file mode 100755 index 00000000..26b9059a --- /dev/null +++ b/src/org.gluster.storage.management.gateway.scripts/src/backend/get_server_details.py @@ -0,0 +1,267 @@ +#!/usr/bin/python +# Copyright (C) 2011 Gluster, Inc. <http://www.gluster.com> +# This file is part of Gluster Storage Platform. +# + +import os +import sys +p1 = os.path.abspath(os.path.dirname(sys.argv[0])) +p2 = "%s/common" % os.path.dirname(p1) +if not p1 in sys.path: + sys.path.append(p1) +if not p2 in sys.path: + sys.path.append(p2) +import socket +import re +import Utils +import DiskUtils +import NetworkUtils +import XmlHandler +from optparse import OptionParser + + +def getDiskDom(): + diskInfo = DiskUtils.getDiskInfo() + if not diskInfo: + return None + procMdstat = DiskUtils.getProcMdstat() + diskDom = XmlHandler.XDOM() + disksTag = diskDom.createTag("disks", None) + diskTagDict = {} + raidDisksTag = diskDom.createTag("raidDisks", None) # raid members tag + for raidDiskName, raidDisk in procMdstat.iteritems(): + raidDiskTag = diskDom.createTag("disk", None) + raidDiskTag.appendChild(diskDom.createTag("name", raidDiskName)) + raidDiskTag.appendChild(diskDom.createTag("description", diskInfo[raidDiskName]['Description'])) + raidDiskTag.appendChild(diskDom.createTag("uuid", diskInfo[raidDiskName]['Uuid'])) + raidDiskTag.appendChild(diskDom.createTag("type", "UNKNOWN")) + raidDiskTag.appendChild(diskDom.createTag("mountPoint", diskInfo[raidDiskName]['MountPoint'])) + raidDiskTag.appendChild(diskDom.createTag("fsType", diskInfo[raidDiskName]['FsType'])) + if diskInfo[raidDiskName]['FsType']: + raidDiskTag.appendChild(diskDom.createTag("status", "INITIALIZED")) + else: + raidDiskTag.appendChild(diskDom.createTag("status", "UNINITIALIZED")) + raidDiskTag.appendChild(diskDom.createTag("interface")) + raidDiskTag.appendChild(diskDom.createTag("fsVersion")) + raidDiskTag.appendChild(diskDom.createTag("size", diskInfo[raidDiskName]['Size'] / 1024.0)) + if not diskInfo[raidDiskName]['SpaceInUse']: + raidDiskTag.appendChild(diskDom.createTag("spaceInUse", None)) + else: + raidDiskTag.appendChild(diskDom.createTag("spaceInUse", diskInfo[raidDiskName]['SpaceInUse'] / 1024.0)) + raidDiskTag.appendChild(raidDisksTag) + disksTag.appendChild(raidDiskTag) + for raidMember in raidDisk['Member']: + # Case1: Raid array member is a disk. The following code will add the disk details under a disk tag + if diskInfo.has_key(raidMember): + diskTag = diskDom.createTag("disk", None) + diskTag.appendChild(diskDom.createTag("name", raidMember)) + diskTag.appendChild(diskDom.createTag("description", diskInfo[raidMember]["Description"])) + diskTag.appendChild(diskDom.createTag("uuid", diskInfo[raidMember]["Uuid"])) + if DiskUtils.isDiskInFormatting(raidMember): + diskTag.appendChild(diskDom.createTag("status", "INITIALIZING")) + else: + if diskInfo[raidMember]["FsType"]: + diskTag.appendChild(diskDom.createTag("status", "INITIALIZED")) + else: + diskTag.appendChild(diskDom.createTag("status", "UNINITIALIZED")) + diskTag.appendChild(diskDom.createTag("interface", diskInfo[raidMember]["Interface"])) + diskTag.appendChild(diskDom.createTag("mountPoint", diskInfo[raidMember]["MountPoint"])) + if diskInfo[raidMember]["FsType"]: + diskTag.appendChild(diskDom.createTag("type", "DATA")) + else: + diskTag.appendChild(diskDom.createTag("type", "UNKNOWN")) + diskTag.appendChild(diskDom.createTag("fsType", diskInfo[raidMember]["FsType"])) + diskTag.appendChild(diskDom.createTag("fsVersion", diskInfo[raidMember]["FsVersion"])) + diskTag.appendChild(diskDom.createTag("size", diskInfo[raidMember]["Size"] / 1024.0)) + if not diskInfo[raidMember]["SpaceInUse"]: + diskTag.appendChild(diskDom.createTag("spaceInUse", None)) + else: + diskTag.appendChild(diskDom.createTag("spaceInUse", diskInfo[raidMember]["SpaceInUse"] / 1024.0)) + raidDisksTag.appendChild(diskTag) + del diskInfo[raidMember] + continue + # Case2: Raid array member is a partition. The following code will add the partition and its corresponding disk its belong to. + for disk, item in diskInfo.iteritems(): + if not item['Partitions'].has_key(raidMember): + continue + if not diskTagDict.has_key(disk): + diskTag = diskDom.createTag("disk", None) + diskTag.appendChild(diskDom.createTag("name", disk)) + diskTag.appendChild(diskDom.createTag("description", item["Description"])) + diskTag.appendChild(diskDom.createTag("uuid", item["Uuid"])) + diskTag.appendChild(diskDom.createTag("status", "INITIALIZED")) + diskTag.appendChild(diskDom.createTag("interface", item["Interface"])) + diskTag.appendChild(diskDom.createTag("mountPoint")) + diskTag.appendChild(diskDom.createTag("type", "DATA")) + diskTag.appendChild(diskDom.createTag("fsType", item["FsType"])) + diskTag.appendChild(diskDom.createTag("fsVersion", item["FsVersion"])) + diskTag.appendChild(diskDom.createTag("size", item["Size"] / 1024.0)) + if not item["SpaceInUse"]: + diskTag.appendChild(diskDom.createTag("spaceInUse", None)) + else: + diskTag.appendChild(diskDom.createTag("spaceInUse", item["SpaceInUse"] / 1024.0)) + partitionsTag = diskDom.createTag("partitions", None) + diskTag.appendChild(partitionsTag) + raidDisksTag.appendChild(diskTag) + # Constructed disk tag will be added to the dictonary. + # This will be used to keep add all the corresponding partitions tags of the disk to the disk tag. + diskTagDict[disk] = {'diskTag': diskTag, 'partitionsTag': partitionsTag} + # adding partition details under this disk tag + partitionTag = diskDom.createTag("partition", None) + partitionTag.appendChild(diskDom.createTag("name", raidMember)) + partitionTag.appendChild(diskDom.createTag("uuid", item['Partitions'][raidMember]["Uuid"])) + partitionTag.appendChild(diskDom.createTag("fsType", item['Partitions'][raidMember]["FsType"])) + if item['Partitions'][raidMember]["FsType"]: + partitionTag.appendChild(diskDom.createTag("status", "INITIALIZED")) + partitionTag.appendChild(diskDom.createTag("type", "DATA")) + else: + partitionTag.appendChild(diskDom.createTag("status", "UNINITIALIZED")) + partitionTag.appendChild(diskDom.createTag("type", "UNKNOWN")) + partitionTag.appendChild(diskDom.createTag("mountPoint", item['Partitions'][raidMember]['MountPoint'])) + partitionTag.appendChild(diskDom.createTag("size", item['Partitions'][raidMember]["Size"] / 1024.0)) + if not item['Partitions'][raidMember]["SpaceInUse"]: + partitionTag.appendChild(diskDom.createTag("spaceInUse", None)) + else: + partitionTag.appendChild(diskDom.createTag("spaceInUse", item['Partitions'][raidMember]["SpaceInUse"] / 1024.0)) + diskTagDict[disk]['partitionsTag'].appendChild(partitionTag) + # deleting partition entry of a raid member from diskInfo (item['Partitions']) + del item['Partitions'][raidMember] + del diskInfo[raidDiskName] + disksTag.appendChild(raidDisksTag) + for diskName, value in diskInfo.iteritems(): + diskTag = diskDom.createTag("disk", None) + diskTag.appendChild(diskDom.createTag("name", diskName)) + diskTag.appendChild(diskDom.createTag("description", value["Description"])) + diskTag.appendChild(diskDom.createTag("uuid", value["Uuid"])) + if DiskUtils.isDiskInFormatting(diskName): + status = "INITIALIZING" + else: + if value["FsType"]: + status = "INITIALIZED" + else: + status = "UNINITIALIZED" + diskTag.appendChild(diskDom.createTag("status", status)) + diskTag.appendChild(diskDom.createTag("interface", value["Interface"])) + if value["MountPoint"] and value["MountPoint"] in ["/", "/boot"]: + diskTag.appendChild(diskDom.createTag("type", "BOOT")) + elif "UNINITIALIZED" == status: + diskTag.appendChild(diskDom.createTag("type", "UNKNOWN")) + else: + diskTag.appendChild(diskDom.createTag("type", "DATA")) + diskTag.appendChild(diskDom.createTag("fsType", value["FsType"])) + diskTag.appendChild(diskDom.createTag("fsVersion", value["FsVersion"])) + diskTag.appendChild(diskDom.createTag("mountPoint", value["MountPoint"])) + diskTag.appendChild(diskDom.createTag("size", value["Size"] / 1024.0)) + if not value["SpaceInUse"]: + diskTag.appendChild(diskDom.createTag("spaceInUse", None)) + else: + diskTag.appendChild(diskDom.createTag("spaceInUse", value["SpaceInUse"] / 1024.0)) + partitionsTag = diskDom.createTag("partitions", None) + diskTag.appendChild(partitionsTag) + for partName, partValues in value['Partitions'].iteritems(): + partitionTag = diskDom.createTag("partition", None) + partitionTag.appendChild(diskDom.createTag("name", partName)) + partitionTag.appendChild(diskDom.createTag("uuid", partValues["Uuid"])) + partitionTag.appendChild(diskDom.createTag("fsType", partValues["FsType"])) + if partValues["MountPoint"] and partValues["MountPoint"] in ["/", "/boot"]: + partitionTag.appendChild(diskDom.createTag("status", "INITIALIZED")) + partitionTag.appendChild(diskDom.createTag("type", "BOOT")) + elif partValues["FsType"]: + partitionTag.appendChild(diskDom.createTag("status", "INITIALIZED")) + partitionTag.appendChild(diskDom.createTag("type", "DATA")) + else: + partitionTag.appendChild(diskDom.createTag("status", "UNINITIALIZED")) + partitionTag.appendChild(diskDom.createTag("type", "UNKNOWN")) + partitionTag.appendChild(diskDom.createTag("mountPoint", partValues['MountPoint'])) + partitionTag.appendChild(diskDom.createTag("size", partValues["Size"] / 1024.0)) + if not partValues["SpaceInUse"]: + partitionTag.appendChild(diskDom.createTag("spaceInUse", None)) + else: + partitionTag.appendChild(diskDom.createTag("spaceInUse", partValues["SpaceInUse"] / 1024.0)) + partitionsTag.appendChild(partitionTag) + continue + disksTag.appendChild(diskTag) + diskDom.addTag(disksTag) + return diskDom + + +def getServerDetails(listall): + serverName = socket.getfqdn() + meminfo = Utils.getMeminfo() + cpu = Utils.getCpuUsageAvg() + nameServerList, domain, searchDomain = NetworkUtils.readResolvConfFile() + if not domain: + domain = [None] + + responseDom = XmlHandler.ResponseXml() + serverTag = responseDom.appendTagRoute("server") + serverTag.appendChild(responseDom.createTag("name", serverName)) + serverTag.appendChild(responseDom.createTag("domainname", domain[0])) + if Utils.runCommand("pidof glusterd") == 0: + serverTag.appendChild(responseDom.createTag("status", "ONLINE")) + else: + serverTag.appendChild(responseDom.createTag("status", "OFFLINE")) + serverTag.appendChild(responseDom.createTag("glusterFsVersion", Utils.getGlusterVersion())) + serverTag.appendChild(responseDom.createTag("cpuUsage", str(cpu))) + serverTag.appendChild(responseDom.createTag("totalMemory", str(Utils.convertKbToMb(meminfo['MemTotal'])))) + serverTag.appendChild(responseDom.createTag("memoryInUse", str(Utils.convertKbToMb(meminfo['MemUsed'])))) + serverTag.appendChild(responseDom.createTag("uuid", None)) + + for dns in nameServerList: + serverTag.appendChild(responseDom.createTag("dns%s" % str(nameServerList.index(dns) +1) , dns)) + + #TODO: probe and retrieve timezone, ntp-server details and update the tags + + interfaces = responseDom.createTag("networkInterfaces", None) + for deviceName, values in NetworkUtils.getNetDeviceList().iteritems(): + if values["type"].upper() in ['LOCAL', 'IPV6-IN-IPV4']: + continue + interfaceTag = responseDom.createTag("networkInterface", None) + interfaceTag.appendChild(responseDom.createTag("name", deviceName)) + interfaceTag.appendChild(responseDom.createTag("hwAddr", values["hwaddr"])) + interfaceTag.appendChild(responseDom.createTag("speed", values["speed"])) + interfaceTag.appendChild(responseDom.createTag("model", values["type"])) + if values["onboot"]: + interfaceTag.appendChild(responseDom.createTag("onBoot", "yes")) + else: + interfaceTag.appendChild(responseDom.createTag("onBoot", "no")) + interfaceTag.appendChild(responseDom.createTag("bootProto", values["bootproto"])) + interfaceTag.appendChild(responseDom.createTag("ipAddress", values["ipaddr"])) + interfaceTag.appendChild(responseDom.createTag("netMask", values["netmask"])) + interfaceTag.appendChild(responseDom.createTag("defaultGateway", values["gateway"])) + if values["mode"]: + interfaceTag.appendChild(responseDom.createTag("mode", values["mode"])) + if values["master"]: + interfaceTag.appendChild(responseDom.createTag("bonding", "yes")) + spliter = re.compile(r'[\D]') + interfaceTag.appendChild(responseDom.createTag("bondid", spliter.split(values["master"])[-1])) + interfaces.appendChild(interfaceTag) + serverTag.appendChild(interfaces) + + responseDom.appendTag(serverTag) + serverTag.appendChild(responseDom.createTag("numOfCPUs", int(os.sysconf('SC_NPROCESSORS_ONLN')))) + + diskDom = getDiskDom() + if not diskDom: + sys.stderr.write("No disk found!") + Utils.log("Failed to get disk details") + sys.exit(2) + + serverTag.appendChild(diskDom.getElementsByTagRoute("disks")[0]) + return serverTag + +def main(): + parser = OptionParser() + parser.add_option("-N", "--only-data-disks", + action="store_false", dest="listall", default=True, + help="List only data disks") + + (options, args) = parser.parse_args() + responseXml = getServerDetails(options.listall) + if responseXml: + print responseXml.toxml() + + sys.exit(0) + +if __name__ == "__main__": + main() diff --git a/src/org.gluster.storage.management.gateway.scripts/src/backend/get_server_status.py b/src/org.gluster.storage.management.gateway.scripts/src/backend/get_server_status.py new file mode 100755 index 00000000..2814f10f --- /dev/null +++ b/src/org.gluster.storage.management.gateway.scripts/src/backend/get_server_status.py @@ -0,0 +1,28 @@ +#!/usr/bin/python +# Copyright (C) 2011 Gluster, Inc. <http://www.gluster.com> +# This file is part of Gluster Management Console. +# + +import os +import sys +p1 = os.path.abspath(os.path.dirname(sys.argv[0])) +p2 = "%s/common" % os.path.dirname(p1) +if not p1 in sys.path: + sys.path.append(p1) +if not p2 in sys.path: + sys.path.append(p2) +import Utils + +def main(): + if len(sys.argv) != 1: + sys.stderr.write("usage: %s\n" % os.path.basename(sys.argv[0])) + sys.exit(-1) + + if Utils.runCommand("pidof glusterd") == 0: + print "ONLINE" + else: + print "OFFLINE" + sys.exit(0) + +if __name__ == "__main__": + main() diff --git a/src/org.gluster.storage.management.gateway.scripts/src/backend/get_volume_brick_log.py b/src/org.gluster.storage.management.gateway.scripts/src/backend/get_volume_brick_log.py new file mode 100755 index 00000000..026c3c00 --- /dev/null +++ b/src/org.gluster.storage.management.gateway.scripts/src/backend/get_volume_brick_log.py @@ -0,0 +1,97 @@ +#!/usr/bin/python +# Copyright (C) 2011 Gluster, Inc. <http://www.gluster.com> +# This file is part of Gluster Storage Platform. +# + +import re +import os +import sys +p1 = os.path.abspath(os.path.dirname(sys.argv[0])) +p2 = "%s/common" % os.path.dirname(p1) +if not p1 in sys.path: + sys.path.append(p1) +if not p2 in sys.path: + sys.path.append(p2) +from XmlHandler import XDOM +import Utils + +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, logMessagesTag, loginfo): + logMessageTag = responseDom.createTag("logMessage") + logMessageTag.appendChild(responseDom.createTag("timestamp", loginfo[0] + " " + loginfo[1])) + logMessageTag.appendChild(responseDom.createTag("severity", enumLogType(loginfo[2]))) + logMessageTag.appendChild(responseDom.createTag("message", loginfo[3])) + logMessagesTag.appendChild(logMessageTag); + 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 = XDOM() + if not logFilePath: + sys.stderr.write("No log file path given\n") + sys.exit(-1) + + if not tailCount: + sys.stderr.write("No tail count given\n") + sys.exit(-1) + + pattern = '\[\d{4}-\d{2}-\d{2}\s{1}\d{2}:\d{2}:\d{2}.\d+\]\s{1}([MACEWNIDT]){1}\s+' + + content = Utils.readFile(logFilePath, lines=True) + if not content: + sys.stderr.write("volume log not found in file %s\n" % logFilePath) + sys.exit(-1) + + lines = [line for line in content if re.match(pattern, line)] + i = len(lines) - int(tailCount) + if i < 0: + i = 0 + logMessagesTag = rs.createTag("logMessages") + rs.addTag(logMessagesTag) + for log in lines[i:]: + loginfo = logSplit(log) + addLog(rs, logMessagesTag, loginfo) + return rs.toxml() +##--end of getVolumeLog() + +def main(): + if len(sys.argv) != 3: + sys.stderr.write("usage: %s LOG-FILE LINE-COUNT\n" % 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/org.gluster.storage.management.gateway.scripts/src/backend/gluster-provision-block b/src/org.gluster.storage.management.gateway.scripts/src/backend/gluster-provision-block new file mode 100755 index 00000000..0385b82c --- /dev/null +++ b/src/org.gluster.storage.management.gateway.scripts/src/backend/gluster-provision-block @@ -0,0 +1,171 @@ +#!/bin/bash + +ME=$(basename $0); + +set -o pipefail; + +function show_help() +{ + usage_banner; + cat <<EOF + +Usage: $ME [-h] [-t FSTYPE] DEVICE + +Prepare DEVICE to be used in volumes. +DEVICE is the special file corresponding to the +device (e.g /dev/sdXX). + +General: + -t FSTYPE Prepare DEVICE using FSTYPE filesystem. + Supported filesystems are ext3/ext4/xfs + (Default is ext4/ext3) + +Miscellaneous: + -h display this help and exit + +Example: + $ME /dev/sdb + $ME -t xfs /dev/sdb +EOF +} + + +function usage_banner() +{ + echo "Gluster Storage Virtual Appliance, Version 1.2." +} + +function fail() +{ + echo "$ME: FATAL: $@" + exit 1; +} + + +function main() +{ + # Parse command line arguments. + while getopts :ht: OPT; do + case "$OPT" in + h) + show_help + exit 0 + ;; + t) + fstype=$OPTARG + case $fstype in + ext3 | ext4 | xfs) + ;; + *) + echo "unknown fstype $fstype" + show_help + exit 1 + ;; + esac + ;; + \?) + # getopts issues an error message + echo "Invalid option: -$OPTARG" + show_help + exit 1 + ;; + :) + echo "Option -$OPTARG requires an argument." + show_help + exit 1 + ;; + esac + done + + # Remove the switches we parsed above. + shift `expr $OPTIND - 1` + + # We want only one non-option argument. + if [ $# -ne 1 ]; then + show_help + exit 1 + fi + + if [ -z "$fstype" ]; then + if [ -x /sbin/mkfs.ext4 ]; then + fstype=ext4 + elif [ -x /sbin/mkfs.ext3 ]; then + fstype=ext3 + else + fail "neither ext4 nor ext3 support available (or mkfs tools not present)" + fi + fi + + set -e; + + devblk="$1"; + blk=$(echo $1 | cut -f3 -d/); + mnt="/export/$blk"; + + [ -e $mnt ] || mkdir -p $mnt + + [ -b $devblk ] || fail "$devblk is not a valid block device"; + + [ -d $mnt ] || fail "$mnt is not a directory"; + + grep -wq $blk /proc/partitions || fail "$blk is not detected in /proc/partitions"; + + blkid -c /dev/null | grep -q "^$devblk:" && fail "$devblk is already formatted"; + + grep -q " $mnt " /proc/mounts && fail "$mnt already has a mount"; + grep -q " $mnt/" /proc/mounts && fail "$mnt has a submount"; + + grep -q " $mnt " /etc/fstab && fail "$mnt already has an entry in fstab"; + + grep -wq "$devblk" /etc/fstab && fail "$devblk already has an entry in fstab"; + + if [ ! -x /sbin/mkfs.$fstype ]; then + fail "no $fstype support available" + fi + + case $fstype in + ext3 | ext4) + /sbin/mkfs.$fstype -I 512 $devblk; + ;; + xfs) + /sbin/mkfs.$fstype -i size=512 $devblk + ;; + esac + + uuid=$(blkid -c /dev/null -o value $devblk | head -1); #sed -n 's/ID_FS_UUID=//p'); + + grep -wq "$uuid" /etc/fstab && fail "$uuid already has an entry in fstab"; + + case $fstype in + ext3 | ext4) + echo "UUID=$uuid $mnt $fstype defaults,user_xattr 0 2" >> /etc/fstab || fail "Failed to update fstab"; + ;; + *) + echo "UUID=$uuid $mnt $fstype defaults 0 2" >> /etc/fstab || fail "Failed to update fstab"; + ;; + esac + + mount -v $mnt || fail "mounting $devblk on $mnt failed"; + +cat <<EOF + +================================================================================ +Completed mounting and setting up fstab for $devblk on $mnt + +You may now expand existing volumes or create new volumes with commands like: + + sh# gluster volume create VOLNAME $(hostname):$mnt/SUBDIR" ... + + or + + sh# gluster volume add-brick VOLNAME $(hostname):$mnt/SUBDIR ... + +Please refer documentation at http://www.gluster.com/community/documentation/ +for the exact syntax and reference. + +================================================================================ +EOF +} + + +main "$@"; diff --git a/src/org.gluster.storage.management.gateway.scripts/src/backend/gluster-volume-settings.init.d b/src/org.gluster.storage.management.gateway.scripts/src/backend/gluster-volume-settings.init.d new file mode 100755 index 00000000..97bc01ee --- /dev/null +++ b/src/org.gluster.storage.management.gateway.scripts/src/backend/gluster-volume-settings.init.d @@ -0,0 +1,20 @@ +#!/bin/bash +# +# chkconfig: - 90 10 +### BEGIN INIT INFO +# Required-Start: $network syslog glusterd +# Default-Start: 3 5 +# Description: Setup/cleanup CIFS settings of Gluster volumes +### END INIT INFO + +case "$1" in + start) + modprobe -q fuse + sleep 3 + if ! lsmod | grep -qw fuse; then + echo "FATAL: fuse kernel module is not found. Gluster CIFS volume access will not work" >&2 + exit 1 + fi + /usr/sbin/gluster_cifs_volume_startup + ;; +esac diff --git a/src/org.gluster.storage.management.gateway.scripts/src/backend/gluster_cifs_volume_startup.py b/src/org.gluster.storage.management.gateway.scripts/src/backend/gluster_cifs_volume_startup.py new file mode 100644 index 00000000..9ea7e021 --- /dev/null +++ b/src/org.gluster.storage.management.gateway.scripts/src/backend/gluster_cifs_volume_startup.py @@ -0,0 +1,114 @@ +#!/usr/bin/python +# Copyright (C) 2011 Gluster, Inc. <http://www.gluster.com> +# This file is part of Gluster Management Gateway. +# + +import os +import sys +import glob +p1 = os.path.abspath(os.path.dirname(sys.argv[0])) +p2 = "%s/common" % os.path.dirname(p1) +if not p1 in sys.path: + sys.path.append(p1) +if not p2 in sys.path: + sys.path.append(p2) +import Globals +import Utils +import VolumeUtils + +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 main(): + volumeInfo = getGlusterVolumeInfo() + if not volumeInfo: + print "No volume present. Removing CIFS volume configuration if any" + Utils.runCommand("rm -fr %s/*" % Globals.VOLUME_CONF_DIR, root=True, shell=True) + Utils.runCommand("rm -fr %s/*" % Globals.REEXPORT_DIR, root=True, shell=True) + Utils.runCommand("rm -fr %s/*" % Globals.CIFS_EXPORT_DIR, root=True, shell=True) + sys.exit(0) + + lines = Utils.readFile(Globals.VOLUME_SMBCONF_FILE) + volumeSmbConfList = [line.strip() for line in lines] + for volumeName in volumeInfo.keys(): + if not "include = %s/%s.smbconf" % (Globals.VOLUME_CONF_DIR, volumeName) in volumeSmbConfList: + continue + if 'STOPPED' == volumeInfo[volumeName]['VolumeStatus'].upper(): + Utils.runCommand("rmdir %s/%s" % (Globals.CIFS_EXPORT_DIR, volumeName), root=True) + if not VolumeUtils.excludeVolume(volumeName): + Utils.log("Failed to exclude %s volume for CIFS reexport" % volumeName) + continue + if 'STARTED' == volumeInfo[volumeName]['VolumeStatus'].upper(): + volumeMountDirName = "%s/%s" % (Globals.REEXPORT_DIR, volumeName) + if Utils.runCommand("mount -t glusterfs 127.0.0.1:%s %s" % (volumeName, volumeMountDirName)) != 0: + Utils.log("Failed to mount volume %s" % (volumeName)) + + smbConfFileList = glob.glob("%s/*.smbconf" % Globals.VOLUME_CONF_DIR) + volumeList = [smbConfFileName.split(".smbconf")[0].split("/")[-1] for smbConfFileName in smbConfFileList] + danglingVolumeList = list(set(volumeList).difference(set(volumeInfo.keys()))) + if not danglingVolumeList: + sys.exit(0) + + print "Cleaning up dangling volume(s):", danglingVolumeList + for volumeName in danglingVolumeList: + Utils.runCommand("rmdir %s/%s" % (Globals.REEXPORT_DIR, volumeName), root=True) + Utils.runCommand("rm -f %s/%s" % (Globals.CIFS_EXPORT_DIR, volumeName), root=True) + if not VolumeUtils.excludeVolume(volumeName): + Utils.log("Failed to exclude volume %s for CIFS reexport" % volumeName) + Utils.runCommand("rm -f %s/%s.smbconf" % (Globals.VOLUME_CONF_DIR, volumeName), root=True) + + sys.exit(0) + +if __name__ == "__main__": + main() diff --git a/src/org.gluster.storage.management.gateway.scripts/src/backend/modify_volume_cifs.py b/src/org.gluster.storage.management.gateway.scripts/src/backend/modify_volume_cifs.py new file mode 100755 index 00000000..d56b1f59 --- /dev/null +++ b/src/org.gluster.storage.management.gateway.scripts/src/backend/modify_volume_cifs.py @@ -0,0 +1,36 @@ +#!/usr/bin/python +# Copyright (C) 2011 Gluster, Inc. <http://www.gluster.com> +# This file is part of Gluster Management Gateway. +# + +import os +import sys +p1 = os.path.abspath(os.path.dirname(sys.argv[0])) +p2 = "%s/common" % os.path.dirname(p1) +if not p1 in sys.path: + sys.path.append(p1) +if not p2 in sys.path: + sys.path.append(p2) +import Utils +import VolumeUtils + +def main(): + if len(sys.argv) <= 2: + sys.stderr.write("usage: %s VOLUME_NAME USER1 USER2 ...\n" % os.path.basename(sys.argv[0])) + sys.exit(-1) + + volumeName = sys.argv[1] + userList = sys.argv[2:] + + if not VolumeUtils.writeVolumeCifsConfiguration(volumeName, userList): + sys.stderr.write("Unable to write cifs configuration\n") + sys.exit(1) + if Utils.runCommand("service smb reload") != 0: + Utils.log("Failed to reload smb service") + sys.stderr.write("Failed to reload smb service\n") + sys.exit(2) + sys.exit(0) + + +if __name__ == "__main__": + main() diff --git a/src/org.gluster.storage.management.gateway.scripts/src/backend/multicast-discoverd.init.d b/src/org.gluster.storage.management.gateway.scripts/src/backend/multicast-discoverd.init.d new file mode 100755 index 00000000..7cfbe44a --- /dev/null +++ b/src/org.gluster.storage.management.gateway.scripts/src/backend/multicast-discoverd.init.d @@ -0,0 +1,48 @@ +#!/bin/bash +# Copyright (C) 2011 Gluster, Inc. <http://www.gluster.com> +# This file is part of Gluster Management Gateway. +# +# chkconfig: - 85 15 +# description: multicast discovery service +# processname: multicast-discoverd +# pidfile: /var/run/multicast-discoverd.pid + +# Source function library. + +. /etc/init.d/functions + +case "$1" in + start) + echo -n "Starting multicast-discoverd:" + daemon multicast-discoverd + RETVAL=$? + echo + [ $RETVAL -eq 0 ] && touch /var/lock/subsys/multicast-discoverd + ;; + stop) + echo -n "Shutting down multicast-discoverd:" + killproc multicast-discoverd + RETVAL=$? + echo + [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/multicast-discoverd + ;; + restart) + $0 stop + $0 start + RETVAL=$? + ;; + status) + status multicast-discoverd + RETVAL=$? + ;; + reload) + killproc multicast-discoverd -HUP + RETVAL=$? + echo + ;; + *) + echo $"Usage: $0 {start|stop|restart|status|reload}" + exit 1 +esac + +exit $RETVAL diff --git a/src/org.gluster.storage.management.gateway.scripts/src/backend/multicast-discoverd.py b/src/org.gluster.storage.management.gateway.scripts/src/backend/multicast-discoverd.py new file mode 100755 index 00000000..cb5de70c --- /dev/null +++ b/src/org.gluster.storage.management.gateway.scripts/src/backend/multicast-discoverd.py @@ -0,0 +1,103 @@ +#!/usr/bin/python +# Copyright (C) 2011 Gluster, Inc. <http://www.gluster.com> +# This file is part of Gluster Management Gateway. +# + +import os +import sys +p1 = os.path.abspath(os.path.dirname(sys.argv[0])) +p2 = "%s/common" % os.path.dirname(p1) +if not p1 in sys.path: + sys.path.append(p1) +if not p2 in sys.path: + sys.path.append(p2) +import socket +import struct +import signal +import time +import Utils +import Globals + +PID_FILE = "/var/run/multicast-discoverd.pid" +GLUSTERD_UUID = "NA" + +def exitHandler(signum, frame): + 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))) + sys.exit(0) + + +def updateGlusterdUuid(signum, frame): + lines = Utils.readFile("/etc/glusterd/glusterd.info", lines=True) + for line in lines: + if line.strip().startswith("UUID="): + GLUSTERD_UUID = line.strip().split("=")[1] + return + GLUSTERD_UUID = "NA" + + +def isInPeer(): + status = Utils.runCommand("gluster peer status", output=True) + if status["Status"] == 0: + if status["Stdout"].strip().upper() != "NO PEERS PRESENT": + return True + return False + + +def main(): + if os.path.exists(PID_FILE): + sys.stderr.write("fatal: PID file %s exists\n" % PID_FILE) + sys.exit(-1) + if not Utils.daemonize(): + sys.stderr.write("fatal: unable to run as daemon\n") + sys.exit(-1) + try: + fp = open(PID_FILE, "w") + fp.write("%s\n" % os.getpid()) + fp.close() + except IOError, e: + Utils.log("failed to create PID file %s: %s" % (PID_FILE, str(e))) + sys.exit(1) + + updateGlusterdUuid(None, None) + + signal.signal(signal.SIGINT, exitHandler) + signal.signal(signal.SIGTERM, exitHandler) + signal.signal(signal.SIGHUP, exitHandler) + + multicastSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) + multicastSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + multicastSocket.bind(('', Globals.MULTICAST_PORT)) + multicastSocket.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, + struct.pack("4sl", socket.inet_aton(Globals.MULTICAST_GROUP), + socket.INADDR_ANY)) + + while True: + request = multicastSocket.recvfrom(Globals.DEFAULT_BUFSIZE) + if not request: + continue + #print "received [%s] from %s" % (request[0], request[1]) + tokens = request[0].strip().split(",") + if len(tokens) != 3: + continue + if tokens[0] != Globals.GLUSTER_PROBE_STRING: + continue + if isInPeer(): + continue + + time.sleep(0.2) + try: + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + sock.connect((request[1][0], Globals.SERVER_PORT)) + sock.send("%s,%s,%s,%s,%s,%s\n" % (tokens[0], tokens[1], tokens[2], socket.gethostname(), socket.getfqdn(), GLUSTERD_UUID)) + sock.close() + except socket.error, e: + Utils.log("failed to send reply to [%s:%s]: %s" % (request[1][0], Globals.SERVER_PORT, str(e))) + sys.exit(0) + + +if __name__ == "__main__": + main() diff --git a/src/org.gluster.storage.management.gateway.scripts/src/backend/rrd_cpu.pl b/src/org.gluster.storage.management.gateway.scripts/src/backend/rrd_cpu.pl new file mode 100755 index 00000000..30a66342 --- /dev/null +++ b/src/org.gluster.storage.management.gateway.scripts/src/backend/rrd_cpu.pl @@ -0,0 +1,84 @@ +#!/usr/bin/perl + +use RRDs; + +my $rrdlog = '/var/lib/rrd'; +my $graphs = '/var/lib/rrd'; + +updatecpudata(); +#updatecpugraph('day'); +#updatecpugraph('week'); +#updatecpugraph('month'); +#updatecpugraph('year'); + +sub updatecpugraph { + my $period = $_[0]; + + RRDs::graph ("$graphs/cpu-$period.png", + "--start", "-1$period", "-aPNG", "-i", "-z", + "--alt-y-grid", "-w 300", "-h 50", "-l 0", "-u 100", "-r", + "--color", "SHADEA#FFFFFF", + "--color", "SHADEB#FFFFFF", + "--color", "BACK#FFFFFF", + "-t cpu usage per $period", + "DEF:user=$rrdlog/cpu.rrd:user:AVERAGE", + "DEF:system=$rrdlog/cpu.rrd:system:AVERAGE", + "DEF:idle=$rrdlog/cpu.rrd:idle:AVERAGE", + + "CDEF:total=user,system,idle,+,+", + "CDEF:userpct=100,user,total,/,*", + "CDEF:systempct=100,system,total,/,*", + "CDEF:idlepct=100,idle,total,/,*", + + "AREA:userpct#0000FF:User cpu usage\\j", + "STACK:systempct#FF0000:system cpu usage\\j", + "STACK:idlepct#00FF00:idle cpu usage\\j"); + + # "GPRINT:userpct:MAX:maximal user cpu\\:%3.2lf%%", + # "GPRINT:userpct:AVERAGE:average user cpu\\:%3.2lf%%", + # "GPRINT:userpct:LAST:current user cpu\\:%3.2lf%%\\j", + # "GPRINT:systempct:MAX:maximal system cpu\\:%3.2lf%%", + # "GPRINT:systempct:AVERAGE:average system cpu\\:%3.2lf%%", + # "GPRINT:systempct:LAST:current system cpu\\:%3.2lf%%\\j", + # "GPRINT:idlepct:MAX:maximal idle cpu\\:%3.2lf%%", + # "GPRINT:idlepct:AVERAGE:average idle cpu\\:%3.2lf%%", + # "GPRINT:idlepct:LAST:current idle cpu\\:%3.2lf%%\\j"); + $ERROR = RRDs::error; + print "Error in RRD::graph for cpu: $ERROR\n" if $ERROR; +} + +sub updatecpudata { + if ( ! -e "$rrdlog/cpu.rrd") { + RRDs::create ("$rrdlog/cpu.rrd", "--step=300", + "DS:user:COUNTER:600:0:U", + "DS:system:COUNTER:600:0:U", + "DS:idle:COUNTER:600:0:U", + + "RRA:AVERAGE:0.5:1:576", + "RRA:AVERAGE:0.5:6:672", + "RRA:AVERAGE:0.5:24:732", + "RRA:AVERAGE:0.5:144:1460"); + $ERROR = RRDs::error; + print "Error in RRD::create for cpu: $ERROR\n" if $ERROR; + } + + my ($cpu, $user, $nice, $system,$idle); + + open STAT, "/proc/stat"; + while(<STAT>) { + chomp; + /^cpu\s/ or next; + ($cpu, $user, $nice, $system, $idle) = split /\s+/; + last; + } + close STAT; + $user += $nice; + + RRDs::update ("$rrdlog/cpu.rrd", + "-t", "user:system:idle", + "N:$user:$system:$idle"); + $ERROR = RRDs::error; + print "Error in RRD::update for cpu: $ERROR\n" if $ERROR; + + #print "N:$user:$system:$idle\n"; +} diff --git a/src/org.gluster.storage.management.gateway.scripts/src/backend/rrd_mem.pl b/src/org.gluster.storage.management.gateway.scripts/src/backend/rrd_mem.pl new file mode 100755 index 00000000..5c47cd81 --- /dev/null +++ b/src/org.gluster.storage.management.gateway.scripts/src/backend/rrd_mem.pl @@ -0,0 +1,100 @@ +#!/usr/bin/perl + +use RRDs; + +my $rrdlog = '/var/lib/rrd'; +my $graphs = '/var/lib/rrd'; + +updatememdata (); +#updatememgraph ('day'); +#updatememgraph ('week'); +#updatememgraph ('month'); +#updatememgraph ('year'); + +sub updatememgraph { + my $period = $_[0]; + + RRDs::graph ("$graphs/memory-$period.png", + "--start", "-1$period", "-aPNG", "-i", "-z", + "--alt-y-grid", "-w 300", "-h 50", "-l 0", "-u 100", "-r", + "--color", "SHADEA#FFFFFF", + "--color", "SHADEB#FFFFFF", + "--color", "BACK#FFFFFF", + "-t memory usage per $period", + "DEF:used=$rrdlog/mem.rrd:memused:AVERAGE", + "DEF:free=$rrdlog/mem.rrd:memfree:AVERAGE", + "DEF:cache=$rrdlog/mem.rrd:memcache:AVERAGE", + "CDEF:total=used,free,+", + "CDEF:used1=used,buffer,cache,-,-", + "CDEF:usedpct=100,used1,total,/,*", + "CDEF:free1=total,used1,-", + "CDEF:cachepct=100,cache,total,/,*", + "CDEF:freepct=100,free1,total,/,*", + "AREA:usedpct#0000FF:used memory\\j", + "STACK:cachepct#FFFF00:cached memory\\j", + "STACK:freepct#00FF00:free memory\\j"); + $ERROR = RRDs::error; + print "Error in RRD::graph for mem: $ERROR\n" if $ERROR; + + RRDs::graph ("$graphs/swap-$period.png", + "--start", "-1$period", "-aPNG", "-i", "-z", + "--alt-y-grid", "-w 300", "-h 50", "-l 0", "-u 100", "-r", + "--color", "SHADEA#FFFFFF", + "--color", "SHADEB#FFFFFF", + "--color", "BACK#FFFFFF", + "-t swap usage per $period", + "DEF:used=$rrdlog/mem.rrd:swapused:AVERAGE", + "DEF:free=$rrdlog/mem.rrd:swapfree:AVERAGE", + "CDEF:total=used,free,+", + "CDEF:usedpct=100,used,total,/,*", + "CDEF:freepct=100,free,total,/,*", + "AREA:usedpct#0000FF:used swap\\j", + "STACK:freepct#00FF00:free swap\\j"); + $ERROR = RRDs::error; + print "Error in RRD::graph for swap: $ERROR\n" if $ERROR; +} + +sub updatememdata { + my ($memused, $memfree, $memshared, $membuffers, $memcache, $swapused, $swapfree); + if ( ! -e "$rrdlog/mem.rrd") { + RRDs::create ("$rrdlog/mem.rrd", "--step=300", + "DS:memused:ABSOLUTE:600:0:U", + "DS:memfree:ABSOLUTE:600:0:U", + "DS:memcache:ABSOLUTE:600:0:U", + "DS:membuffer:ABSOLUTE:600:0:U", + "DS:swapused:ABSOLUTE:600:0:U", + "DS:swapfree:ABSOLUTE:600:0:U", + "RRA:AVERAGE:0.5:1:576", + "RRA:AVERAGE:0.5:6:672", + "RRA:AVERAGE:0.5:24:732", + "RRA:AVERAGE:0.5:144:1460"); + $ERROR = RRDs::error; + print "Error in RRD::create for mem: $ERROR\n" if $ERROR; + } + + my @memdata = `free -b -o`; + + my $temp = $memdata[1]; + + chomp( $temp ); + my @tempa = split (/\s+/, $temp); + $memused = $tempa [2]; + $memfree = $tempa [3]; + $memshared = $tempa [4]; + $membuffers = $tempa [5]; + $memcache = $tempa [6]; + + $temp = $memdata[2]; + chomp( $temp ); + @tempa = split (/\s+/, $temp); + $swapused = $tempa [2]; + $swapfree = $tempa [3]; + + + RRDs::update ("$rrdlog/mem.rrd", + "-t", "memused:memfree:memcache:membuffer:swapused:swapfree", + "N:$memused:$memfree:$memcache:$membuffers:$swapused:$swapfree"); + + $ERROR = RRDs::error; + print "Error in RRD::update for mem: $ERROR\n" if $ERROR; +} diff --git a/src/org.gluster.storage.management.gateway.scripts/src/backend/rrd_net.pl b/src/org.gluster.storage.management.gateway.scripts/src/backend/rrd_net.pl new file mode 100755 index 00000000..6ae128fd --- /dev/null +++ b/src/org.gluster.storage.management.gateway.scripts/src/backend/rrd_net.pl @@ -0,0 +1,75 @@ +#!/usr/bin/perl + +use RRDs; + +my $rrdlog = '/var/lib/rrd'; +my $graphs = '/var/lib/rrd'; + +updatenetdata(); +#updatenetgraph('hour'); +#updatenetgraph('day'); +#updatenetgraph('week'); +#updatenetgraph('month'); +#updatenetgraph('year'); + +sub updatenetgraph { + my $period = $_[0]; + + foreach $rrdfile (<$rrdlog/network-*.rrd>) { + RRDs::graph ("$graphs/network-$device-$period.png", + "--start", "-1$period", "-aPNG", "-i", "-z", + "--alt-y-grid", "-w 800", "-h 400", "-l 0", "-u 10000000", "-r", + "--color", "SHADEA#FFFFFF", + "--color", "SHADEB#FFFFFF", + "--color", "BACK#FFFFFF", + "-t $device load per $period", + "DEF:received=$rrdfile:received:AVERAGE", + "DEF:transmitted=$rrdfile:transmitted:AVERAGE", + + "LINE2:received#FF0000:received load\\j", + "LINE1:transmitted#0000FF:transmitted load\\j"); + + $ERROR = RRDs::error; + print "Error in RRD::graph for network $device: $ERROR\n" if $ERROR; + } +} + +sub updatenetdata { + open NETDEV, "/proc/net/dev"; + while (<NETDEV>) { + chomp; + s/^\s+//; # remove left side whitespaces + /:.+/ or next; # if input line contains ':' else continue + next if /^lo:/; # continue if input line starts with 'lo:' + + @tokens1 = split /:/; # split with ':' + $tokens1[1]=~s/^\s+//; # remove left side whitespaces + @tokens2 = split(/\s+/, $tokens1[1]); # split with space + + $device = $tokens1[0]; + $received = $tokens2[0]; + $transmitted = $tokens2[8]; + + #print "$device, $received, $transmitted \n"; + + if ( ! -e "$rrdlog/network-$device.rrd") { + RRDs::create ("$rrdlog/network-$device.rrd", "--step=300", + "DS:received:COUNTER:600:0:U", + "DS:transmitted:COUNTER:600:0:U", + + "RRA:AVERAGE:0.5:1:576", + "RRA:AVERAGE:0.5:6:672", + "RRA:AVERAGE:0.5:24:732", + "RRA:AVERAGE:0.5:144:1460"); + $ERROR = RRDs::error; + print "Error in RRD::create for device $device: $ERROR\n" if $ERROR; + } + + RRDs::update ("$rrdlog/network-$device.rrd", + "-t", "received:transmitted", + "N:$received:$transmitted"); + $ERROR = RRDs::error; + print "Error in RRD::update for net: $ERROR\n" if $ERROR; + } + close NETDEV +} diff --git a/src/org.gluster.storage.management.gateway.scripts/src/backend/setup_cifs_config.py b/src/org.gluster.storage.management.gateway.scripts/src/backend/setup_cifs_config.py new file mode 100755 index 00000000..5d5187f4 --- /dev/null +++ b/src/org.gluster.storage.management.gateway.scripts/src/backend/setup_cifs_config.py @@ -0,0 +1,108 @@ +#!/usr/bin/python +# Copyright (C) 2011 Gluster, Inc. <http://www.gluster.com> +# This file is part of Gluster Management Gateway. +# + +import os +import sys +p1 = os.path.abspath(os.path.dirname(sys.argv[0])) +p2 = "%s/common" % os.path.dirname(p1) +if not p1 in sys.path: + sys.path.append(p1) +if not p2 in sys.path: + sys.path.append(p2) +import time +import Globals +import Utils + +def main(): + try: + if not os.path.exists(Globals.GLUSTER_BASE_DIR): + os.mkdir(Globals.GLUSTER_BASE_DIR) + if not os.path.exists(Globals.VOLUME_CONF_DIR): + os.mkdir(Globals.VOLUME_CONF_DIR) + if not os.path.exists(Globals.CIFS_EXPORT_DIR): + os.mkdir(Globals.CIFS_EXPORT_DIR) + if not os.path.exists(Globals.REEXPORT_DIR): + os.mkdir(Globals.REEXPORT_DIR) + except OSError, e: + Utils.log("failed to create directory: %s" % str(e)) + sys.stderr.write("Failed to create directory: %s\n" % str(e)) + sys.exit(1) + try: + if not os.path.exists(Globals.VOLUME_SMBCONF_FILE): + fp = open(Globals.VOLUME_SMBCONF_FILE, "w") + fp.close() + except IOError, e: + Utils.log("Failed to create file %s: %s" % (Globals.VOLUME_SMBCONF_FILE, str(e))) + sys.stderr.write("Failed to create file %s: %s\n" % (Globals.VOLUME_SMBCONF_FILE, str(e))) + sys.exit(2) + try: + backupFile = "%s.%s" % (Globals.SAMBA_CONF_FILE, time.time()) + os.rename(Globals.SAMBA_CONF_FILE, backupFile) + except IOError, e: + Utils.log("Ignoring rename %s to %s: %s" % (Globals.SAMBA_CONF_FILE, backupFile)) + sys.stderr.write("Ignoring rename %s to %s: %s\n" % (Globals.SAMBA_CONF_FILE, backupFile)) + try: + fp = open(Globals.SAMBA_CONF_FILE, "w") + fp.write("##\n") + fp.write("## THIS FILE SHOULD NOT BE MODIFIED. IF YOU WANT TO MODIFY SAMBA\n") + fp.write("## CONFIGURATIONS, USE /etc/samba/real.smb.conf FILE\n") + fp.write("##\n") + fp.write("include = %s\n\n" % Globals.REAL_SAMBA_CONF_FILE) + fp.write("## CAUTION: DO NOT REMOVE BELOW LINE. REMOVAL OF THE LINE DISABLES\n") + fp.write("## CIFS REEXPORT OF GLUSTER VOLUMES\n") + fp.write("include = %s\n" % Globals.VOLUME_SMBCONF_FILE) + fp.close() + except IOError, e: + Utils.log("Failed to create samba configuration file %s: %s" % (Globals.SAMBA_CONF_FILE, str(e))) + sys.stderr.write("Failed to create samba configuration file %s: %s\n" % (Globals.SAMBA_CONF_FILE, str(e))) + sys.exit(3) + try: + if not os.path.exists(Globals.REAL_SAMBA_CONF_FILE): + fp = open(Globals.REAL_SAMBA_CONF_FILE, "w") + fp.write("[global]\n") + fp.write("## CAUTION: DO NOT REMOVE BELOW INCLUDE LINE. REMOVAL OF THE LINE\n") + fp.write("## DISABLES SERVER/CIFS HIGH AVAILABILITY\n") + #fp.write("include = %s\n" % Globals.CTDB_SAMBA_CONF_FILE) + fp.write("##\n") + fp.write("socket options = TCP_NODELAY IPTOS_LOWDELAY SO_SNDBUF=131072 SO_RCVBUF=131072\n") + fp.write("read raw = yes\n") + fp.write("server string = %h\n") + fp.write("write raw = yes\n") + fp.write("oplocks = yes\n") + fp.write("max xmit = 131072\n") + fp.write("dead time = 15\n") + fp.write("getwd cache = yes\n") + fp.write("#read size = 131072\n") + fp.write("use sendfile=yes\n") + fp.write("block size = 131072\n") + fp.write("printcap name = /etc/printcap\n") + fp.write("load printers = no\n") + fp.close() + except IOError, e: + Utils.log("Failed to create samba configuration file %s: %s" % (Globals.REAL_SAMBA_CONF_FILE, str(e))) + sys.stderr.write("Failed to create samba configuration file %s: %s\n" % (Globals.REAL_SAMBA_CONF_FILE, str(e))) + sys.exit(4) + + if Utils.runCommand("/usr/sbin/selinuxenabled") == 0: + if Utils.runCommand("setsebool -P samba_share_fusefs on") != 0: + Utils.log("failed to set SELinux samba_share_fusefs") + sys.stderr.write("failed to set SELinux samba_share_fusefs\n") + sys.exit(5) + + if Utils.runCommand("service smb status") != 0: + if Utils.runCommand("service smb start") != 0: + Utils.log("failed to start smb service") + sys.stderr.write("Failed to start smb service\n") + sys.exit(6) + + if Utils.runCommand("service smb reload") != 0: + Utils.log("failed to reload smb configuration") + sys.stderr.write("Failed to reload smb configuration\n") + sys.exit(7) + sys.exit(0) + + +if __name__ == "__main__": + main() diff --git a/src/org.gluster.storage.management.gateway.scripts/src/backend/start_volume_cifs.py b/src/org.gluster.storage.management.gateway.scripts/src/backend/start_volume_cifs.py new file mode 100755 index 00000000..e16c87c2 --- /dev/null +++ b/src/org.gluster.storage.management.gateway.scripts/src/backend/start_volume_cifs.py @@ -0,0 +1,53 @@ +#!/usr/bin/python +# Copyright (C) 2011 Gluster, Inc. <http://www.gluster.com> +# This file is part of Gluster Management Gateway. +# + +import os +import sys +p1 = os.path.abspath(os.path.dirname(sys.argv[0])) +p2 = "%s/common" % os.path.dirname(p1) +if not p1 in sys.path: + sys.path.append(p1) +if not p2 in sys.path: + sys.path.append(p2) +import Globals +import Utils +import VolumeUtils + +def main(): + if len(sys.argv) != 2: + sys.stderr.write("usage: %s VOLUME_NAME\n" % os.path.basename(sys.argv[0])) + sys.exit(-1) + + volumeName = sys.argv[1] + + volumeMountDirName = "%s/%s" % (Globals.REEXPORT_DIR, volumeName) + cifsDirName = "%s/%s" % (Globals.CIFS_EXPORT_DIR, volumeName) + + if Utils.runCommand("mount -t glusterfs 127.0.0.1:%s %s" % (volumeName, volumeMountDirName)) != 0: + Utils.log("Failed to mount volume %s" % (volumeName)) + sys.stderr.write("Failed to mount volume %s\n" % (volumeName)) + sys.exit(1) + if Utils.runCommand("ln -fTs %s %s" % (volumeMountDirName, cifsDirName)) != 0: + Utils.log("Failed to create reexport link %s" % cifsDirName) + sys.stderr.write("Failed to create reexport link %s\n" % cifsDirName) + sys.exit(2) + if Utils.runCommand("/usr/sbin/selinuxenabled") == 0: + if Utils.runCommand("chcon -t samba_share_t %s -h" % cifsDirName) != 0: + Utils.log("Failed to change security context for the link %s" % cifsDirName) + sys.stderr.write("Failed to change security context for the link %s\n" % cifsDirName) + sys.exit(2) + if not VolumeUtils.includeVolume(volumeName): + Utils.log("Failed to include volume for CIFS reexport") + sys.stderr.write("Failed to include volume for CIFS reexport\n") + sys.exit(3) + if Utils.runCommand("service smb reload") != 0: + Utils.log("Failed to reload smb service") + sys.stderr.write("Failed to reload smb service\n") + sys.exit(4) + sys.exit(0) + + +if __name__ == "__main__": + main() diff --git a/src/org.gluster.storage.management.gateway.scripts/src/backend/stop_volume_cifs.py b/src/org.gluster.storage.management.gateway.scripts/src/backend/stop_volume_cifs.py new file mode 100755 index 00000000..d67d9061 --- /dev/null +++ b/src/org.gluster.storage.management.gateway.scripts/src/backend/stop_volume_cifs.py @@ -0,0 +1,48 @@ +#!/usr/bin/python +# Copyright (C) 2011 Gluster, Inc. <http://www.gluster.com> +# This file is part of Gluster Management Gateway. +# + +import os +import sys +p1 = os.path.abspath(os.path.dirname(sys.argv[0])) +p2 = "%s/common" % os.path.dirname(p1) +if not p1 in sys.path: + sys.path.append(p1) +if not p2 in sys.path: + sys.path.append(p2) +import Globals +import Utils +import VolumeUtils + +def main(): + if len(sys.argv) != 2: + sys.stderr.write("usage: %s VOLUME_NAME\n" % os.path.basename(sys.argv[0])) + sys.exit(-1) + + volumeName = sys.argv[1] + + volumeMountDirName = "%s/%s" % (Globals.REEXPORT_DIR, volumeName) + cifsDirName = "%s/%s" % (Globals.CIFS_EXPORT_DIR, volumeName) + + if not Utils.removeFile(cifsDirName): + Utils.log("Failed to remove reexport link %s" % cifsDirName) + sys.stderr.write("Failed to remove reexport link %s\n" % cifsDirName) + sys.exit(1) + if not VolumeUtils.excludeVolume(volumeName): + Utils.log("Failed to exclude volume for CIFS reexport") + sys.stderr.write("Failed to exclude volume for CIFS reexport\n") + sys.exit(2) + if Utils.runCommand("service smb reload") != 0: + Utils.log("Failed to reload smb service") + sys.stderr.write("Failed to reload smb service\n") + sys.exit(3) + if Utils.runCommand("umount %s" % (volumeMountDirName)) != 0: + Utils.log("Failed to unmount volume %s" % (volumeName)) + sys.stderr.write("Failed to unmount volume %s\n" % (volumeName)) + sys.exit(4) + sys.exit(0) + + +if __name__ == "__main__": + main() diff --git a/src/org.gluster.storage.management.gateway.scripts/src/backend/update-rrd.sh b/src/org.gluster.storage.management.gateway.scripts/src/backend/update-rrd.sh new file mode 100755 index 00000000..b081d6db --- /dev/null +++ b/src/org.gluster.storage.management.gateway.scripts/src/backend/update-rrd.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +/usr/bin/rrd_cpu.pl & +/usr/bin/rrd_mem.pl & +/usr/bin/rrd_net.pl & +wait diff --git a/src/org.gluster.storage.management.gateway.scripts/src/backend/update_volume_cifs.py b/src/org.gluster.storage.management.gateway.scripts/src/backend/update_volume_cifs.py new file mode 100755 index 00000000..64297a87 --- /dev/null +++ b/src/org.gluster.storage.management.gateway.scripts/src/backend/update_volume_cifs.py @@ -0,0 +1,37 @@ +#!/usr/bin/python +# Copyright (C) 2011 Gluster, Inc. <http://www.gluster.com> +# This file is part of Gluster Management Gateway. +# + +import os +import sys +p1 = os.path.abspath(os.path.dirname(sys.argv[0])) +p2 = "%s/common" % os.path.dirname(p1) +if not p1 in sys.path: + sys.path.append(p1) +if not p2 in sys.path: + sys.path.append(p2) +import Globals +import Utils +import VolumeUtils + +def main(): + if len(sys.argv) < 3: + sys.stderr.write("usage: %s VOLUME_NAME USER1 USER2 ...\n" % os.path.basename(sys.argv[0])) + sys.exit(-1) + + volumeName = sys.argv[1] + userList = sys.argv[2:] + + if not VolumeUtils.writeVolumeCifsConfiguration(volumeName, userList): + sys.stderr.write("Failed to update volume cifs configuration\n") + sys.exit(1) + if Utils.runCommand("service smb reload") != 0: + Utils.log("Failed to reload smb service") + sys.stderr.write("Failed to reload smb service\n") + sys.exit(2) + sys.exit(0) + + +if __name__ == "__main__": + main() diff --git a/src/org.gluster.storage.management.gateway.scripts/src/common/Globals.py b/src/org.gluster.storage.management.gateway.scripts/src/common/Globals.py new file mode 100644 index 00000000..49a12b69 --- /dev/null +++ b/src/org.gluster.storage.management.gateway.scripts/src/common/Globals.py @@ -0,0 +1,35 @@ +# Copyright (C) 2011 Gluster, Inc. <http://www.gluster.com> +# This file is part of Gluster Storage Platform. +# + +MULTICAST_GROUP = '224.224.1.1' +MULTICAST_PORT = 24729 +GLUSTER_PROBE_STRING = "GLUSTERPROBE" +GLUSTER_PROBE_VERSION = "1.0.0" +DEFAULT_BUFSIZE = 1024 +SERVER_PORT = 24731 +DEFAULT_BACKLOG = 5 +DEFAULT_TIMEOUT = 3 +DEFAULT_ID_LENGTH = 16 +GLUSTER_PLATFORM_VERSION = "3.2" + +## System configuration constants +SYSCONFIG_NETWORK_DIR = "/etc/sysconfig/network-scripts" +FSTAB_FILE = "/etc/fstab" +SAMBA_CONF_FILE = "/etc/samba/smb.conf" +REAL_SAMBA_CONF_FILE = "/etc/samba/real.smb.conf" +MODPROBE_CONF_FILE = "/etc/modprobe.d/bonding.conf" +RESOLV_CONF_FILE = "/etc/resolv.conf" +VOLUME_USER_DESCRIPTION = "Gluster Volume User" +GLUSTER_BASE_DIR = "/etc/glustermg" +REEXPORT_DIR = "/reexport" +CIFS_EXPORT_DIR = "/cifs" + +## Derived constants +VOLUME_CONF_DIR = GLUSTER_BASE_DIR + "/volumes" +VOLUME_SMBCONF_FILE = VOLUME_CONF_DIR + "/volumes.smbconf.list" + +AWS_WEB_SERVICE_URL = "http://169.254.169.254/latest" +DEFAULT_UID = 1024000 +CIFS_USER_FILE = "/opt/glustermg/etc/users.cifs" +CIFS_VOLUME_FILE = "/opt/glustermg/etc/volumes.cifs" diff --git a/src/org.gluster.storage.management.gateway.scripts/src/common/Utils.py b/src/org.gluster.storage.management.gateway.scripts/src/common/Utils.py new file mode 100644 index 00000000..3c90c533 --- /dev/null +++ b/src/org.gluster.storage.management.gateway.scripts/src/common/Utils.py @@ -0,0 +1,329 @@ +# Copyright (C) 2011 Gluster, Inc. <http://www.gluster.com> +# This file is part of Gluster Management Gateway. +# + +import os +import sys +p1 = os.path.abspath(os.path.dirname(sys.argv[0])) +p2 = "%s/common" % os.path.dirname(p1) +if not p1 in sys.path: + sys.path.append(p1) +if not p2 in sys.path: + sys.path.append(p2) +import re +import syslog +import subprocess +import time +import tempfile +import glob + +import Globals + +RUN_COMMAND_ERROR = -1024 +LOG_SYSLOG = 1 +SYSLOG_REQUIRED = False +LOG_FILE_NAME = None +LOG_FILE_OBJ = None +logOpened = False +sshCommandPrefix = "ssh -l root -q -i /opt/glustermg/keys/gluster.pem -o BatchMode=yes -o GSSAPIAuthentication=no -o PasswordAuthentication=no -o StrictHostKeyChecking=no".split() +try: + commandPath = "/opt/glustermg/%s/backend" % os.environ['GMG_VERSION'] +except KeyError, e: + commandPath = "/opt/glustermg/1.0.0/backend" + +def log(priority, message=None): + global logOpened + if not logOpened: + syslog.openlog(os.path.basename(sys.argv[0])) + logOpened = True + + 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 isString(value): + return (type(value) == type("") or type(value) == type(u"")) + + +def getTempFileName(): + filedesc, filename = tempfile.mkstemp(prefix="GSP_") + os.close(filedesc) + return filename + + +def readFile(fileName, lines=False): + content = None + try: + fp = open(fileName) + if lines: + content = fp.readlines() + else: + content = fp.read() + fp.close() + return content + except IOError, e: + log("failed to read file %s: %s" % (fileName, str(e))) + if lines: + return [] + else: + return "" + + +def writeFile(fileName, content): + try: + fp = open(fileName, "w") + if isString(content): + fp.write(content) + elif type(content) == type([]): + fp.writelines(content) + fp.close() + return True + except IOError, e: + log("failed to write file %s: %s" % (fileName, str(e))) + return False + + +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: + log("Failed to remove file %s: %s" % (fileName, str(e))) + return False + + +def runCommandBG(command, stdinFileObj=None, stdoutFileObj=None, stderrFileObj=None, + shell=False, root=None): + 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'] = readFile(stdoutFileName) + rv['Stderr'] = readFile(stderrFileName) + + os.remove(stdinFileName) + os.remove(stdoutFileName) + os.remove(stderrFileName) + + if output: + return rv + return rv["Status"] + + +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 getMeminfo(): + lines = readFile("/proc/meminfo", lines=True) + re_parser = re.compile(r'^(?P<key>\S*):\s*(?P<value>\d*)\s*kB' ) + result = {} + for line in lines: + 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) + result['MemUsed'] = (result['MemTotal'] - result['MemFree'] - result['Buffers'] - result['Cached']) + return result + + +def _getCpuStatList(): + lines = readFile("/proc/stat", lines=True) + if not lines: + return None + return map(float, lines[0].split()[1:5]) + + +def getCpuUsageAvg(): + st1 = _getCpuStatList() + #time1 = time.time() + time.sleep(1) + st2 = _getCpuStatList() + #time2 = time.time() + if not (st1 and st2): + return None + usageTime = (st2[0] - st1[0]) + (st2[1] - st1[1]) + (st2[2] - st1[2]) + try: + return (100.0 * usageTime) / (usageTime + (st2[3] - st1[3])) + except ZeroDivisionError, e: + return 0 + + +def convertKbToMb(kb): + return kb / 1024.0 + + +def getDeviceFormatStatusFile(device): + return "/var/tmp/format_%s.status" % device.replace('/', '_') + + +def getDeviceFormatLockFile(device): + return "/var/lock/format_%s.lock" % device.replace('/', '_') + + +def getDeviceFormatOutputFile(device): + return "/var/tmp/format_%s.out" % device.replace('/', '_') + + +def getGlusterVersion(): + rv = runCommand("/usr/sbin/gluster --version", output=True) + if rv["Stderr"]: + return None + if rv["Status"] != 0: + return None + if not rv["Stdout"]: + return None + return rv["Stdout"].strip().split()[1] + + +def getCifsUserUid(userName): + lines = readFile(Globals.CIFS_USER_FILE, lines=True) + for line in lines: + if not line.strip(): + continue + tokens = line.strip().split(":") + if tokens[1] == userName: + return int(tokens[0]) + return None + +def grun(serverFile, command, argumentList=[]): + commandList = ["%s/%s" % (commandPath, command)] + argumentList + serverNameList = readFile(serverFile, lines=True) + if not serverNameList: + return 1 + status = True + for serverName in serverNameList: + rv = runCommand(sshCommandPrefix + [serverName.strip()] + commandList, output=True) + if rv["Status"] != 0: + sys.stderr.write("%s: %s\n" % (serverName.strip(), rv["Status"])) + sys.stderr.write("Stdout:\n%s\n" % rv["Stdout"]) + sys.stderr.write("Stderr:\n%s\n" % rv["Stderr"]) + sys.stderr.write("---\n") + status = False + + if status: + return 0 + else: + return 2 + +def getFileSystemType(): + return [os.path.basename(i).split('.')[1] for i in glob.glob("/sbin/mkfs.*")] diff --git a/src/org.gluster.storage.management.gateway.scripts/src/common/XmlHandler.py b/src/org.gluster.storage.management.gateway.scripts/src/common/XmlHandler.py new file mode 100644 index 00000000..d55ef07a --- /dev/null +++ b/src/org.gluster.storage.management.gateway.scripts/src/common/XmlHandler.py @@ -0,0 +1,332 @@ +# Copyright (C) 2011 Gluster, Inc. <http://www.gluster.com> +# This file is part of Gluster Management Gateway. +# + +import xml +import xml.parsers.expat +import xml.dom.minidom as MDOM +import os +import Globals +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, e: + 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, e: + XDOM.__init__(self) + except xml.parsers.expat.ExpatError, e: + 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/org.gluster.storage.management.gateway.scripts/src/gateway/add_user_cifs_all.py b/src/org.gluster.storage.management.gateway.scripts/src/gateway/add_user_cifs_all.py new file mode 100755 index 00000000..adfd031c --- /dev/null +++ b/src/org.gluster.storage.management.gateway.scripts/src/gateway/add_user_cifs_all.py @@ -0,0 +1,78 @@ +#!/usr/bin/python +# Copyright (C) 2011 Gluster, Inc. <http://www.gluster.com> +# This file is part of Gluster Management Gateway. +# + +import os +import sys +p1 = os.path.abspath(os.path.dirname(sys.argv[0])) +p2 = "%s/common" % os.path.dirname(p1) +if not p1 in sys.path: + sys.path.append(p1) +if not p2 in sys.path: + sys.path.append(p2) +import Globals +import Utils + + +def getUid(userName): + lines = Utils.readFile(Globals.CIFS_USER_FILE, lines=True) + for line in lines: + tokens = line.strip().split(":") + if tokens[1] == userName: + return int(tokens[0]) + return None + + +def getLastUid(): + lines = Utils.readFile(Globals.CIFS_USER_FILE, lines=True) + if not lines: + return Globals.DEFAULT_UID + return int([line.strip().split(':')[0] for line in lines if line.strip()][-1]) + + +def setUid(uid, userName): + try: + fp = open(Globals.CIFS_USER_FILE, "a") + fp.write("%s:%s\n" % (uid, userName)) + fp.close() + return True + except IOError, e: + Utils.log("failed to write file %s: %s" % (Globals.CIFS_USER_FILE, str(e))) + return False + + +def main(): + if len(sys.argv) < 4: + sys.stderr.write("usage: %s SERVER_FILE USERNAME PASSWORD\n" % os.path.basename(sys.argv[0])) + sys.exit(-1) + + serverFile = sys.argv[1] + userName = sys.argv[2] + password = sys.argv[3] + + existingUser = False + uid = getUid(userName) + if not uid: + uid = getLastUid() + if not uid: + sys.stderr.write("Unable to read file %s\n" % Globals.CIFS_USER_FILE) + sys.exit(10) + uid += 1 + else: + existingUser = True + + print (serverFile, uid, userName, password) + rv = Utils.grun(serverFile, "add_user_cifs.py", [uid, userName, password]) + if existingUser: + sys.exit(rv) + + if rv == 0: + if not setUid(uid, userName): + sys.stderr.write("Failed to add the user\n") + sys.exit(11) + sys.exit(rv) + + +if __name__ == "__main__": + main() diff --git a/src/org.gluster.storage.management.gateway.scripts/src/gateway/create_volume_cifs_all.py b/src/org.gluster.storage.management.gateway.scripts/src/gateway/create_volume_cifs_all.py new file mode 100755 index 00000000..8a43e7dc --- /dev/null +++ b/src/org.gluster.storage.management.gateway.scripts/src/gateway/create_volume_cifs_all.py @@ -0,0 +1,62 @@ +#!/usr/bin/python +# Copyright (C) 2011 Gluster, Inc. <http://www.gluster.com> +# This file is part of Gluster Management Gateway. +# + +import os +import sys +p1 = os.path.abspath(os.path.dirname(sys.argv[0])) +p2 = "%s/common" % os.path.dirname(p1) +if not p1 in sys.path: + sys.path.append(p1) +if not p2 in sys.path: + sys.path.append(p2) +import Globals +import Utils + + +def addVolumeCifsConf(volumeName, userList): + lines = Utils.readFile(Globals.CIFS_VOLUME_FILE, lines=True) + try: + fp = open(Globals.CIFS_VOLUME_FILE, "w") + for line in lines: + if not line.strip(): + continue + if line.strip().split(":")[0] != volumeName: + fp.write("%s\n" % line) + fp.write("%s:%s\n" % (volumeName, ":".join(userList))) + fp.close() + except IOError, e: + Utils.log("failed to write file %s: %s" % (Globals.CIFS_VOLUME_FILE, str(e))) + return False + return True + + +def main(): + if len(sys.argv) < 4: + sys.stderr.write("usage: %s SERVER_FILE VOLUME_NAME USER1 USER2 ...\n" % os.path.basename(sys.argv[0])) + sys.exit(-1) + + serverFile = sys.argv[1] + volumeName = sys.argv[2] + userList = sys.argv[3:] + + missingUserList = [] + for userName in userList: + if not Utils.getCifsUserUid(userName): + missingUserList.append(userName) + + if missingUserList: + sys.stderr.write("User %s does not exists\n" % missingUserList) + sys.exit(1) + + rv = Utils.grun(serverFile, "create_volume_cifs.py", [volumeName] + userList) + if rv == 0: + if not addVolumeCifsConf(volumeName, userList): + sys.stderr.write("Failed to add volume %s and user-list %s in cifs volume configuration\n" % (volumeName, userList)) + sys.exit(11) + sys.exit(rv) + + +if __name__ == "__main__": + main() diff --git a/src/org.gluster.storage.management.gateway.scripts/src/gateway/delete_user_cifs_all.py b/src/org.gluster.storage.management.gateway.scripts/src/gateway/delete_user_cifs_all.py new file mode 100755 index 00000000..a86e7264 --- /dev/null +++ b/src/org.gluster.storage.management.gateway.scripts/src/gateway/delete_user_cifs_all.py @@ -0,0 +1,52 @@ +#!/usr/bin/python +# Copyright (C) 2011 Gluster, Inc. <http://www.gluster.com> +# This file is part of Gluster Management Gateway. +# + +import os +import sys +p1 = os.path.abspath(os.path.dirname(sys.argv[0])) +p2 = "%s/common" % os.path.dirname(p1) +if not p1 in sys.path: + sys.path.append(p1) +if not p2 in sys.path: + sys.path.append(p2) +import Globals +import Utils + + +def removeUser(userName): + lines = Utils.readFile(Globals.CIFS_USER_FILE, lines=True) + try: + fp = open(Globals.CIFS_USER_FILE, "w") + for line in lines: + if not line.strip(): + continue + if line.split(":")[1] == userName: + continue + fp.write("%s\n" % line) + fp.close() + except IOError, e: + Utils.log("failed to write file %s: %s" % (Globals.CIFS_USER_FILE, str(e))) + return False + return True + + +def main(): + if len(sys.argv) < 3: + sys.stderr.write("usage: %s SERVER_FILE USERNAME\n" % os.path.basename(sys.argv[0])) + sys.exit(-1) + + serverFile = sys.argv[1] + userName = sys.argv[2] + + rv = Utils.grun(serverFile, "delete_user_cifs.py", [userName]) + if rv == 0: + if not removeUser(userName): + Utils.log("Failed to remove the user:%s on gateway server\n" % userName) + sys.exit(0) + sys.exit(rv) + + +if __name__ == "__main__": + main() diff --git a/src/org.gluster.storage.management.gateway.scripts/src/gateway/delete_volume_cifs_all.py b/src/org.gluster.storage.management.gateway.scripts/src/gateway/delete_volume_cifs_all.py new file mode 100755 index 00000000..925a3548 --- /dev/null +++ b/src/org.gluster.storage.management.gateway.scripts/src/gateway/delete_volume_cifs_all.py @@ -0,0 +1,51 @@ +#!/usr/bin/python +# Copyright (C) 2011 Gluster, Inc. <http://www.gluster.com> +# This file is part of Gluster Management Gateway. +# + +import os +import sys +p1 = os.path.abspath(os.path.dirname(sys.argv[0])) +p2 = "%s/common" % os.path.dirname(p1) +if not p1 in sys.path: + sys.path.append(p1) +if not p2 in sys.path: + sys.path.append(p2) +import Globals +import Utils + + +def removeVolumeCifsConf(volumeName): + lines = Utils.readFile(Globals.CIFS_VOLUME_FILE, lines=True) + try: + fp = open(Globals.CIFS_VOLUME_FILE, "w") + for line in lines: + if not line.strip(): + continue + if line.strip().split(":")[0] != volumeName: + fp.write("%s\n" % line) + fp.close() + except IOError, e: + Utils.log("failed to write file %s: %s" % (Globals.CIFS_VOLUME_FILE, str(e))) + return False + return True + + +def main(): + if len(sys.argv) < 3: + sys.stderr.write("usage: %s SERVER_FILE VOLUME_NAME\n" % os.path.basename(sys.argv[0])) + sys.exit(-1) + + serverFile = sys.argv[1] + volumeName = sys.argv[2] + + rv = Utils.grun(serverFile, "delete_volume_cifs.py", [volumeName]) + if rv == 0: + if not removeVolumeCifsConf(volumeName): + sys.stderr.write("Failed to remove volume %s and user-list in cifs volume configuration\n" % volumeName) + sys.exit(11) + sys.exit(rv) + + +if __name__ == "__main__": + main() diff --git a/src/org.gluster.storage.management.gateway.scripts/src/gateway/get_volume_user_cifs.py b/src/org.gluster.storage.management.gateway.scripts/src/gateway/get_volume_user_cifs.py new file mode 100755 index 00000000..c072a556 --- /dev/null +++ b/src/org.gluster.storage.management.gateway.scripts/src/gateway/get_volume_user_cifs.py @@ -0,0 +1,38 @@ +#!/usr/bin/python +# Copyright (C) 2011 Gluster, Inc. <http://www.gluster.com> +# This file is part of Gluster Management Gateway. +# + +import os +import sys +p1 = os.path.abspath(os.path.dirname(sys.argv[0])) +p2 = "%s/common" % os.path.dirname(p1) +if not p1 in sys.path: + sys.path.append(p1) +if not p2 in sys.path: + sys.path.append(p2) +import Globals +import Utils + + +def main(): + if len(sys.argv) < 2: + sys.stderr.write("usage: %s VOLUME_NAME\n" % os.path.basename(sys.argv[0])) + sys.exit(-1) + + volumeName = sys.argv[1] + + lines = Utils.readFile(Globals.CIFS_VOLUME_FILE, lines=True) + for line in lines: + if not line.strip(): + continue + tokens = line.strip().split(":") + if tokens[0] == volumeName: + print "\n".join(tokens[1:]) + sys.exit(0) + # given volume is not configured for cifs export + sys.exit(0) + + +if __name__ == "__main__": + main() diff --git a/src/org.gluster.storage.management.gateway.scripts/src/gateway/gmg-reset-password.sh b/src/org.gluster.storage.management.gateway.scripts/src/gateway/gmg-reset-password.sh new file mode 100755 index 00000000..b39fe6b5 --- /dev/null +++ b/src/org.gluster.storage.management.gateway.scripts/src/gateway/gmg-reset-password.sh @@ -0,0 +1,26 @@ +#----------------------------------------------------------------------------------- +# gmg-reset-password.sh - script to reset password of given user to default password +#----------------------------------------------------------------------------------- + +USAGE_ERR=1 + +if [ $# -ne 1 ]; then + echo "Usage: ${0} <username>" + echo + exit ${USAGE_ERR} +fi + +CURR_DIR=${PWD} +SCRIPT_PATH=`readlink -f ${0}` +GLUSTERMG_DIR=`dirname ${SCRIPT_PATH}` + +# Main action body +cd ${GLUSTERMG_DIR} +cd .. +for FILE in WEB-INF/lib/*.jar +do + export CLASSPATH=${CLASSPATH}:${PWD}/${FILE} +done +export CLASSPATH=${PWD}/WEB-INF/classes:${CLASSPATH} +cd ${CURR_DIR} +java org.gluster.storage.management.gateway.utils.PasswordManager reset ${1} diff --git a/src/org.gluster.storage.management.gateway.scripts/src/gateway/grun.py b/src/org.gluster.storage.management.gateway.scripts/src/gateway/grun.py new file mode 100755 index 00000000..6519d726 --- /dev/null +++ b/src/org.gluster.storage.management.gateway.scripts/src/gateway/grun.py @@ -0,0 +1,21 @@ +#!/usr/bin/python +# Copyright (C) 2011 Gluster, Inc. <http://www.gluster.com> +# This file is part of Gluster Management Gateway. +# + +import os +import sys +p1 = os.path.abspath(os.path.dirname(sys.argv[0])) +p2 = "%s/common" % os.path.dirname(p1) +if not p1 in sys.path: + sys.path.append(p1) +if not p2 in sys.path: + sys.path.append(p2) +import Utils + + +if len(sys.argv) < 3: + sys.stderr.write("usage: %s SERVER_FILE COMMAND [ARGUMENTS]\n" % os.path.basename(sys.argv[0])) + sys.exit(-1) + +sys.exit(Utils.grun(sys.argv[1], sys.argv[2], sys.argv[3:])) diff --git a/src/org.gluster.storage.management.gateway.scripts/src/gateway/multicast-discover-servers.py b/src/org.gluster.storage.management.gateway.scripts/src/gateway/multicast-discover-servers.py new file mode 100755 index 00000000..ded207c0 --- /dev/null +++ b/src/org.gluster.storage.management.gateway.scripts/src/gateway/multicast-discover-servers.py @@ -0,0 +1,112 @@ +#!/usr/bin/python +# Copyright (C) 2011 Gluster, Inc. <http://www.gluster.com> +# This file is part of Gluster Management Gateway. +# + +import os +import sys +p1 = os.path.abspath(os.path.dirname(sys.argv[0])) +p2 = "%s/common" % os.path.dirname(p1) +if not p1 in sys.path: + sys.path.append(p1) +if not p2 in sys.path: + sys.path.append(p2) +import socket +import select +import signal +import random +import string +import Utils +import Globals + +running = True + + +def exitHandler(signum, frame): + running = False + + +def sendMulticastRequest(idString): + multicastSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) + multicastSocket.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2) + multicastSocket.sendto("%s,%s,%s\n" % (Globals.GLUSTER_PROBE_STRING, Globals.GLUSTER_PROBE_VERSION, idString), + (Globals.MULTICAST_GROUP, Globals.MULTICAST_PORT)) + return multicastSocket + + +def openServerSocket(): + try: + server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + server.setblocking(0) + server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + server.bind(('', Globals.SERVER_PORT)) + server.listen(Globals.DEFAULT_BACKLOG) + return server + except socket.error, e: + Utils.log("failed to open server socket on port %s: %s" % (Globals.SERVER_PORT, str(e))) + sys.stderr.write("failed to open server socket on port %s: %s\n" % (Globals.SERVER_PORT, str(e))) + sys.exit(1) + + +def main(): + signal.signal(signal.SIGINT, exitHandler) + signal.signal(signal.SIGTERM, exitHandler) + signal.signal(signal.SIGALRM, exitHandler) + + idString = ''.join(random.choice(string.ascii_lowercase + + string.ascii_uppercase + + string.digits) for x in range(Globals.DEFAULT_ID_LENGTH)) + + multicastSocket = sendMulticastRequest(idString) + + serverInfoDict = {} + serverSocket = openServerSocket() + rlist = [serverSocket] + signal.alarm(Globals.DEFAULT_TIMEOUT) + while running: + try: + ilist,olist,elist = select.select(rlist, [], [], 0.1) + except select.error, e: + Utils.log("failed to read from connections: %s" % str(e)) + break + for sock in ilist: + # handle new connection + if sock == serverSocket: + clientSocket, address = serverSocket.accept() + clientSocket.setblocking(0) + #print "connection from %s on %s" % (address, clientSocket) + rlist.append(clientSocket) + continue + + # handle all other sockets + data = sock.recv(Globals.DEFAULT_BUFSIZE) + if not data: + #print "closing socket %s" % sock + sock.close() + rlist.remove(sock) + tokens = data.strip().split(",") + if len(tokens) != 6: + continue + if not (tokens[0] == Globals.GLUSTER_PROBE_STRING and \ + tokens[1] == Globals.GLUSTER_PROBE_VERSION and \ + tokens[2] == idString): + continue + serverInfoDict[tokens[3]] = [tokens[4], tokens[5]] + #print "closing socket %s" % sock + sock.close() + rlist.remove(sock) + + for sock in rlist: + sock.close() + + for k, v in serverInfoDict.iteritems(): + if v[0]: + print v[0] + else: + print k + + sys.exit(0) + + +if __name__ == "__main__": + main() diff --git a/src/org.gluster.storage.management.gateway.scripts/src/gateway/remove_server_volume_cifs_config.py b/src/org.gluster.storage.management.gateway.scripts/src/gateway/remove_server_volume_cifs_config.py new file mode 100755 index 00000000..27fb9b92 --- /dev/null +++ b/src/org.gluster.storage.management.gateway.scripts/src/gateway/remove_server_volume_cifs_config.py @@ -0,0 +1,68 @@ +#!/usr/bin/python +# Copyright (C) 2011 Gluster, Inc. <http://www.gluster.com> +# This file is part of Gluster Management Gateway. +# + +import os +import sys +p1 = os.path.abspath(os.path.dirname(sys.argv[0])) +p2 = "%s/common" % os.path.dirname(p1) +if not p1 in sys.path: + sys.path.append(p1) +if not p2 in sys.path: + sys.path.append(p2) +import Globals +import Utils + + +def main(): + if len(sys.argv) < 3: + sys.stderr.write("usage: %s SERVER_NAME VOLUME_FILE\n" % os.path.basename(sys.argv[0])) + sys.exit(-1) + + serverName = sys.argv[1] + volumeFile = sys.argv[2] + + lines = Utils.readFile(volumeFile, lines=True) + volumeNameList = [line.strip() for line in lines] + if not volumeNameList: + sys.exit(0) + + lines = Utils.readFile(Globals.CIFS_VOLUME_FILE, lines=True) + cifsVolumeList = [line.strip().split(":")[0] for line in lines if line.strip()] + runningCifsVolumeList = set(cifsVolumeList).intersection(set(volumeNameList)) + + if not runningCifsVolumeList: + sys.exit(0) + + tempFileName = Utils.getTempFileName() + try: + fp = open(tempFileName, "w") + fp.write("%s\n" % serverName) + fp.close() + except IOError, e: + Utils.log("Failed to write server name to file %s: %s" % (tempFileName, str(e))) + sys.stderr.write("Failed to write server name to file %s: %s\n" % (tempFileName, str(e))) + sys.exit(3) + + status = True + for volumeName in runningCifsVolumeList: + if Utils.grun(tempFileName, "stop_volume_cifs.py", [volumeName.strip()]) != 0: + status = False + if Utils.grun(tempFileName, "delete_volume_cifs.py", [volumeName.strip()]) != 0: + status = False + + try: + os.remove(tempFileName) + except OSError, e: + Utils.log("Failed to remove temporary file %s: %s" % (tempFileName, str(e))) + sys.stderr.write("Failed to remove temporary file %s: %s\n" % (tempFileName, str(e))) + pass + + if status: + sys.exit(0) + else: + sys.exit(2) + +if __name__ == "__main__": + main() diff --git a/src/org.gluster.storage.management.gateway.scripts/src/gateway/setup_cifs_config_all.py b/src/org.gluster.storage.management.gateway.scripts/src/gateway/setup_cifs_config_all.py new file mode 100755 index 00000000..e7e0a4a0 --- /dev/null +++ b/src/org.gluster.storage.management.gateway.scripts/src/gateway/setup_cifs_config_all.py @@ -0,0 +1,29 @@ +#!/usr/bin/python +# Copyright (C) 2011 Gluster, Inc. <http://www.gluster.com> +# This file is part of Gluster Management Gateway. +# + +import os +import sys +p1 = os.path.abspath(os.path.dirname(sys.argv[0])) +p2 = "%s/common" % os.path.dirname(p1) +if not p1 in sys.path: + sys.path.append(p1) +if not p2 in sys.path: + sys.path.append(p2) +import Utils + + +def main(): + if len(sys.argv) < 2: + sys.stderr.write("usage: %s SERVER_FILE\n" % os.path.basename(sys.argv[0])) + sys.exit(-1) + + serverFile = sys.argv[1] + + rv = Utils.grun(serverFile, "setup_cifs_config.py") + sys.exit(rv) + + +if __name__ == "__main__": + main() diff --git a/src/org.gluster.storage.management.gateway.scripts/src/gateway/update_volume_cifs_all.py b/src/org.gluster.storage.management.gateway.scripts/src/gateway/update_volume_cifs_all.py new file mode 100755 index 00000000..e5576c45 --- /dev/null +++ b/src/org.gluster.storage.management.gateway.scripts/src/gateway/update_volume_cifs_all.py @@ -0,0 +1,63 @@ +#!/usr/bin/python +# Copyright (C) 2011 Gluster, Inc. <http://www.gluster.com> +# This file is part of Gluster Management Gateway. +# + +import os +import sys +p1 = os.path.abspath(os.path.dirname(sys.argv[0])) +p2 = "%s/common" % os.path.dirname(p1) +if not p1 in sys.path: + sys.path.append(p1) +if not p2 in sys.path: + sys.path.append(p2) +import Globals +import Utils + + +def updateVolumeCifsConf(volumeName, userList): + lines = Utils.readFile(Globals.CIFS_VOLUME_FILE, lines=True) + try: + fp = open(Globals.CIFS_VOLUME_FILE, "w") + for line in lines: + if not line.strip(): + continue + if line.strip().split(":")[0] == volumeName: + fp.write("%s:%s\n" % (volumeName, ":".join(userList))) + else: + fp.write("%s\n" % line.strip()) + fp.close() + except IOError, e: + Utils.log("failed to write file %s: %s" % (Globals.CIFS_VOLUME_FILE, str(e))) + return False + return True + + +def main(): + if len(sys.argv) < 4: + sys.stderr.write("usage: %s SERVER_FILE VOLUME_NAME USER1 USER2 ...\n" % os.path.basename(sys.argv[0])) + sys.exit(-1) + + serverFile = sys.argv[1] + volumeName = sys.argv[2] + userList = sys.argv[3:] + + missingUserList = [] + for userName in userList: + if not Utils.getCifsUserUid(userName): + missingUserList.append(userName) + + if missingUserList: + sys.stderr.write("User %s does not exists\n" % missingUserList) + sys.exit(1) + + rv = Utils.grun(serverFile, "update_volume_cifs.py", [volumeName] + userList) + if rv == 0: + if not updateVolumeCifsConf(volumeName, userList): + sys.stderr.write("Failed to update volume %s and user-list %s in cifs volume configuration\n" % (volumeName, userList)) + sys.exit(11) + sys.exit(rv) + + +if __name__ == "__main__": + main() |