diff options
| author | Shireesh Anjal <anjalshireesh@gmail.com> | 2011-07-07 09:00:09 -0700 |
|---|---|---|
| committer | Shireesh Anjal <anjalshireesh@gmail.com> | 2011-07-07 09:00:09 -0700 |
| commit | 3a0363633bacf93bf81eb8f3917ecea9d1adfc22 (patch) | |
| tree | 0138f6dcdb86aa24be982bd645601a264f9ff52c | |
| parent | 5e04ff19a21ed84aa59004bb8040e1a0d6734542 (diff) | |
| parent | 529525fe5dec5d9ead5aab6bd39029ea1a63762b (diff) | |
Merge pull request #103 from Dhandapani/master
VolumeOptions data model change
42 files changed, 1842 insertions, 395 deletions
diff --git a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/DiscoveredServersClient.java b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/DiscoveredServersClient.java index 3704e2ff..0d4ef85c 100644 --- a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/DiscoveredServersClient.java +++ b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/DiscoveredServersClient.java @@ -25,10 +25,12 @@ import java.util.List; import javax.ws.rs.core.MultivaluedMap; +import com.gluster.storage.management.core.model.GlusterServer; import com.gluster.storage.management.core.model.Server; import com.gluster.storage.management.core.response.GenericResponse; import com.gluster.storage.management.core.response.ServerListResponse; import com.gluster.storage.management.core.response.ServerNameListResponse; +import com.gluster.storage.management.core.utils.GlusterCoreUtil; import com.sun.jersey.core.util.MultivaluedMapImpl; public class DiscoveredServersClient extends AbstractClient { @@ -59,7 +61,13 @@ public class DiscoveredServersClient extends AbstractClient { } public List<Server> getDiscoveredServerDetails() { - return ((ServerListResponse) getDiscoveredServers(Boolean.TRUE, ServerListResponse.class)).getServers(); + List<Server> servers = ((ServerListResponse) getDiscoveredServers(Boolean.TRUE, ServerListResponse.class)) + .getServers(); + + for (Server server : servers) { + GlusterCoreUtil.updateServerNameOnDevices(server); + } + return servers; } public Server getServer(String serverName) { diff --git a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/GlusterDataModelManager.java b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/GlusterDataModelManager.java index 9ee4513c..6db98ed4 100644 --- a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/GlusterDataModelManager.java +++ b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/GlusterDataModelManager.java @@ -19,7 +19,6 @@ package com.gluster.storage.management.client; import java.util.ArrayList; -import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; @@ -31,8 +30,8 @@ import com.gluster.storage.management.core.exceptions.GlusterRuntimeException; import com.gluster.storage.management.core.model.Brick; import com.gluster.storage.management.core.model.Cluster; import com.gluster.storage.management.core.model.ClusterListener; +import com.gluster.storage.management.core.model.Device.DEVICE_STATUS; import com.gluster.storage.management.core.model.Disk; -import com.gluster.storage.management.core.model.Disk.DISK_STATUS; import com.gluster.storage.management.core.model.Event; import com.gluster.storage.management.core.model.Event.EVENT_TYPE; import com.gluster.storage.management.core.model.GlusterDataModel; @@ -605,10 +604,10 @@ public class GlusterDataModelManager { } } - public void setVolumeOption(Volume volume, Entry<String, String> entry) { - volume.setOption(entry.getKey(), (String) entry.getValue()); + public void setVolumeOption(Volume volume, String optionKey, String optionValue) { + volume.setOption(optionKey, optionValue); for (ClusterListener listener : listeners) { - listener.volumeChanged(volume, new Event(EVENT_TYPE.VOLUME_OPTION_SET, entry)); + listener.volumeChanged(volume, new Event(EVENT_TYPE.VOLUME_OPTION_SET, optionKey)); } } @@ -673,8 +672,7 @@ public class GlusterDataModelManager { } public void setAccessControlList(Volume volume, String accessControlList) { - volume.setAccessControlList(accessControlList); - setVolumeOption(volume, getOptionEntry(volume, Volume.OPTION_AUTH_ALLOW)); + setVolumeOption(volume, Volume.OPTION_AUTH_ALLOW, accessControlList); } public Server getGlusterServer(String serverName) { @@ -686,17 +684,6 @@ public class GlusterDataModelManager { return null; } - @SuppressWarnings({ "rawtypes", "unchecked" }) - private Entry<String, String> getOptionEntry(Volume volume, String optionKey) { - for (Entry entry : volume.getOptions().entrySet()) { - if (entry.getKey().equals(optionKey)) { - return entry; - } - } - throw new GlusterRuntimeException("Couldn't find entry for option [" + optionKey + "] on volume [" - + volume.getName()); - } - private Boolean isDiskUsed(Volume volume, Disk disk) { for (Brick brick : volume.getBricks()) { if (disk.getName().equals(brick.getDiskName()) && disk.getServerName().equals(brick.getServerName())) { @@ -707,7 +694,7 @@ public class GlusterDataModelManager { } public String getDiskStatus(Disk disk) { - if (disk.getStatus() == DISK_STATUS.AVAILABLE) { + if (disk.getStatus() == DEVICE_STATUS.INITIALIZED) { for (Volume volume : model.getCluster().getVolumes()) { if (isDiskUsed(volume, disk)) { return "In use"; diff --git a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/GlusterServersClient.java b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/GlusterServersClient.java index 865ec5f2..0abccda5 100644 --- a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/GlusterServersClient.java +++ b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/GlusterServersClient.java @@ -28,6 +28,7 @@ import com.gluster.storage.management.core.constants.RESTConstants; import com.gluster.storage.management.core.model.GlusterServer; import com.gluster.storage.management.core.model.Server; import com.gluster.storage.management.core.response.GlusterServerListResponse; +import com.gluster.storage.management.core.utils.GlusterCoreUtil; import com.sun.jersey.api.representation.Form; public class GlusterServersClient extends AbstractClient { @@ -50,11 +51,17 @@ public class GlusterServersClient extends AbstractClient { } public List<GlusterServer> getServers() { - return ((GlusterServerListResponse) fetchResource(GlusterServerListResponse.class)).getServers(); + List<GlusterServer> servers = ((GlusterServerListResponse) fetchResource(GlusterServerListResponse.class)).getServers(); + for(GlusterServer server : servers) { + GlusterCoreUtil.updateServerNameOnDevices(server); + } + return servers; } public GlusterServer getGlusterServer(String serverName) { - return (GlusterServer) fetchSubResource(serverName, GlusterServer.class); + GlusterServer server = (GlusterServer) fetchSubResource(serverName, GlusterServer.class); + GlusterCoreUtil.updateServerNameOnDevices(server); + return server; } public void addServer(Server discoveredServer) { diff --git a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Device.java b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Device.java new file mode 100644 index 00000000..063cdd18 --- /dev/null +++ b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Device.java @@ -0,0 +1,201 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + *******************************************************************************/ +package com.gluster.storage.management.core.model; + +import java.io.File; +import java.nio.channels.GatheringByteChannel; + +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlTransient; + +import com.gluster.storage.management.core.utils.StringUtil; + + +/** + * + */ +public class Device extends Entity { + public enum DEVICE_STATUS { + //TODO: Status "READY" to be removed after python script is changed accordingly + READY, INITIALIZED, UNINITIALIZED, INITIALIZING, IO_ERROR, UNKNOWN + }; + + public enum DEVICE_TYPE { + DATA, BOOT, SWAP, UNKNOWN + }; + + private static final String[] DEVICE_STATUS_STR = { "Ready", "Initialized", "Uninitialized", "Initializing", "I/O Error", "Unknown" }; + private static final String[] DEVICE_TYPE_STR = { "Data", "Boot", "Swap", "Unknown" }; + + // type = data, boot, other + private DEVICE_TYPE type; + + private String fsType; + private String fsVersion; + + private String serverName; + private String mountPoint; + + private Double space; + private Double spaceInUse; + private DEVICE_STATUS status; + + public Device() { + } + + public Device(Server server, String name, String mountPoint, Double space, Double spaceInUse, DEVICE_STATUS status) { + super(name, server); + setServerName(server != null ? server.getName() : ""); + setMountPoint(mountPoint); + setSpace(space); + setSpaceInUse(spaceInUse); + setStatus(status); + } + + @XmlElement(name="size") + public Double getSpace() { + return space; + } + + public Double getFreeSpace() { + return getSpace() - getSpaceInUse(); + } + + public void setSpace(Double space) { + this.space = space; + } + + public boolean isUninitialized() { + return getStatus() == DEVICE_STATUS.UNINITIALIZED; + } + + public boolean hasErrors() { + return getStatus() == DEVICE_STATUS.IO_ERROR; + } + + public boolean isReady() { + // TODO: Check if status is INITIALIZED AND type = DATA + // return (getStatus() == DEVICE_STATUS.INITIALIZED && getType() == DEVICE_TYPE.DATA); + return (getStatus() == DEVICE_STATUS.READY); + } + + public DEVICE_STATUS getStatus() { + return status; + } + + public String getStatusStr() { + if (getStatus() == null) { + return DEVICE_STATUS_STR[DEVICE_STATUS.UNKNOWN.ordinal()]; // Return as Unknown + } + + if(isReady()) { + return "Available"; + } + return DEVICE_STATUS_STR[getStatus().ordinal()]; + } + + public void setStatus(DEVICE_STATUS status) { + this.status = status; + } + + public Double getSpaceInUse() { + return spaceInUse; + } + + public void setSpaceInUse(Double spaceInUse) { + this.spaceInUse = spaceInUse; + } + + @XmlTransient + public String getServerName() { + return serverName; + } + + public void setServerName(String serverName) { + this.serverName = serverName; + } + + public void setMountPoint(String mountPoint) { + this.mountPoint = mountPoint; + } + + public String getMountPoint() { + return mountPoint; + } + + public DEVICE_TYPE getType() { + return type; + } + + public String getTypeStr() { + return DEVICE_TYPE_STR[type.ordinal()]; + } + + public void setType(DEVICE_TYPE diskType) { + this.type = diskType; + } + + public String getFsType() { + return fsType; + } + + public void setFsType(String fsType) { + this.fsType = fsType; + } + + public String getFsVersion() { + return fsVersion; + } + + public void setFsVersion(String fsVersion) { + this.fsVersion = fsVersion; + } + + @Override + public boolean filter(String filterString, boolean caseSensitive) { + return StringUtil.filterString(getServerName() + getName() + getStatusStr() + getSpace() + getFreeSpace() + + getType(), filterString, caseSensitive); + } + + public String getQualifiedName() { + return getServerName() + ":" + getName(); + } + + public String getQualifiedBrickName(String volumeName) { + return getServerName() + ":" + getMountPoint() + File.separator + volumeName; + } + + @Override + public boolean equals(Object obj) { + if(!(obj instanceof Device)) { + return false; + } + + Device disk = (Device)obj; + + if (getName().equals(disk.getName()) && getServerName().equals(disk.getServerName()) + && getMountPoint().equals(disk.getMountPoint()) && getStatus() == disk.getStatus() + && getSpace() == disk.getSpace() && getSpaceInUse() == disk.getSpaceInUse() + && getFsType().equals(disk.getFsType()) && getFsVersion().equals(disk.getFsVersion())) { + return true; + } + + return false; + } +} diff --git a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Disk.java b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Disk.java index ecc3a278..32341eca 100644 --- a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Disk.java +++ b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Disk.java @@ -18,119 +18,70 @@ *******************************************************************************/ package com.gluster.storage.management.core.model; -import java.io.File; +import java.util.Collection; +import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; +import com.gluster.storage.management.core.utils.GlusterCoreUtil; import com.gluster.storage.management.core.utils.StringUtil; -@XmlRootElement(name="Disk") -public class Disk extends Entity { - public enum DISK_STATUS { - AVAILABLE, UNINITIALIZED, INITIALIZING, IO_ERROR - }; - - private String[] DISK_STATUS_STR = { "Available", "Uninitialized", "Initializing", "I/O Error" }; - - private String serverName; - private String mountPoint; +@XmlRootElement(name="disk") +public class Disk extends Device { private String description; - private Double space; - private Double spaceInUse; - private DISK_STATUS status; - - public Disk() { - - } - - public Double getSpace() { - return space; - } - - public Double getFreeSpace() { - return getSpace() - getSpaceInUse(); - } - - public void setSpace(Double space) { - this.space = space; - } - public boolean isUninitialized() { - return getStatus() == DISK_STATUS.UNINITIALIZED; - } + // interface = pci, raid0, raid3, etc + private String diskInterface; - public boolean hasErrors() { - return getStatus() == DISK_STATUS.IO_ERROR; - } + private Collection<Partition> partitions; - public boolean isReady() { - return getStatus() == DISK_STATUS.AVAILABLE; - } - - public DISK_STATUS getStatus() { - return status; - } - - public String getStatusStr() { - return DISK_STATUS_STR[getStatus().ordinal()]; - } + // In case of a software raid, the disk will contain an array of other disks + private Collection<Disk> raidDisks; - public void setStatus(DISK_STATUS status) { - this.status = status; + public Disk() { } - public Double getSpaceInUse() { - return spaceInUse; + public void setDescription(String description) { + this.description = description; } - public void setSpaceInUse(Double spaceInUse) { - this.spaceInUse = spaceInUse; + public String getDescription() { + return description; } - public String getServerName() { - return serverName; + @XmlElement(name="interface") + public String getDiskInterface() { + return diskInterface; } - public void setServerName(String serverName) { - this.serverName = serverName; + public void setDiskInterface(String diskInterface) { + this.diskInterface = diskInterface; } - public void setMountPoint(String mountPoint) { - this.mountPoint = mountPoint; + public Collection<Disk> getRaidDisks() { + return raidDisks; } - public String getMountPoint() { - return mountPoint; + public void setRaidDisks(Collection<Disk> raidDisks) { + this.raidDisks = raidDisks; } - public void setDescription(String description) { - this.description = description; + public void setPartitions(Collection<Partition> partitions) { + this.partitions = partitions; } - public String getDescription() { - return description; + public Collection<Partition> getPartitions() { + return partitions; } - public Disk(Server server, String name, String mountPoint, Double space, Double spaceInUse, DISK_STATUS status) { - super(name, server); - setServerName(server != null ? server.getName() : ""); - setMountPoint(mountPoint); - setSpace(space); - setSpaceInUse(spaceInUse); - setStatus(status); + public Disk(Server server, String name, String mountPoint, Double space, Double spaceInUse, DEVICE_STATUS status) { + super(server, name, mountPoint, space, spaceInUse, status); } @Override public boolean filter(String filterString, boolean caseSensitive) { - return StringUtil.filterString(getServerName() + getName() + getStatusStr(), filterString, caseSensitive); - } - - public String getQualifiedName() { - return getServerName() + ":" + getName(); - } - - public String getQualifiedBrickName(String volumeName) { - return getServerName() + ":" + getMountPoint() + File.separator + volumeName; + return StringUtil.filterString(getServerName() + getName() + getStatusStr() + getSpace() + getFreeSpace() + + getType() + getDescription(), filterString, caseSensitive); } @Override @@ -140,13 +91,29 @@ public class Disk extends Entity { } Disk disk = (Disk)obj; - if (getName().equals(disk.getName()) && getServerName().equals(disk.getServerName()) - && getMountPoint().equals(disk.getMountPoint()) && getDescription().equals(disk.getDescription()) - && getStatus() == disk.getStatus() && getSpace() == disk.getSpace() - && getSpaceInUse() == disk.getSpaceInUse()) { - return true; + if (!(super.equals(obj) && getDescription().equals(disk.getDescription()) && getDiskInterface().equals( + disk.getDiskInterface()))) { + return false; + } + + if (raidDisks != null) { + for (Disk raidDisk : raidDisks) { + // check if the disk contains same raid disks + if (!(raidDisk.equals(GlusterCoreUtil.getEntity(disk.getRaidDisks(), raidDisk.getName(), false)))) { + return false; + } + } } +// // check if the disk contains same partitions +// if (partitions != null) { +// for (Partition partition : partitions) { +// if (!(partition.equals(GlusterCoreUtil.getEntity(disk.getPartitions(), partition.getName(), false)))) { +// return false; +// } +// } +// } + return false; } diff --git a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/GlusterDummyModel.java b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/GlusterDummyModel.java index f2ccc5db..22681919 100644 --- a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/GlusterDummyModel.java +++ b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/GlusterDummyModel.java @@ -23,7 +23,7 @@ import java.util.Arrays; import java.util.Date; import java.util.List; -import com.gluster.storage.management.core.model.Disk.DISK_STATUS; +import com.gluster.storage.management.core.model.Device.DEVICE_STATUS; import com.gluster.storage.management.core.model.GlusterServer.SERVER_STATUS; import com.gluster.storage.management.core.model.Volume.TRANSPORT_TYPE; import com.gluster.storage.management.core.model.Volume.VOLUME_STATUS; @@ -72,7 +72,7 @@ public class GlusterDummyModel { private void addDiscoveredServer(List<Server> servers, Entity parent, String name, int numOfCPUs, double cpuUsage, double totalMemory, double memoryInUse, double totalDiskSpace, double diskSpaceInUse) { Server server = new Server(name, parent, numOfCPUs, cpuUsage, totalMemory, memoryInUse); - server.addDisk(new Disk(server, "sda", "/export/md0", totalDiskSpace, diskSpaceInUse, DISK_STATUS.AVAILABLE)); + server.addDisk(new Disk(server, "sda", "/export/md0", totalDiskSpace, diskSpaceInUse, DEVICE_STATUS.INITIALIZED)); addNetworkInterface(server, "eth0"); servers.add(server); @@ -138,18 +138,18 @@ public class GlusterDummyModel { } private void initializeDisks() { - s1da = new Disk(server1, "sda", "/export/md0", 100d, 80d, DISK_STATUS.AVAILABLE); - s1db = new Disk(server1, "sdb", "/export/md1", 100d, 67.83, DISK_STATUS.AVAILABLE); + s1da = new Disk(server1, "sda", "/export/md0", 100d, 80d, DEVICE_STATUS.INITIALIZED); + s1db = new Disk(server1, "sdb", "/export/md1", 100d, 67.83, DEVICE_STATUS.INITIALIZED); - s2da = new Disk(server2, "sda", "/export/md0", 200d, 157.12, DISK_STATUS.AVAILABLE); - s2db = new Disk(server2, "sdb", "/export/md1", 200d, 182.27, DISK_STATUS.AVAILABLE); - s2dc = new Disk(server2, "sdc", "/export/md0", 200d, -1d, DISK_STATUS.UNINITIALIZED); - s2dd = new Disk(server2, "sdd", "/export/md1", 200d, 124.89, DISK_STATUS.AVAILABLE); + s2da = new Disk(server2, "sda", "/export/md0", 200d, 157.12, DEVICE_STATUS.INITIALIZED); + s2db = new Disk(server2, "sdb", "/export/md1", 200d, 182.27, DEVICE_STATUS.INITIALIZED); + s2dc = new Disk(server2, "sdc", "/export/md0", 200d, -1d, DEVICE_STATUS.UNINITIALIZED); + s2dd = new Disk(server2, "sdd", "/export/md1", 200d, 124.89, DEVICE_STATUS.INITIALIZED); - s4da = new Disk(server4, "sda", "/export/md0", 100d, 85.39, DISK_STATUS.AVAILABLE); + s4da = new Disk(server4, "sda", "/export/md0", 100d, 85.39, DEVICE_STATUS.INITIALIZED); - s5da = new Disk(server5, "sda", "/export/md1", 100d, 92.83, DISK_STATUS.AVAILABLE); - s5db = new Disk(server5, "sdb", "/export/md1", 200d, 185.69, DISK_STATUS.AVAILABLE); + s5da = new Disk(server5, "sda", "/export/md1", 100d, 92.83, DEVICE_STATUS.INITIALIZED); + s5db = new Disk(server5, "sdb", "/export/md1", 200d, 185.69, DEVICE_STATUS.INITIALIZED); } private void addDisksToServers() { diff --git a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Partition.java b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Partition.java new file mode 100644 index 00000000..a06b1e1c --- /dev/null +++ b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Partition.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + *******************************************************************************/ +package com.gluster.storage.management.core.model; + +/** + * + */ +public class Partition extends Device { + +} diff --git a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Volume.java b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Volume.java index 006202fb..fe05c517 100644 --- a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Volume.java +++ b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Volume.java @@ -24,6 +24,7 @@ import java.util.Collection; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; +import java.util.Map.Entry; import java.util.Set; import javax.xml.bind.annotation.XmlElement; @@ -196,7 +197,11 @@ public class Volume extends Entity { } public void setOptions(LinkedHashMap<String, String> options) { - this.options.setOptionsMap(options); + List<VolumeOption> volumeOptions = new ArrayList<VolumeOption>(); + for(Entry<String, String> entry : options.entrySet()) { + volumeOptions.add(new VolumeOption(entry.getKey(), entry.getValue())); + } + this.options.setOptions(volumeOptions); } public void addBrick(Brick brick) { diff --git a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/VolumeOption.java b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/VolumeOption.java index f4ca3e81..4b54b010 100644 --- a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/VolumeOption.java +++ b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/VolumeOption.java @@ -23,7 +23,7 @@ import javax.xml.bind.annotation.XmlRootElement; /** * */ -@XmlRootElement +@XmlRootElement(name="option") public class VolumeOption { private String key; private String value; diff --git a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/VolumeOptions.java b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/VolumeOptions.java index f928c241..bda01075 100644 --- a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/VolumeOptions.java +++ b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/VolumeOptions.java @@ -27,64 +27,54 @@ import java.util.Set; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlTransient; /** * */ -@XmlRootElement +@XmlRootElement(name="options") public class VolumeOptions { - private Map<String, String> optionsMap = new HashMap<String, String>(); + private List<VolumeOption> options = new ArrayList<VolumeOption>(); public VolumeOptions() { } public String get(String key) { - return optionsMap.get(key); + for(VolumeOption option : options) { + if(option.getKey().equals(key)) { + return option.getValue(); + } + } + return null; } - public String put(String key, String value) { - return optionsMap.put(key, value); + public void put(String key, String value) { + options.add(new VolumeOption(key, value)); } @XmlElement(name="option", type=VolumeOption.class) public List<VolumeOption> getOptions() { - List<VolumeOption> options = new ArrayList<VolumeOption>(); - for(Entry<String, String> entry : optionsMap.entrySet()) { - options.add(new VolumeOption(entry.getKey(), entry.getValue())); - } return options; } - public Set<Entry<String, String>> getOptionsMap() { - return optionsMap.entrySet(); - } - - public void setOptionsMap(Map<String, String> optionsMap) { - this.optionsMap = optionsMap; + public void setOptions(List<VolumeOption> options) { + this.options = options; } public void clear() { - optionsMap.clear(); + options.clear(); } - public Set<Entry<String, String>> entrySet() { - return optionsMap.entrySet(); - } - - public Set<String> keySet() { - return optionsMap.keySet(); - } - - public String remove(String key) { - return optionsMap.remove(key); + public boolean remove(String key) { + return options.remove(get(key)); } public int size() { - return optionsMap.size(); + return options.size(); } public boolean containsKey(String key) { - return optionsMap.containsKey(key); + return get(key) != null; } @Override @@ -108,8 +98,7 @@ public class VolumeOptions { } public void copyFrom(VolumeOptions options) { - for(Entry<String, String> entry : options.entrySet()) { - optionsMap.put(entry.getKey(), entry.getValue()); - } + this.options.clear(); + this.options.addAll(options.getOptions()); } }
\ No newline at end of file diff --git a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/utils/GlusterCoreUtil.java b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/utils/GlusterCoreUtil.java index 838612be..7b1eec36 100644 --- a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/utils/GlusterCoreUtil.java +++ b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/utils/GlusterCoreUtil.java @@ -21,6 +21,7 @@ package com.gluster.storage.management.core.utils; import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -30,6 +31,8 @@ import java.util.Set; import com.gluster.storage.management.core.model.Brick; import com.gluster.storage.management.core.model.Disk; import com.gluster.storage.management.core.model.Entity; +import com.gluster.storage.management.core.model.Partition; +import com.gluster.storage.management.core.model.Server; public class GlusterCoreUtil { @@ -95,7 +98,7 @@ public class GlusterCoreUtil { return getEntity(entityList, searchEntity.getName(), caseInsensitive) != null; } - public static <T extends Entity> T getEntity(List<T> entityList, String searchEntityName, boolean caseInsensitive) { + public static <T extends Entity> T getEntity(Collection<T> entityList, String searchEntityName, boolean caseInsensitive) { if (caseInsensitive) { searchEntityName = searchEntityName.toUpperCase(); } @@ -112,4 +115,24 @@ public class GlusterCoreUtil { return null; } + + public static void updateServerNameOnDevices(Server server) { + String serverName = server.getName(); + for(Disk disk : server.getDisks()) { + disk.setServerName(serverName); + + if (disk.getRaidDisks() != null) { + for (Disk raidDisk : disk.getRaidDisks()) { + raidDisk.setServerName(serverName); + } + } + + if (disk.getPartitions() != null) { + for (Partition partition : disk.getPartitions()) { + partition.setServerName(serverName); + } + } + } + // TODO: do the same for raid disks and/or partitions whenever we start supporting them + } } diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/BrickTableLabelProvider.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/BrickTableLabelProvider.java index 763dac2a..7d2b1b7b 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/BrickTableLabelProvider.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/BrickTableLabelProvider.java @@ -23,8 +23,8 @@ import org.eclipse.swt.graphics.Image; import com.gluster.storage.management.client.GlusterDataModelManager; import com.gluster.storage.management.core.exceptions.GlusterRuntimeException; import com.gluster.storage.management.core.model.Brick; +import com.gluster.storage.management.core.model.Device.DEVICE_STATUS; import com.gluster.storage.management.core.model.Disk; -import com.gluster.storage.management.core.model.Disk.DISK_STATUS; import com.gluster.storage.management.core.utils.NumberUtil; import com.gluster.storage.management.gui.utils.GUIHelper; import com.gluster.storage.management.gui.views.pages.BricksPage.BRICK_TABLE_COLUMN_INDICES; @@ -44,9 +44,10 @@ public class BrickTableLabelProvider extends TableLabelProviderAdapter { Disk disk = GlusterDataModelManager.getInstance().getDiskDetails(brick.getDiskName()); if (columnIndex == DISK_TABLE_COLUMN_INDICES.STATUS.ordinal()) { - DISK_STATUS status = disk.getStatus(); + DEVICE_STATUS status = disk.getStatus(); switch (status) { - case AVAILABLE: + case INITIALIZED: + case READY: return guiHelper.getImage(IImageKeys.STATUS_ONLINE); case IO_ERROR: return guiHelper.getImage(IImageKeys.STATUS_OFFLINE); @@ -63,7 +64,7 @@ public class BrickTableLabelProvider extends TableLabelProviderAdapter { } private String getDiskFreeSpace(Disk disk) { - if (disk.isReady() && disk.getFreeSpace() != null) { + if (disk != null && disk.isReady() && disk.getFreeSpace() != null) { return NumberUtil.formatNumber((disk.getFreeSpace() / 1024)); } else { return "NA"; diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/DiskTableLabelProvider.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/DiskTableLabelProvider.java index d2f265b5..e0f11a85 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/DiskTableLabelProvider.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/DiskTableLabelProvider.java @@ -22,8 +22,8 @@ import org.eclipse.swt.graphics.Image; import com.gluster.storage.management.client.GlusterDataModelManager; import com.gluster.storage.management.core.exceptions.GlusterRuntimeException; +import com.gluster.storage.management.core.model.Device.DEVICE_STATUS; import com.gluster.storage.management.core.model.Disk; -import com.gluster.storage.management.core.model.Disk.DISK_STATUS; import com.gluster.storage.management.core.utils.NumberUtil; import com.gluster.storage.management.gui.utils.GUIHelper; import com.gluster.storage.management.gui.views.pages.DisksPage.DISK_TABLE_COLUMN_INDICES; @@ -44,9 +44,10 @@ public class DiskTableLabelProvider extends TableLabelProviderAdapter { Disk disk = (Disk) element; if (columnIndex == DISK_TABLE_COLUMN_INDICES.STATUS.ordinal()) { - DISK_STATUS status = disk.getStatus(); + DEVICE_STATUS status = disk.getStatus(); switch (status) { - case AVAILABLE: + case INITIALIZED: + case READY: return guiHelper.getImage(IImageKeys.STATUS_ONLINE); case IO_ERROR: return guiHelper.getImage(IImageKeys.STATUS_OFFLINE); diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/ServerDiskTableLabelProvider.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/ServerDiskTableLabelProvider.java index f0e65edc..d6564610 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/ServerDiskTableLabelProvider.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/ServerDiskTableLabelProvider.java @@ -23,8 +23,8 @@ import org.eclipse.swt.graphics.Image; import com.gluster.storage.management.client.GlusterDataModelManager; import com.gluster.storage.management.core.constants.CoreConstants; import com.gluster.storage.management.core.exceptions.GlusterRuntimeException; +import com.gluster.storage.management.core.model.Device.DEVICE_STATUS; import com.gluster.storage.management.core.model.Disk; -import com.gluster.storage.management.core.model.Disk.DISK_STATUS; import com.gluster.storage.management.core.utils.NumberUtil; import com.gluster.storage.management.gui.utils.GUIHelper; import com.gluster.storage.management.gui.views.pages.ServerDisksPage.SERVER_DISK_TABLE_COLUMN_INDICES; @@ -41,9 +41,14 @@ public class ServerDiskTableLabelProvider extends TableLabelProviderAdapter { Disk disk = (Disk) element; if (columnIndex == SERVER_DISK_TABLE_COLUMN_INDICES.STATUS.ordinal()) { - DISK_STATUS status = disk.getStatus(); + DEVICE_STATUS status = disk.getStatus(); + + if (status == null) { + return null; + } + switch (status) { - case AVAILABLE: + case INITIALIZED: return guiHelper.getImage(IImageKeys.STATUS_ONLINE); case IO_ERROR: return guiHelper.getImage(IImageKeys.STATUS_OFFLINE); diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/VolumeOptionsTableLabelProvider.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/VolumeOptionsTableLabelProvider.java index cd85d22b..53c8c472 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/VolumeOptionsTableLabelProvider.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/VolumeOptionsTableLabelProvider.java @@ -20,6 +20,7 @@ package com.gluster.storage.management.gui; import java.util.Map.Entry; +import com.gluster.storage.management.core.model.VolumeOption; import com.gluster.storage.management.gui.views.pages.VolumeOptionsPage.OPTIONS_TABLE_COLUMN_INDICES; public class VolumeOptionsTableLabelProvider extends TableLabelProviderAdapter { @@ -29,11 +30,9 @@ public class VolumeOptionsTableLabelProvider extends TableLabelProviderAdapter { return null; } - Entry<String, String> entry = (Entry<String, String>) element; - String key = entry.getKey(); - String value = entry.getValue(); - return (columnIndex == OPTIONS_TABLE_COLUMN_INDICES.OPTION_KEY.ordinal() ? key - : columnIndex == OPTIONS_TABLE_COLUMN_INDICES.OPTION_VALUE.ordinal() ? value + VolumeOption option = (VolumeOption)element; + return (columnIndex == OPTIONS_TABLE_COLUMN_INDICES.OPTION_KEY.ordinal() ? option.getKey() + : columnIndex == OPTIONS_TABLE_COLUMN_INDICES.OPTION_VALUE.ordinal() ? option.getValue() : "Invalid"); } } diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/jobs/InitializeDiskJob.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/jobs/InitializeDiskJob.java index 02a8b0e0..76659885 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/jobs/InitializeDiskJob.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/jobs/InitializeDiskJob.java @@ -25,8 +25,8 @@ import org.eclipse.core.runtime.jobs.Job; import org.eclipse.ui.progress.IProgressConstants; import org.eclipse.ui.progress.IProgressConstants2; +import com.gluster.storage.management.core.model.Device.DEVICE_STATUS; import com.gluster.storage.management.core.model.Disk; -import com.gluster.storage.management.core.model.Disk.DISK_STATUS; import com.gluster.storage.management.gui.Application; import com.gluster.storage.management.gui.IImageKeys; import com.gluster.storage.management.gui.utils.GUIHelper; @@ -44,7 +44,7 @@ public class InitializeDiskJob extends Job { setProperty(IProgressConstants.ICON_PROPERTY, guiHelper.getImageDescriptor(IImageKeys.WORK_IN_PROGRESS)); } - private void updateStatus(final DISK_STATUS status) { + private void updateStatus(final DEVICE_STATUS status) { disk.setStatus(status); disk.setSpaceInUse(0d); app.entityChanged(disk, new String[] { "status", "spaceInUse" }); @@ -76,7 +76,7 @@ public class InitializeDiskJob extends Job { e.printStackTrace(); } - updateStatus(DISK_STATUS.AVAILABLE); + updateStatus(DEVICE_STATUS.INITIALIZED); setProperty(IProgressConstants.ICON_PROPERTY, guiHelper.getImageDescriptor(IImageKeys.STATUS_SUCCESS)); return new Status(Status.OK, Application.PLUGIN_ID, "Task Completed!"); diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/ClusterSummaryView.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/ClusterSummaryView.java index ef14c197..32aeb0cb 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/ClusterSummaryView.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/ClusterSummaryView.java @@ -40,8 +40,8 @@ import org.eclipse.ui.part.ViewPart; import com.gluster.storage.management.client.GlusterDataModelManager; import com.gluster.storage.management.core.model.Alert; import com.gluster.storage.management.core.model.Cluster; +import com.gluster.storage.management.core.model.Device.DEVICE_STATUS; import com.gluster.storage.management.core.model.Disk; -import com.gluster.storage.management.core.model.Disk.DISK_STATUS; import com.gluster.storage.management.core.model.EntityGroup; import com.gluster.storage.management.core.model.GlusterDataModel; import com.gluster.storage.management.core.model.GlusterServer; @@ -138,7 +138,7 @@ public class ClusterSummaryView extends ViewPart { createDiskSpaceChart(toolkit, section, values); } - private int getDiskCountByStatus(Cluster cluster, DISK_STATUS status) { + private int getDiskCountByStatus(Cluster cluster, DEVICE_STATUS status) { int diskCount = 0; for(GlusterServer server : cluster.getServers()) { for(Disk disk : server.getDisks()) { diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/AbstractDisksPage.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/AbstractDisksPage.java index cc12415e..d58394e2 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/AbstractDisksPage.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/AbstractDisksPage.java @@ -46,8 +46,8 @@ import com.gluster.storage.management.client.GlusterServersClient; import com.gluster.storage.management.client.TasksClient; import com.gluster.storage.management.core.model.ClusterListener; import com.gluster.storage.management.core.model.DefaultClusterListener; +import com.gluster.storage.management.core.model.Device.DEVICE_STATUS; import com.gluster.storage.management.core.model.Disk; -import com.gluster.storage.management.core.model.Disk.DISK_STATUS; import com.gluster.storage.management.core.model.Entity; import com.gluster.storage.management.core.model.TaskInfo; import com.gluster.storage.management.gui.Application; @@ -193,7 +193,7 @@ public abstract class AbstractDisksPage extends AbstractTableViewerPage<Disk> im this.myLink = link; } - private void updateStatus(final DISK_STATUS status, final boolean disposeEditor) { + private void updateStatus(final DEVICE_STATUS status, final boolean disposeEditor) { if (disposeEditor) { myLink.dispose(); myEditor.dispose(); @@ -221,7 +221,7 @@ public abstract class AbstractDisksPage extends AbstractTableViewerPage<Disk> im if (taskInfo != null && taskInfo instanceof TaskInfo) { GlusterDataModelManager.getInstance().getModel().getCluster().addTaskInfo(taskInfo); } - updateStatus(DISK_STATUS.INITIALIZING, true); + updateStatus(DEVICE_STATUS.INITIALIZING, true); } catch (Exception e1) { MessageDialog.openError(getShell(), "Error: Initialize disk", e1.getMessage()); } diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/OptionKeyEditingSupport.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/OptionKeyEditingSupport.java index 1f64d82e..924c5cc8 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/OptionKeyEditingSupport.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/OptionKeyEditingSupport.java @@ -4,7 +4,6 @@ package com.gluster.storage.management.gui.views.pages; import java.util.ArrayList; -import java.util.Iterator; import java.util.List; import java.util.Map.Entry; @@ -17,6 +16,7 @@ import org.eclipse.swt.widgets.Composite; import com.gluster.storage.management.client.GlusterDataModelManager; import com.gluster.storage.management.core.model.Volume; +import com.gluster.storage.management.core.model.VolumeOption; import com.gluster.storage.management.core.model.VolumeOptionInfo; import com.gluster.storage.management.core.model.VolumeOptions; @@ -73,7 +73,7 @@ public class OptionKeyEditingSupport extends EditingSupport { @Override protected Object getValue(Object element) { - Entry<String, String> entryBeingAdded = getEntryBeingAdded(); + VolumeOption entryBeingAdded = getEntryBeingAdded(); if(entryBeingAdded == null) { return cellEditor.getValue(); } @@ -93,7 +93,7 @@ public class OptionKeyEditingSupport extends EditingSupport { return cellEditor; } - private int getIndexOfEntry(Entry<String, String> entryBeingAdded) { + private int getIndexOfEntry(VolumeOption entryBeingAdded) { for(int index = 0; index < allowedKeys.length; index++) { if(allowedKeys[index].equals(entryBeingAdded.getKey())) { return index; @@ -102,18 +102,16 @@ public class OptionKeyEditingSupport extends EditingSupport { return -1; } - protected Entry<String, String> getEntryBeingAdded() { - Entry<String, String> entryBeingAdded = null; - Iterator<Entry<String, String>> iter = volume.getOptions().entrySet().iterator(); - while(iter.hasNext()) { - Entry<String, String> nextEntry = iter.next(); - if(!iter.hasNext() && nextEntry.getValue().isEmpty()) { - // it's the LAST entry, and it's value is empty. - // means this is a new row being added in the table viewer. - entryBeingAdded = nextEntry; - } + protected VolumeOption getEntryBeingAdded() { + List<VolumeOption> options = volume.getOptions().getOptions(); + int size = options.size(); + String lastValue = options.get(size - 1).getValue(); + if(lastValue == null || lastValue.isEmpty()) { + // it's the LAST entry, and it's value is empty. + // means this is a new row being added in the table viewer. + return options.get(size - 1); } - return entryBeingAdded; + return null; } @SuppressWarnings("unchecked") diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/OptionValueEditingSupport.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/OptionValueEditingSupport.java index 2358aa73..b349ab78 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/OptionValueEditingSupport.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/OptionValueEditingSupport.java @@ -18,6 +18,7 @@ import org.eclipse.swt.widgets.Display; import com.gluster.storage.management.client.GlusterDataModelManager; import com.gluster.storage.management.client.VolumesClient; import com.gluster.storage.management.core.model.Volume; +import com.gluster.storage.management.core.model.VolumeOption; import com.gluster.storage.management.core.model.VolumeOptionInfo; import com.gluster.storage.management.gui.utils.GUIHelper; @@ -39,7 +40,7 @@ public class OptionValueEditingSupport extends EditingSupport { @SuppressWarnings("unchecked") @Override protected void setValue(final Object element, final Object value) { - final Entry<String, String> entry = (Entry<String, String>) element; + final VolumeOption entry = (VolumeOption)element; final String optionKey = entry.getKey(); final String optionValue = (String)value; final String oldValue = entry.getValue(); @@ -67,9 +68,9 @@ public class OptionValueEditingSupport extends EditingSupport { public void run() { VolumesClient client = new VolumesClient(); try { - client.setVolumeOption(volume.getName(), entry.getKey(), (String) value); + client.setVolumeOption(volume.getName(), optionKey, optionValue); entry.setValue((String)value); - GlusterDataModelManager.getInstance().setVolumeOption(volume, entry); + GlusterDataModelManager.getInstance().setVolumeOption(volume, optionKey, optionValue); } catch(Exception e) { MessageDialog.openError(Display.getDefault().getActiveShell(), "Set Volume Option", e.getMessage()); } diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/VolumeOptionsPage.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/VolumeOptionsPage.java index 956fc215..b131999b 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/VolumeOptionsPage.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/VolumeOptionsPage.java @@ -58,6 +58,7 @@ import com.gluster.storage.management.core.model.DefaultClusterListener; import com.gluster.storage.management.core.model.Event; import com.gluster.storage.management.core.model.Event.EVENT_TYPE; import com.gluster.storage.management.core.model.Volume; +import com.gluster.storage.management.core.model.VolumeOption; import com.gluster.storage.management.core.model.VolumeOptionInfo; import com.gluster.storage.management.gui.VolumeOptionsTableLabelProvider; import com.gluster.storage.management.gui.utils.GUIHelper; @@ -103,7 +104,7 @@ public class VolumeOptionsPage extends Composite { setAddButtonsEnabled(false); } - tableViewer.setInput(volume.getOptions().entrySet()); + tableViewer.setInput(volume.getOptions()); parent.layout(); // Important - this actually paints the table registerListeners(parent); @@ -151,7 +152,7 @@ public class VolumeOptionsPage extends Composite { if (!(addTopButton.isEnabled() || addBottomButton.isEnabled())) { // user has selected key, but not added value. Since this is not a valid entry, // remove the last option (without value) from the volume - Entry<String, String> entryBeingAdded = keyEditingSupport.getEntryBeingAdded(); + VolumeOption entryBeingAdded = keyEditingSupport.getEntryBeingAdded(); volume.getOptions().remove(entryBeingAdded.getKey()); } } @@ -200,7 +201,7 @@ public class VolumeOptionsPage extends Composite { } // if this is the last option in the volume options, it must be the new option - return optionKey.equals(volume.getOptions().keySet().toArray()[volume.getOptions().size() - 1]); + return optionKey.equals(volume.getOptions().getOptions().get(volume.getOptions().size() - 1)); } }; @@ -219,8 +220,8 @@ public class VolumeOptionsPage extends Composite { filterText.setEnabled(false); } - private Entry<String, String> getEntry(String key) { - for (Entry<String, String> entry : volume.getOptions().entrySet()) { + private VolumeOption getEntry(String key) { + for (VolumeOption entry : volume.getOptions().getOptions()) { if (entry.getKey().equals(key)) { return entry; } diff --git a/src/com.gluster.storage.management.server.scripts/src/Common.py b/src/com.gluster.storage.management.server.scripts/src/Common.py index 99c2f440..c85e9a2b 100644 --- a/src/com.gluster.storage.management.server.scripts/src/Common.py +++ b/src/com.gluster.storage.management.server.scripts/src/Common.py @@ -18,26 +18,3 @@ import sys
import syslog
-def log(priority, message=None):
- if type(priority) == type(""):
- logPriority = syslog.LOG_INFO
- logMessage = priority
- else:
- logPriority = priority
- logMessage = message
- if not logMessage:
- return
- #if Globals.DEBUG:
- # sys.stderr.write(logMessage)
- else:
- syslog.syslog(logPriority, logMessage)
- return
-
-
-def stripEmptyLines(content):
- ret = ""
- for line in content.split("\n"):
- if line.strip() != "":
- ret += line
- return ret
-
diff --git a/src/com.gluster.storage.management.server.scripts/src/Disk.py b/src/com.gluster.storage.management.server.scripts/src/Disk.py index a1ab9264..2c47d396 100755 --- a/src/com.gluster.storage.management.server.scripts/src/Disk.py +++ b/src/com.gluster.storage.management.server.scripts/src/Disk.py @@ -17,7 +17,6 @@ import os import dbus -from Common import * class Disk: def __init__(self): diff --git a/src/com.gluster.storage.management.server.scripts/src/DiskUtils.py b/src/com.gluster.storage.management.server.scripts/src/DiskUtils.py index 03c5019e..4861f4c4 100644 --- a/src/com.gluster.storage.management.server.scripts/src/DiskUtils.py +++ b/src/com.gluster.storage.management.server.scripts/src/DiskUtils.py @@ -17,23 +17,26 @@ import os import glob +from copy import deepcopy import dbus -import syslog import Globals -import Common +import time import Utils +import Disk +import Protocol +from FsTabUtils import * ONE_MB_SIZE = 1048576 def _stripDev(device): - if isString(device) and device.startswith("/dev/"): + if Utils.isString(device) and device.startswith("/dev/"): return device[5:] return device def _addDev(deviceName): - if isString(deviceName) and not deviceName.startswith("/dev/"): + if Utils.isString(deviceName) and not deviceName.startswith("/dev/"): return "/dev/" + deviceName return deviceName @@ -48,7 +51,7 @@ def getDeviceName(device): def getDevice(deviceName): - if isString(deviceName): + if Utils.isString(deviceName): return _addDev(deviceName) if type(deviceName) == type([]): nameList = [] @@ -73,7 +76,7 @@ def getUuidByDiskPartition(device): def getDiskPartitionUuid(partition): - log("WARNING: getDiskPartitionUuid() is deprecated by getUuidByDiskPartition()") + Utils.log("WARNING: getDiskPartitionUuid() is deprecated by getUuidByDiskPartition()") return getUuidByDiskPartition(partition) @@ -81,17 +84,18 @@ def getDiskPartitionByLabel(label): ## TODO: Finding needs to be enhanced labelFile = "/dev/disk/by-label/%s" % label if os.path.exists(labelFile): - return getDeviceName(os.path.realpath(labelFile)) + if os.path.islink(labelFile): + return getDeviceName(os.path.realpath(labelFile)) return None def getDeviceByLabel(label): - log("WARNING: getDeviceByLabel() is deprecated by getDiskPartitionByLabel()") + Utils.log("WARNING: getDeviceByLabel() is deprecated by getDiskPartitionByLabel()") return getDiskPartitionByLabel(label) def getDiskPartitionLabel(device): - rv = runCommandFG(["sudo", "e2label", device], stdout=True) + rv = Utils.runCommandFG(["sudo", "e2label", device], stdout=True) if rv["Status"] == 0: return rv["Stdout"].strip() return False @@ -104,19 +108,58 @@ def getRootPartition(fsTabFile=Globals.FSTAB_FILE): if fsTabEntry["Device"].startswith("UUID="): return getDiskPartitionByUuid(fsTabEntry["Device"].split("UUID=")[-1]) if fsTabEntry["Device"].startswith("LABEL="): - return getDiskPartitionByLabel(fsTabEntry["Device"].split("LABEL=")[-1]) + partitionName = getDiskPartitionByLabel(fsTabEntry["Device"].split("LABEL=")[-1]) + if partitionName: + return partitionName return getDeviceName(fsTabEntry["Device"]) return None +def getRaidDisk(): + array = [] + arrayList = [] + mdFound = False + + try: + fp = open("/proc/mdstat") + for line in fp: + str = line.strip() + if str.startswith("md"): + array.append(str) + mdFound = True + continue + if mdFound: + if str: + array.append(str) + else: + arrayList.append(array) + array = [] + mdFound = False + fp.close() + except IOError, e: + return None + + raidList = {} + for array in arrayList: + raid = {} + tokens = array[0].split() + raid['status'] = tokens[2] + raid['type'] = tokens[3] + + raid['disks'] = [x.split('[')[0] for x in tokens[4:]] + raid['size'] = float(array[1].split()[0]) / 1024.0 + raidList[tokens[0]] = raid + return raidList + + def getOsDisk(): - log("WARNING: getOsDisk() is deprecated by getRootPartition()") + Utils.log("WARNING: getOsDisk() is deprecated by getRootPartition()") return getRootPartition() -def getDiskList(diskDeviceList=None): +def getDiskInfo(diskDeviceList=None): diskDeviceList = getDevice(diskDeviceList) - if isString(diskDeviceList): + if Utils.isString(diskDeviceList): diskDeviceList = [diskDeviceList] dbusSystemBus = dbus.SystemBus() @@ -125,15 +168,15 @@ def getDiskList(diskDeviceList=None): halManager = dbus.Interface(halObj, "org.freedesktop.Hal.Manager") storageUdiList = halManager.FindDeviceByCapability("storage") + diskInfo = {} diskList = [] for udi in storageUdiList: halDeviceObj = dbusSystemBus.get_object("org.freedesktop.Hal", udi) halDevice = dbus.Interface(halDeviceObj, "org.freedesktop.Hal.Device") - if halDevice.GetProperty("storage.drive_type") == "cdrom" or \ + if halDevice.GetProperty("storage.drive_type") in ["cdrom", "floppy"] or \ halDevice.GetProperty("block.is_volume"): continue - disk = {} disk["Device"] = str(halDevice.GetProperty('block.device')) if diskDeviceList and disk["Device"] not in diskDeviceList: @@ -142,39 +185,94 @@ def getDiskList(diskDeviceList=None): if halDevice.GetProperty('storage.removable'): disk["Size"] = long(halDevice.GetProperty('storage.removable.media_size')) else: - disk["Size"] = long(halDevice.GetProperty('storage.size')) + disk["Size"] = long(halDevice.GetProperty('storage.size')) / 1024**2 disk["Interface"] = str(halDevice.GetProperty('storage.bus')) disk["DriveType"] = str(halDevice.GetProperty('storage.drive_type')) + disk["Status"] = "UNINITIALIZED" + if isDiskInFormatting(disk["Device"]): + disk["Status"] = "FORMATTING IN PROGRESS" + disk["Uuid"] = None + disk["Init"] = False + disk["Type"] = False + disk["FsType"] = None + disk["FsVersion"] = None + disk["MountPoint"] = None + disk["ReadOnlyAccess"] = None + disk["SpaceInUse"] = None + partitionList = [] partitionUdiList = halManager.FindDeviceStringMatch("info.parent", udi) + diskSpaceInUse = 0 for partitionUdi in partitionUdiList: + used = 0 partitionHalDeviceObj = dbusSystemBus.get_object("org.freedesktop.Hal", partitionUdi) partitionHalDevice = dbus.Interface(partitionHalDeviceObj, "org.freedesktop.Hal.Device") if not partitionHalDevice.GetProperty("block.is_volume"): continue - partition = {} - partition["Device"] = str(partitionHalDevice.GetProperty('block.device')) - partition["Uuid"] = str(partitionHalDevice.GetProperty('volume.uuid')) - partition["Size"] = long(partitionHalDevice.GetProperty('volume.size')) - partition["Fstype"] = str(partitionHalDevice.GetProperty('volume.fstype')) - partition["Fsversion"] = str(partitionHalDevice.GetProperty('volume.fsversion')) - partition["Label"] = str(partitionHalDevice.GetProperty('volume.label')) - partition["Used"] = 0L + partitionDevice = str(partitionHalDevice.GetProperty('block.device')) if partitionHalDevice.GetProperty("volume.is_mounted"): - rv = runCommandFG(["df", str(partitionHalDevice.GetProperty('volume.mount_point'))], stdout=True) + rv = Utils.runCommandFG(["df", str(partitionHalDevice.GetProperty('volume.mount_point'))], stdout=True) if rv["Status"] == 0: try: - partition["Used"] = long(rv["Stdout"].split("\n")[1].split()[2]) + used = long(rv["Stdout"].split("\n")[1].split()[2]) / 1024 + diskSpaceInUse += used except IndexError: pass except ValueError: pass + + if disk["Device"] == partitionDevice: + disk["Uuid"] = str(partitionHalDevice.GetProperty('volume.uuid')) + disk["Init"] = True # TODO: use isDataDiskPartitionFormatted function to cross verify this + disk["Status"] = "INITIALIZED" + mountPoint = str(partitionHalDevice.GetProperty('volume.mount_point')) + if "/export/" in mountPoint: + disk["Type"] = True + disk["Status"] = "READY" + disk["FsType"] = str(partitionHalDevice.GetProperty('volume.fstype')) + disk["FsVersion"] = str(partitionHalDevice.GetProperty('volume.fsversion')) + disk["MountPoint"] = str(partitionHalDevice.GetProperty('volume.mount_point')) + disk["ReadOnlyAccess"] = str(partitionHalDevice.GetProperty('volume.is_mounted_read_only')) + if not disk["Size"]: + disk["Size"] = long(partitionHalDevice.GetProperty('volume.size')) / 1024**2 + disk["SpaceInUse"] = used + continue + + partition = {} + partition["Init"] = False + partition["Type"] = False + partition["Status"] = "UNINITIALIZED" + if isDiskInFormatting(partitionDevice): + partition["Status"] = "FORMATTING IN PROGRESS" + partition["Interface"] = None # Partition will not have bus details, info.interfaces can be used here! + partition["Device"] = partitionDevice + partition["Uuid"] = str(partitionHalDevice.GetProperty('volume.uuid')) + partition["Size"] = long(partitionHalDevice.GetProperty('volume.size')) / 1024**2 + partition["FsType"] = str(partitionHalDevice.GetProperty('volume.fstype')) + partition["FsVersion"] = str(partitionHalDevice.GetProperty('volume.fsversion')) + partition["Label"] = str(partitionHalDevice.GetProperty('volume.label')) + partition["MountPoint"] = str(partitionHalDevice.GetProperty('volume.mount_point')) + partition["Size"] = long(partitionHalDevice.GetProperty('volume.size')) / 1024**2 + partition["SpaceInUse"] = used + if partition["MountPoint"] or isDataDiskPartitionFormatted(partitionDevice): + partition["Init"] = True + partition["Status"] = "INITIALIZED" + if "/export/" in partition["MountPoint"]: + partition["Type"] = True + partition["Status"] = "READY" + partition["ReadOnlyAccess"] = str(partitionHalDevice.GetProperty('volume.is_mounted_read_only')) partitionList.append(partition) disk["Partitions"] = partitionList + if not disk["SpaceInUse"]: + disk["SpaceInUse"] = diskSpaceInUse diskList.append(disk) - return diskList + diskInfo["disks"] = diskList + return diskInfo + +def getDiskList(diskDeviceList=None): + return diskInfo["disks"] def readFsTab(fsTabFile=Globals.FSTAB_FILE): try: @@ -206,7 +304,6 @@ def readFsTab(fsTabFile=Globals.FSTAB_FILE): pass if fsTabEntry["Device"] and fsTabEntry["MountPoint"] and fsTabEntry["FsType"] and fsTabEntry["Options"]: fsTabEntryList.append(fsTabEntry) - fsTabfp.close() return fsTabEntryList @@ -250,9 +347,9 @@ def getDiskSizeInfo(partition): free = None command = "df -kl -t ext3 -t ext4 -t xfs" rv = Utils.runCommandFG(command, stdout=True, root=True) - message = Common.stripEmptyLines(rv["Stdout"]) + message = Utils.stripEmptyLines(rv["Stdout"]) if rv["Stderr"]: - Common.log(syslog.LOG_ERR, "failed to get disk details. %s" % Common.stripEmptyLines(rv["Stdout"])) + Utils.log("failed to get disk details. %s" % Utils.stripEmptyLines(rv["Stdout"])) return None, None, None for line in rv["Stdout"].split("\n"): tokens = line.split() @@ -280,9 +377,9 @@ def getDiskSizeInfo(partition): number = int(partitionNumber) command = "parted -ms %s unit kb print" % disk rv = Utils.runCommandFG(command, stdout=True, root=True) - message = Common.stripEmptyLines(rv["Stdout"]) + message = Utils.stripEmptyLines(rv["Stdout"]) if rv["Stderr"]: - Common.log(syslog.LOG_ERR, "failed to get disk details. %s" % Common.stripEmptyLines(rv["Stdout"])) + Utils.log("failed to get disk details. %s" % Utils.stripEmptyLines(rv["Stdout"])) return None, None, None lines = rv["Stdout"].split(";\n") @@ -299,10 +396,398 @@ def getDiskSizeInfo(partition): return total, used, free -def refreshHal(): - rv = Utils.runCommandFG(["lshal"], stdout=True, root=True) - if rv["Stderr"]: - error = Common.stripEmptyLines(rv["Stderr"]) - Common.log(syslog.LOG_ERR, "failed to execute lshal command. Error: %s" % error) +def isDataDiskPartitionFormatted(device): + #Todo: Proper label needs to be added for data partition + #if getDiskPartitionLabel(device) != Globals.DATA_PARTITION_LABEL: + # return False + device = getDeviceName(device) + diskObj = Disk.Disk() + for disk in diskObj.getMountableDiskList(): + if disk['device'].upper() == device.upper(): + mountPoint = disk['mount_point'] + if not mountPoint: + return False + if not os.path.exists(mountPoint): + return False + + uuid = getUuidByDiskPartition(device) + if not uuid: + return False + + for fsTabEntry in readFsTab(): + if fsTabEntry["Device"] == ("UUID=%s" % uuid) and fsTabEntry["MountPoint"] == mountPoint: + return True + return False + + +def getDiskDom(diskDeviceList=None, bootPartition=None, skipDisk=None): + diskDeviceList = getDevice(diskDeviceList) + if Utils.isString(diskDeviceList): + diskDeviceList = [diskDeviceList] + + if skipDisk: + skipDisk = getDevice(skipDisk) + if Utils.isString(skipDisk): + skipDisk = [skipDisk] + + diskInfo = getDiskInfo(diskDeviceList) + diskList = diskInfo["disks"] + if not diskList: + return None + + raidDiskPartitions = [] + raidDisk = getRaidDisk() + for partition in raidDisk.values(): + raidDiskPartitions += partition['disks'] + + diskDom = Protocol.XDOM() + disksTag = diskDom.createTag("disks", None) + raidPartitions = {} + raidDisks = {} + if not bootPartition: + bootPartition = getRootPartition() + for disk in diskList: + if skipDisk and disk["Device"] in skipDisk: + continue + diskTag = diskDom.createTag("disk", None) + diskDevice = getDeviceName(disk["Device"]) + diskTag.appendChild(diskDom.createTag("name", diskDevice)) + diskTag.appendChild(diskDom.createTag("description", disk["Description"])) + diskTag.appendChild(diskDom.createTag("uuid", disk["Uuid"])) + diskTag.appendChild(diskDom.createTag("status", disk["Status"])) + diskTag.appendChild(diskDom.createTag("init", str(disk["Init"]).lower())) + diskTag.appendChild(diskDom.createTag("type", str(disk["Type"]).lower())) + diskTag.appendChild(diskDom.createTag("interface", disk["Interface"])) + diskTag.appendChild(diskDom.createTag("fsType", disk["FsType"])) + diskTag.appendChild(diskDom.createTag("fsVersion", disk["FsVersion"])) + diskTag.appendChild(diskDom.createTag("mountPoint", disk["MountPoint"])) + diskTag.appendChild(diskDom.createTag("size", disk["Size"])) + diskTag.appendChild(diskDom.createTag("spaceInUse", disk["SpaceInUse"])) + partitionsTag = diskDom.createTag("partitions", None) + for partition in disk["Partitions"]: + partitionTag = diskDom.createTag("partition", None) + device = getDeviceName(partition["Device"]) + partitionTag.appendChild(diskDom.createTag("name", device)) + if partition["Uuid"]: #TODO: Move this verification and findings to getDiskInfo function + partitionTag.appendChild(diskDom.createTag("uuid", partition["Uuid"])) + else: + partitionTag.appendChild(diskDom.createTag("uuid", getUuidByDiskPartition("/dev/" + device))) + partitionTag.appendChild(diskDom.createTag("status", partition["Status"])) + partitionTag.appendChild(diskDom.createTag("init", str(partition["Init"]).lower())) + partitionTag.appendChild(diskDom.createTag("type", str(partition["Type"]).lower())) + partitionTag.appendChild(diskDom.createTag("interface", partition["Interface"])) + partitionTag.appendChild(diskDom.createTag("fsType", partition["FsType"])) + partitionTag.appendChild(diskDom.createTag("mountPoint", partition['MountPoint'])) + partitionTag.appendChild(diskDom.createTag("size", partition["Size"])) + partitionTag.appendChild(diskDom.createTag("spaceInUse", partition["SpaceInUse"])) + if device in raidDiskPartitions: + raidPartitions[device] = partitionTag + continue + partitionsTag.appendChild(partitionTag) + diskTag.appendChild(partitionsTag) + + if diskDevice in raidDiskPartitions: + raidDisks[diskDevice] = diskTag + else: + disksTag.appendChild(diskTag) + + + for rdisk in raidDisk.keys(): + raidDiskTag = diskDom.createTag("disk", None) + raidDiskTag.appendChild(diskDom.createTag("name", rdisk)) + if 'active' == raidDisk[rdisk]['status']: + raidDiskTag.appendChild(diskDom.createTag("status", "true")) + else: + raidDiskTag.appendChild(diskDom.createTag("status", "false")) + raidDiskTag.appendChild(diskDom.createTag("interface", raidDisk[rdisk]['type'])) + raidDiskTag.appendChild(diskDom.createTag("size", raidDisk[rdisk]['size'])) + raidDisksTag = diskDom.createTag("raidDisks", None) + raidDiskPartitionsTag = diskDom.createTag("partitions", None) + for disk in raidDisk[rdisk]['disks']: + if raidPartitions.has_key(disk): + raidDiskPartitionsTag.appendChild(raidPartitions[disk]) + if raidDisks.has_key(disk): + raidDisksTag.appendChild(raidDisks[disk]) + raidDisksTag.appendChild(raidDiskPartitionsTag) + raidDiskTag.appendChild(raidDisksTag) + disksTag.appendChild(raidDiskTag) + diskDom.addTag(disksTag) + return diskDom + + +def initializeDisk(disk, boot=False, startSize=0, sudo=False): + if boot and startSize > 0: + return False + + disk = getDevice(disk) + diskObj = getDiskList(disk)[0] + + if boot or startSize == 0: + command = "dd if=/dev/zero of=%s bs=1024K count=1" % diskObj["Device"] + if runCommandFG(command, root=sudo) != 0: + if boot: + Utils.log("failed to clear boot sector of disk %s" % diskObj["Device"]) + return False + Utils.log("failed to clear boot sector of disk %s. ignoring" % diskObj["Device"]) + + command = "parted -s %s mklabel gpt" % diskObj["Device"] + if runCommandFG(command, root=sudo) != 0: + return False + + if boot: + command = "parted -s %s mkpart primary ext3 0MB %sMB" % (diskObj["Device"], Globals.OS_PARTITION_SIZE) + if runCommandFG(command, root=sudo) != 0: + return False + command = "parted -s %s set 1 boot on" % (diskObj["Device"]) + if runCommandFG(command, root=sudo) != 0: + return False + startSize = Globals.OS_PARTITION_SIZE + + size = (diskObj["Size"] / ONE_MB_SIZE) - startSize + while size > Globals.MAX_PARTITION_SIZE: + endSize = startSize + Globals.MAX_PARTITION_SIZE + command = "parted -s %s mkpart primary ext3 %sMB %sMB" % (diskObj["Device"], startSize, endSize) + if runCommandFG(command, root=sudo) != 0: + return False + size -= Globals.MAX_PARTITION_SIZE + startSize = endSize + + if size: + command = "parted -s %s mkpart primary ext3 %sMB 100%%" % (diskObj["Device"], startSize) + if runCommandFG(command, root=sudo) != 0: + return False + + if runCommandFG("udevadm settle", root=sudo) != 0: + if runCommandFG("udevadm settle", root=sudo) != 0: + Utils.log("udevadm settle for disk %s failed. ignoring" % diskObj["Device"]) + time.sleep(1) + + if runCommandFG("partprobe %s" % diskObj["Device"], root=sudo) != 0: + Utils.log("partprobe %s failed" % diskObj["Device"]) return False + + if runCommandFG("gptsync %s" % diskObj["Device"], root=sudo) != 0: + Utils.log("gptsync %s failed. ignoring" % diskObj["Device"]) + + # wait forcefully to appear devices in /dev + time.sleep(2) return True + + +def initializeOsDisk(diskObj): + Utils.log("WARNING: initializeOsDisk() is deprecated by initializeDisk(boot=True)") + return initializeDisk(diskObj, boot=True) + + +def initializeDataDisk(diskObj): + Utils.log("WARNING: initializeDataDisk() is deprecated by initializeDisk()") + return initializeDisk(diskObj) + +def getBootPartition(serverName): + diskDom = XDOM() + diskDom.parseFile("%s/%s/disk.xml" % (Globals.SERVER_VOLUME_CONF_DIR, serverName)) + if not diskDom: + return None + partitionDom = XDOM() + partitionUuid = None + partitionName = None + for partitionTag in diskDom.getElementsByTagRoute("disk.partition"): + partitionDom.setDomObj(partitionTag) + boot = partitionDom.getTextByTagRoute("boot") + if boot and boot.strip().upper() == 'YES': + partitionUuid = partitionDom.getTextByTagRoute("uuid") + partitionName = partitionDom.getTextByTagRoute("device") + break + if not (partitionUuid and partitionName): + return None + + # check device label name + deviceBaseName = os.path.basename(partitionName) + process = runCommandBG(['sudo', 'e2label', partitionName]) + if type(process) == type(True): + return None + if process.wait() != 0: + return None + output = process.communicate() + deviceLabel = output[0].split()[0] + if deviceLabel != Globals.BOOT_PARTITION_LABEL: + return None + + # check uuid in etc/fstab + try: + fstabEntries = open(Globals.FSTAB_FILE).readlines() + except IOError: + fstabEntries = [] + found = False + for entry in fstabEntries: + entry = entry.strip() + if not entry: + continue + if entry.split()[0] == "UUID=" + partitionUuid: + found = True + break + if not found: + return None + return partitionName + + +def isDiskInFormatting(device): + DEVICE_FORMAT_LOCK_FILE = "/var/lock/%s.lock" % device + return os.path.exists(DEVICE_FORMAT_LOCK_FILE) + + +def isDiskInFormat(device): + Utils.log("WARNING: isDiskInFormat() is deprecated by isDataDiskPartitionFormatted()") + return isDataDiskPartitionFormatted(device) + + +def diskOrder(serverExportList): + newServerExportList = [] + while serverExportList: + serverExport = deepcopy(serverExportList[0]) + if newServerExportList and serverExport.split(":")[0] == newServerExportList[-1].split(":")[0]: + inserted = False + for i in range(0, len(newServerExportList) - 1): + if serverExport.split(":")[0] == newServerExportList[i].split(":")[0]: + continue + if i == 0: + newServerExportList.insert(i, serverExport) + inserted = True + break + if serverExport.split(":")[0] == newServerExportList[i - 1].split(":")[0]: + continue + newServerExportList.insert(i, serverExport) + inserted = True + break + if not inserted: + newServerExportList.append(serverExport) + else: + newServerExportList.append(serverExport) + serverExportList.remove(serverExport) + i = 0 + while serverExportList and i < len(serverExportList): + if serverExport.split(":")[0] == serverExportList[i].split(":")[0]: + i += 1 + continue + serverExport = deepcopy(serverExportList[i]) + newServerExportList.append(serverExport) + serverExportList.remove(serverExport) + return newServerExportList + + +def updateServerDiskConfig(serverName, diskDom, requestFlag=True, partitionFlag=True): + command = "command.server." + if not requestFlag: + command = "" + diskList = {} + for tagE in diskDom.getElementsByTagRoute(command + "disk"): + diskList[diskDom.getTextByTagRoute(command + "device")] = tagE + configDom = XDOM() + if not configDom.parseFile("%s/%s/disk.xml" % (Globals.SERVER_VOLUME_CONF_DIR, serverName)): + return diskDom.writexml("%s/%s/disk.xml" % (Globals.SERVER_VOLUME_CONF_DIR, serverName)) + diskTag = configDom.getElementsByTagRoute("disks.disk") + disks = configDom.getElementsByTagRoute("disks") + if not (diskTag or disks): + return None + for tagE in diskTag: + diskDom = XDOM() + diskDom.setDomObj(tagE) + device = diskDom.getTextByTagRoute("device") + if partitionFlag and device in diskList: + disks[0].removeChild(tagE) + disks[0].appendChild(deepcopy(diskList[device])) + continue + if not partitionFlag and device in diskList: + partitionList = [] + for childNodeTag in tagE.childNodes: + if childNodeTag.nodeName == 'partition': + partitionList.append(childNodeTag) + tagE.childNodes = [] + tagE.childNodes = diskList[device].childNodes + partitionList + return configDom.writexml("%s/%s/disk.xml" % (Globals.SERVER_VOLUME_CONF_DIR, serverName)) + + +def compareDisksDom(diskDomA, diskDomB, requestFlag=True): + command = "command.server.disk." + if not requestFlag: + command = "" + sourceDiskList = {} + sourceDisk = {} + for tagE in diskDomA.getElementsByTagRoute("disk"): + sourceDisk["description"] = diskDomA.getTextByTagRoute("description") + sourceDisk["size"] = diskDomA.getTextByTagRoute("size") + sourceDisk["init"] = diskDomA.getTextByTagRoute("init") + sourceDisk["interface"] = diskDomA.getTextByTagRoute("interface") + sourceDiskList[diskDomA.getTextByTagRoute("device")] = sourceDisk + objDiskList = {} + objDisk = {} + for tagE in diskDomB.getElementsByTagRoute("disk"): + objDisk["description"] = diskDomB.getTextByTagRoute("description") + objDisk["size"] = diskDomB.getTextByTagRoute("size") + objDisk["init"] = diskDomB.getTextByTagRoute("init") + objDisk["interface"] = diskDomB.getTextByTagRoute("interface") + objDiskList[diskDomB.getTextByTagRoute("device")] = objDisk + return sourceDiskList == objDiskList + + +def compareDiskDom(diskDomA, diskDomB, requestFlag=True): + command = "command.server.disk." + if not requestFlag: + command = "" + sourceDisk = {} + sourceDisk["device"] = diskDomA.getTextByTagRoute("device") + sourceDisk["description"] = diskDomA.getTextByTagRoute("description") + sourceDisk["size"] = diskDomA.getTextByTagRoute("size") + sourceDisk["init"] = diskDomA.getTextByTagRoute("init") + sourceDisk["interface"] = diskDomA.getTextByTagRoute("interface") + for tagE in diskDomA.getElementsByTagRoute("partition"): + sourceDiskPartitions = {} + partitionDom = XDOM() + partitionDom.setDomObj(tagE) + sourceDiskPartitions["size"] = partitionDom.getTextByTagRoute("size") + #sourceDiskPartitions["free"] = partitionDom.getTextByTagRoute("free") + sourceDiskPartitions["format"] = partitionDom.getTextByTagRoute("format") + sourceDiskPartitions["uuid"] = partitionDom.getTextByTagRoute("uuid") + sourceDisk[partitionDom.getTextByTagRoute("device")] = sourceDiskPartitions + + objDisk = {} + objDisk["device"] = diskDomB.getTextByTagRoute(command + "device") + objDisk["description"] = diskDomB.getTextByTagRoute(command + "description") + objDisk["size"] = diskDomB.getTextByTagRoute(command + "size") + objDisk["init"] = diskDomB.getTextByTagRoute(command + "init") + objDisk["interface"] = diskDomB.getTextByTagRoute(command + "interface") + for tagE in diskDomB.getElementsByTagRoute(command + "partition"): + objDiskPartitions = {} + partitionDom = XDOM() + partitionDom.setDomObj(tagE) + objDiskPartitions["size"] = partitionDom.getTextByTagRoute("size") + #objDiskPartitions["free"] = partitionDom.getTextByTagRoute("free") + objDiskPartitions["format"] = partitionDom.getTextByTagRoute("format") + objDiskPartitions["uuid"] = partitionDom.getTextByTagRoute("uuid") + objDisk[partitionDom.getTextByTagRoute("device")] = objDiskPartitions + return sourceDisk == objDisk + + +def getServerConfigDiskDom(serverName, diskName=None): + diskConfigDom = XDOM() + if not diskConfigDom.parseFile("%s/%s/disk.xml" % (Globals.SERVER_VOLUME_CONF_DIR, serverName)): + Utils.log("Unable to parse %s/%s/disk.xml" % (Globals.SERVER_VOLUME_CONF_DIR, serverName)) + return None + diskTag = diskConfigDom.getElementsByTagRoute("disks.disk") + if not diskTag: + Utils.log("Unable to reterive disk information %s/%s/disk.xml" % (Globals.SERVER_VOLUME_CONF_DIR, serverName)) + return None + if diskName: + for tagE in diskTag: + diskDom = XDOM() + diskDom.setDomObj(tagE) + if diskName == diskDom.getTextByTagRoute("device"): + return diskDom + return None + + for tagE in diskTag: + for partitionTag in tagE.getElementsByTagName("partition"): + tagE.removeChild(partitionTag) + return diskConfigDom + + diff --git a/src/com.gluster.storage.management.server.scripts/src/FsTabUtils.py b/src/com.gluster.storage.management.server.scripts/src/FsTabUtils.py new file mode 100644 index 00000000..fcac4196 --- /dev/null +++ b/src/com.gluster.storage.management.server.scripts/src/FsTabUtils.py @@ -0,0 +1,92 @@ +# Copyright (C) 2010 Gluster, Inc. <http://www.gluster.com> +# This file is part of Gluster Storage Platform. +# +# Gluster Storage Platform is free software; you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 3 of +# the License, or (at your option) any later version. +# +# Gluster Storage Platform is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see +# <http://www.gnu.org/licenses/>. + +import Globals + +def readFsTab(fsTabFile=Globals.FSTAB_FILE): + try: + fsTabfp = open(fsTabFile) + except IOError, e: + log("readFsTab(): " + str(e)) + return None + + fsTabEntryList = [] + for line in fsTabfp: + tokens = line.strip().split() + if not tokens or tokens[0].startswith('#'): + continue + fsTabEntry = {} + fsTabEntry["Device"] = None + fsTabEntry["MountPoint"] = None + fsTabEntry["FsType"] = None + fsTabEntry["Options"] = None + fsTabEntry["DumpOption"] = 0 + fsTabEntry["fsckOrder"] = 0 + try: + fsTabEntry["Device"] = tokens[0] + fsTabEntry["MountPoint"] = tokens[1] + fsTabEntry["FsType"] = tokens[2] + fsTabEntry["Options"] = tokens[3] + fsTabEntry["DumpOption"] = tokens[4] + fsTabEntry["fsckOrder"] = tokens[5] + except IndexError: + pass + if fsTabEntry["Device"] and fsTabEntry["MountPoint"] and fsTabEntry["FsType"] and fsTabEntry["Options"]: + fsTabEntryList.append(fsTabEntry) + + fsTabfp.close() + return fsTabEntryList + +def 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: + return False + + return writeFsTab(fsTabEntryList, fsTabFile) + diff --git a/src/com.gluster.storage.management.server.scripts/src/NetworkUtils.py b/src/com.gluster.storage.management.server.scripts/src/NetworkUtils.py index 7a854564..da212a9b 100755 --- a/src/com.gluster.storage.management.server.scripts/src/NetworkUtils.py +++ b/src/com.gluster.storage.management.server.scripts/src/NetworkUtils.py @@ -194,7 +194,7 @@ def getNetSpeed(deviceName): for line in rv["Stdout"].split("\n"): tokens = line.strip().split(":") if tokens[0].upper() == "SPEED": - return tokens[1].strip().upper() + return tokens[1].strip().upper().split("MB")[0] return None def getLinkStatus(deviceName): @@ -264,9 +264,7 @@ def setBondMode(deviceName, mode, fileName=None): def getNetDeviceList(root=""): netDeviceList = [] - for deviceName in os.listdir("/sys/class/net/"): - #for device in getHardwareList(): netDevice = {} netDevice["device"] = None netDevice["description"] = None @@ -298,11 +296,11 @@ def getNetDeviceList(root=""): netDevice["mode"] = getBondMode(deviceName, root + Globals.MODPROBE_CONF_FILE) netDevice["model"] = getNetModel(deviceName) netDevice["speed"] = getNetSpeed(deviceName) - try: netDevice["hwaddr"] = open("/sys/class/net/%s/address" % deviceName).read().strip() except IOError: pass + netDeviceList.append(netDevice) conf = readIfcfgConfFile(deviceName, root) diff --git a/src/com.gluster.storage.management.server.scripts/src/RRDUtils.py b/src/com.gluster.storage.management.server.scripts/src/RRDUtils.py new file mode 100644 index 00000000..1ad0deee --- /dev/null +++ b/src/com.gluster.storage.management.server.scripts/src/RRDUtils.py @@ -0,0 +1,72 @@ +import rrdtool +import os +from socket import gethostname +from itertools import groupby + +class RRD: + def __init__ (self): + self.COLORS = [0xff7777, 0x7777ff, 0x55ff55, 0xffcc77, 0xff77ff, 0x77ffff,0xffff77, 0x55aaff] + self.HOST = gethostname() + self.DIR = "/var/lib/collectd" + + def fade_component(self, component): + return ((component + 255 * 5) / 6) + + def fade_color(self, color): + r = 0; + for i in [0,1,2]: + shft = (i * 8) + component = ((color >> shft) & 255) + r |= (self.fade_component(component) << shft) + return r + + def generate_pngs(self): + + rrdlist = os.popen ("find %s -type f -name '*.rrd'" % self.DIR) + + for rrd in rrdlist: + self.dss = [] + self.defs = "" + + rrdinfo = rrdtool.info(rrd.strip()) + + for key in rrdinfo.keys(): + if key.split('[')[0] == 'ds': + self.dss.append(key.split('[')[1].split(']')[0]) + self.dss.sort() + + self.dss = [a for a,b in groupby(self.dss)] + + for ds in self.dss: + self.defs = self.defs + " DEF:%s_avg=%s:%s:AVERAGE " % (ds, rrd.strip(), ds) + self.defs = self.defs + " DEF:%s_max=%s:%s:MAX " % (ds, rrd.strip(), ds) + + j = 0 + for ds in self.dss: + color = self.COLORS[j % len(self.COLORS)] + j = j + 1 + faded_color = self.fade_color(color) + self.defs = self.defs + " AREA:%s_max#%06x " % (ds, faded_color) + + j = 0 + for ds in self.dss: + color = self.COLORS[j % len(self.COLORS)] + j = j + 1 + self.defs = self.defs + " LINE2:%s_avg#%06x:%s " % (ds, color, ds) + self.defs = self.defs + " GPRINT:%s_avg:AVERAGE:%%5.1lf%%sAvg " % ds + self.defs = self.defs + " GPRINT:%s_max:MAX:%%5.1lf%%sMax " % ds + + for span in ['1hour', '1day', '1week', '1month']: + os.system ("mkdir -p %s/%s" % (self.DIR, self.HOST)) + image = os.path.dirname(rrd.strip()) + "-" + span + ".png" + cmd = "rrdtool graph " + image + " -t \"%s %s\"" % (os.path.dirname(rrd.strip()), span) + " --imgformat PNG --width 600 --height 100 --start now-" + span + " --end now --interlaced " + self.defs + " >/dev/null 2>&1" + os.system(cmd) + + +def main (): + + rrd = RRD () + rrd.generate_pngs () + +if __name__ == "__main__": + main() diff --git a/src/com.gluster.storage.management.server.scripts/src/Utils.py b/src/com.gluster.storage.management.server.scripts/src/Utils.py index 6e33af0b..fe2816d0 100644 --- a/src/com.gluster.storage.management.server.scripts/src/Utils.py +++ b/src/com.gluster.storage.management.server.scripts/src/Utils.py @@ -34,7 +34,6 @@ import urllib import Globals import Protocol -from Common import * RUN_COMMAND_ERROR = -1024 LOG_SYSLOG = 1 @@ -703,7 +702,7 @@ def removeFile(fileName, root=False): os.remove(fileName) return True except OSError, e: - Utils.log("Failed to remove file %s: %s" % (fileName, e)) + log("Failed to remove file %s: %s" % (fileName, e)) return False @@ -712,3 +711,354 @@ def isLiveMode(): def convertKbToMb(kb): return kb / 1024.0 + + +def getIPIndex(indexFile): + try: + fp = open(indexFile) + line = fp.readline() + fp.close() + index = int(line) + except IOError: + index = 0 + except ValueError: + index = False + return index + +def setIPIndex(index, indexFile): + try: + fp = open(indexFile, "w") + fp.write(str(index)) + fp.close() + except IOError: + return False + return True + +def IP2Number(ipString): + try: + return socket.htonl(struct.unpack("I", socket.inet_aton(ipString))[0]) + except socket.error: + return None + except TypeError: + return None + except struct.error: + return None + +def Number2IP(number): + try: + return socket.inet_ntoa(struct.pack("I", socket.ntohl(number))) + except socket.error: + return None + except AttributeError: + return None + except ValueError: + return None + +def hasEntryFoundInFile(searchString, dnsEntryFileName): + try: + addServerEntryList = open(dnsEntryFileName).read().split() + except IOError: + return None + if searchString in addServerEntryList: + return True + return False + + +def computeIpAddress(ipAddress, startIp, endIp): + startIpNumber = IP2Number(startIp) + endIpNumber = IP2Number(endIp) + if not ipAddress: + return startIp + nextIpNumber = IP2Number(ipAddress) + while True: + nextIpNumber = nextIpNumber + 1 + ipAddress = Number2IP(nextIpNumber) + rv = runCommandFG(["ping", "-qnc", "1", ipAddress]) + if type(rv) == type(True): + return False + if rv != 0: + break + + if nextIpNumber >= startIpNumber and nextIpNumber <= endIpNumber: + return ipAddress + + nextIpNumber = IP2Number(startIp) + while True: + ipAddress = Number2IP(nextIpNumber) + nextIpNumber = nextIpNumber + 1 + rv = runCommandFG(["ping", "-qnc", "1", ipAddress]) + if type(rv) == type(True): + return False + if rv != 0: + break + + if IP2Number(ipAddress) >= startIpNumber and IP2Number(ipAddress) <= endIpNumber: + return ipAddress + return False + + +def setHostNameAndIp(hostName, ipAddress, lastAddServerDetailFile): + try: + fp = open(lastAddServerDetailFile, "w") + fp.write("HOSTNAME=" + hostName + "\n") + fp.write("IPADDRESS=" + ipAddress); + fp.close() + except IOError: + return False + return True + +def getPort(): + try: + fd = open(Globals.PORT_FILE, "r") + portString = fd.readline() + fd.close() + port = int(portString) + except IOError: + port = Globals.DEFAULT_PORT - 2 + except ValueError: + port = Globals.DEFAULT_PORT - 2 + return port + +def setPort(port): + try: + fd = open(Globals.PORT_FILE, "w") + fd.write(str(port)) + fd.close() + except IOError: + return False + return True + +def getServerAgentCredentials(): + try: + lines = open(Globals.SERVERAGENT_AUTH_FILE).readlines() + except IOError: + return None,None + + userName = None + password = None + + for l in lines: + if l[-1] == '\n': + l = l[:-1] + k = l[:l.index('=')] + v = l[l.index('=') + 1:] + if v[0] == "'" or v[0] == '"': + v = v[1:] + if v[-1] == "'" or v[-1] == '"': + v = v[:-1] + if k.upper() == "AGENT_ID": + userName = v + if k.upper() == "AGENT_PASSWORD": + password = v + + return userName, password + +def getGatewayAgentCredentials(): + try: + lines = open(Globals.GATEWAYAGENT_AUTH_FILE).readlines() + except IOError: + return None + + #userName = None + password = None + + for l in lines: + if l[-1] == '\n': + l = l[:-1] + k = l[:l.index('=')] + v = l[l.index('=') + 1:] + if v[0] == "'" or v[0] == '"': + v = v[1:] + if v[-1] == "'" or v[-1] == '"': + v = v[:-1] + #if k.upper() == "AGENT_ID": + # userName = v + if k.upper() == "AGENT_PASSWORD": + password = v + + return password + +def getWebAgentCredentials(): + try: + lines = open(Globals.WEBAGENT_AUTH_FILE).readlines() + except IOError: + return None,None + + userName = None + password = None + + for l in lines: + if l[-1] == '\n': + l = l[:-1] + k = l[:l.index('=')] + v = l[l.index('=') + 1:] + if v[0] == "'" or v[0] == '"': + v = v[1:] + if v[-1] == "'" or v[-1] == '"': + v = v[:-1] + if k.upper() == "AGENT_ID": + userName = v + if k.upper() == "AGENT_PASSWORD": + password = v + + return userName, password + +def daemonize(): + try: + pid = os.fork() + if pid > 0: + # exit first parent + sys.exit(0) + except OSError, e: + #sys.stderr.write("fork #1 failed: %d (%s)\n" % (e.errno, e.strerror)) + return False + + # decouple from parent environment + os.chdir("/") + os.setsid() + os.umask(0) + + # do second fork + try: + pid = os.fork() + if pid > 0: + # exit from second parent + sys.exit(0) + except OSError, e: + #sys.stderr.write("fork #2 failed: %d (%s)\n" % (e.errno, e.strerror)) + return False + + # redirect standard file descriptors + sys.stdout.flush() + sys.stderr.flush() + si = file("/dev/null", 'r') + so = file("/dev/null", 'a+') + se = file("/dev/null", 'a+', 0) + os.dup2(si.fileno(), sys.stdin.fileno()) + os.dup2(so.fileno(), sys.stdout.fileno()) + os.dup2(se.fileno(), sys.stderr.fileno()) + return True + +def getFreeIpAddress(): + startRange, endRange = getStoragePoolInfo() + if not (startRange and endRange): + return None + + startIpNumber = IP2Number(startRange) + endIpNumber = IP2Number(endRange) + + for ipNumber in range(endIpNumber, startIpNumber, -1): + rv = runCommandFG(["ping", "-qnc", "1", Number2IP(ipNumber)]) + if type(rv) == type(True): + return None + if rv != 0: + return Number2IP(ipNumber) + return None + +def getDhcpServerStatus(): + status = runCommandFG(["sudo", "service", "dnsmasq", " status"]) + if type(status) == type(True) or 0 != status: + return False + return True + +def startDhcpServer(): + status = runCommandFG(["sudo", "service", "dnsmasq", " start"]) + if type(status) == type(True) or 0 != status: + return False + return True + +def stopDhcpServer(): + status = runCommandFG(["sudo", "service", "dnsmasq", " stop"]) + if type(status) == type(True) or 0 != status: + return False + return True + +def getStoragePoolInfo(): + startRange = None + endRange = None + try: + for line in open(Globals.GLUSTER_SERVER_POOL_FILE): + tokens = line.split("=") + if tokens[0] == "STARTRANGE": + startRange = tokens[1].strip() + if tokens[0] == "ENDRANGE": + endRange = tokens[1].strip() + except IOError: + log(syslog.LOG_ERR, "unable to read %s file" % Globals.GLUSTER_SERVER_POOL_FILE) + return startRange, endRange + +def configureDnsmasq(serverIpAddress, dhcpIpAddress): + dnsmasqConfFile = Globals.GLUSTER_CONF_CONF_DIR + "/dnsmasq.conf" + serverPortString = "68" + try: + for arg in open("/proc/cmdline").read().strip().split(): + token = arg.split("=") + if token[0] == "dhcp": + serverPortString = token[1] + break + except IOError: + log(syslog.LOG_ERR, "Failed to read /proc/cmdline. Continuing with default port 68") + try: + serverPort = int(serverPortString) + except ValueError: + log(syslog.LOG_ERR, "Invalid dhcp port '%s' in /proc/cmdline. Continuing with default port 68" % serverPortString) + serverPort = 68 + + try: + fp = open(dnsmasqConfFile, "w") + fp.write("no-hosts\n") + #fp.write("addn-hosts=%s\n" % Globals.GLUSTER_DNS_ENTRIES) + fp.write("bind-interfaces\n") + fp.write("except-interface=lo\n") + fp.write("dhcp-range=%s,%s\n" % (dhcpIpAddress, dhcpIpAddress)) + fp.write("dhcp-lease-max=1\n") + #fp.write("dhcp-option=option:router,%s\n" % serverIp) + #fp.write("dhcp-option=option:ntp-server,%s\n" % serverIp) + fp.write("dhcp-alternate-port=%s\n" % serverPort) + fp.write("server=%s\n" % serverIpAddress) + fp.write("dhcp-script=/usr/sbin/server-info\n") + fp.close() + except IOError: + log(syslog.LOG_ERR, "unable to write dnsmasq configuration %s" % dnsmasqConfFile) + return False + status = runCommandFG(["sudo", "cp", "-f", Globals.GLUSTER_CONF_CONF_DIR + "/dnsmasq.conf", Globals.DNSMASQ_CONF_FILE]) + if type(status) == type(True) or 0 != status: + log(syslog.LOG_ERR, "unable to copy dnsmasq configuration to " + Globals.DNSMASQ_CONF_FILE) + return False + return True + +def configureDhcpServer(serverIpAddress, dhcpIpAddress): + return configureDnsmasq(serverIpAddress, dhcpIpAddress) + +def log(priority, message=None): + if type(priority) == type(""): + logPriority = syslog.LOG_INFO + logMessage = priority + else: + logPriority = priority + logMessage = message + if not logMessage: + return + #if Globals.DEBUG: + # sys.stderr.write(logMessage) + else: + syslog.syslog(logPriority, logMessage) + return + + +def stripEmptyLines(content): + ret = "" + for line in content.split("\n"): + if line.strip() != "": + ret += line + return ret + + +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('/', '_') diff --git a/src/com.gluster.storage.management.server.scripts/src/clear_volume_directory.py b/src/com.gluster.storage.management.server.scripts/src/clear_volume_directory.py index 6cf2ef38..96677f56 100755 --- a/src/com.gluster.storage.management.server.scripts/src/clear_volume_directory.py +++ b/src/com.gluster.storage.management.server.scripts/src/clear_volume_directory.py @@ -22,13 +22,12 @@ import time from XmlHandler import ResponseXml import DiskUtils import Utils -import Common from optparse import OptionParser def clearVolumeDirectory(diskMountPoint, volumeName, todelete): rs = ResponseXml() if not DiskUtils.checkDiskMountPoint(diskMountPoint): - Common.log(syslog.LOG_ERR, "failed to find disk mount point %s" % diskMountPoint) + Utils.log("failed to find disk mount point %s" % diskMountPoint) rs.appendTagRoute("status.code", "-1") rs.appendTagRoute("status.message", "Error: Mount point does not exists") return rs.toprettyxml() @@ -48,11 +47,11 @@ def clearVolumeDirectory(diskMountPoint, volumeName, todelete): newVolumeDirectoryName = "%s_%s" % (volumeDirectory, time.time()) command = ["sudo", "mv", "-f", volumeDirectory, newVolumeDirectoryName] rv = Utils.runCommandFG(command, stdout=True, root=True) - message = Common.stripEmptyLines(rv["Stdout"]) + message = Utils.stripEmptyLines(rv["Stdout"]) if rv["Stderr"]: - error = Common.stripEmptyLines(rv["Stderr"]) + error = Utils.stripEmptyLines(rv["Stderr"]) message += "Error: [%s]" % (error) - Common.log(syslog.LOG_ERR, "failed to rename volume directory %s, %s" % (volumeDirectory, error)) + Utils.log("failed to rename volume directory %s, %s" % (volumeDirectory, error)) rs.appendTagRoute("status.code", rv["Status"]) rs.appendTagRoute("status.message", message) return rs.toprettyxml() @@ -65,11 +64,11 @@ def clearVolumeDirectory(diskMountPoint, volumeName, todelete): command = ["sudo", "rm", "-fr", newVolumeDirectoryName] rv = Utils.runCommandFG(command, stdout=True, root=True) - message = Common.stripEmptyLines(rv["Stdout"]) + message = Utils.stripEmptyLines(rv["Stdout"]) if rv["Stderr"]: - error = Common.stripEmptyLines(rv["Stderr"]) + error = Utils.stripEmptyLines(rv["Stderr"]) message += "Error: [%s]" % (error) - Common.log(syslog.LOG_ERR, "failed to clear volume directory %s, %s" % (newVolumeDirectoryName, error)) + Utils.log("failed to clear volume directory %s, %s" % (newVolumeDirectoryName, error)) rs.appendTagRoute("status.code", rv["Status"]) rs.appendTagRoute("status.message", message) return rs.toprettyxml() @@ -86,7 +85,7 @@ def main(): (options, args) = parser.parse_args() if len(args) != 2: - print >> sys.stderr, "usage: %s <disk mount point> <volume name> [-d/--delete]" % sys.argv[0] + sys.stderr.write("usage: %s <disk mount point> <volume name> [-d/--delete]\n" % os.path.basename(sys.argv[0])) sys.exit(-1) diskMountPoint = args[0] diff --git a/src/com.gluster.storage.management.server.scripts/src/create_volume_directory.py b/src/com.gluster.storage.management.server.scripts/src/create_volume_directory.py index b8fb2166..3e633697 100755 --- a/src/com.gluster.storage.management.server.scripts/src/create_volume_directory.py +++ b/src/com.gluster.storage.management.server.scripts/src/create_volume_directory.py @@ -17,20 +17,17 @@ # <http://www.gnu.org/licenses/>. import os import sys -import syslog from XmlHandler import ResponseXml import DiskUtils import Utils -import Common def createDirectory(disk, volumeName): - # Retrieving disk uuid diskUuid = DiskUtils.getUuidByDiskPartition(DiskUtils.getDevice(disk)) rs = ResponseXml() if not diskUuid: - Common.log(syslog.LOG_ERR, "failed to find disk:%s uuid" % disk) + Utils.log("failed to find disk:%s uuid" % disk) rs.appendTagRoute("status.code", "-1") rs.appendTagRoute("status.message", "Error: Unable to find disk uuid") return rs.toprettyxml() @@ -38,7 +35,7 @@ def createDirectory(disk, volumeName): # Retrieving disk mount point using disk uuid diskMountPoint = DiskUtils.getMountPointByUuid(diskUuid) if not os.path.exists(diskMountPoint): - Common.log(syslog.LOG_ERR, "failed to retrieve disk:%s mount point" % disk) + Utils.log("failed to retrieve disk:%s mount point" % disk) rs.appendTagRoute("status.code", "-1") rs.appendTagRoute("status.message", "Error: Failed to retrieve disk details") return rs.toprettyxml() @@ -46,7 +43,7 @@ def createDirectory(disk, volumeName): # creating volume directory under disk mount point volumeDirectory = "%s/%s" % (diskMountPoint, volumeName) if os.path.exists(volumeDirectory): - Common.log(syslog.LOG_ERR, "Volume directory:%s already exists" % (volumeDirectory)) + Utils.log("Volume directory:%s already exists" % (volumeDirectory)) rs.appendTagRoute("status.code", "-2") rs.appendTagRoute("status.message", "Volume directory already exists!") return rs.toprettyxml() @@ -54,11 +51,11 @@ def createDirectory(disk, volumeName): if not os.path.exists(volumeDirectory): command = ["sudo", "mkdir", volumeDirectory] rv = Utils.runCommandFG(command, stdout=True, root=True) - message = Common.stripEmptyLines(rv["Stdout"]) + message = Utils.stripEmptyLines(rv["Stdout"]) if rv["Stderr"]: - error = Common.stripEmptyLines(rv["Stderr"]) + error = Utils.stripEmptyLines(rv["Stderr"]) message += "Error: [%s]" % (error) - Common.log(syslog.LOG_ERR, "failed to create volume directory %s, %s" % (volumeDirectory, error)) + Utils.log("failed to create volume directory %s, %s" % (volumeDirectory, error)) rs.appendTagRoute("status.code", rv["Status"]) rs.appendTagRoute("status.message", message) return rs.toprettyxml() @@ -73,7 +70,7 @@ def createDirectory(disk, volumeName): def main(): if len(sys.argv) != 3: - print >> sys.stderr, "usage: %s <disk name> <volume name>" % sys.argv[0] + sys.stderr.write("usage: %s <disk name> <volume name>\n" % os.path.basename(sys.argv[0])) sys.exit(-1) disk = sys.argv[1] diff --git a/src/com.gluster.storage.management.server.scripts/src/format_device.py b/src/com.gluster.storage.management.server.scripts/src/format_device.py new file mode 100755 index 00000000..80334d8a --- /dev/null +++ b/src/com.gluster.storage.management.server.scripts/src/format_device.py @@ -0,0 +1,78 @@ +#!/usr/bin/python +# Copyright (C) 2010 Gluster, Inc. <http://www.gluster.com> +# This file is part of Gluster Storage Platform. +# +# Gluster Storage Platform is free software; you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 3 of +# the License, or (at your option) any later version. +# +# Gluster Storage Platform is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see +# <http://www.gnu.org/licenses/>. + +import os +import sys +import Utils +import DiskUtils +from optparse import OptionParser + + +def main(): + parser = OptionParser() + parser.add_option("-t", "--type", action="store", type="string", dest="fstype") + (options, args) = parser.parse_args() + + if len(args) != 1: + sys.stderr.write("usage: %s [-t FSTYPE] DEVICE_NAME\n" % os.path.basename(sys.argv[0])) + sys.exit(-1) + + device = DiskUtils.getDevice(args[0]) + deviceFormatLockFile = Utils.getDeviceFormatLockFile(device) + deviceFormatStatusFile = Utils.getDeviceFormatStatusFile(device) + deviceFormatOutputFile = Utils.getDeviceFormatOutputFile(device) + + if DiskUtils.isDataDiskPartitionFormatted(device): + sys.stderr.write("Device already formatted\n") + sys.exit(1) + + if os.path.exists(deviceFormatStatusFile): + Utils.log("format status file %s exists" % deviceFormatStatusFile) + try: + fp = open(deviceFormatStatusFile) + line = fp.read() + fp.close() + if line.strip().upper() == "COMPLETED": + sys.stderr.write("Device already formatted\n") + sys.exit(1) + else: + sys.stderr.write("Device format already running\n") + sys.exit(2) + except IOError, e: + Utils.log("failed to read format status file %s: %s" % (deviceFormatStatusFile, str(e))) + sys.stderr.write("%s\n" % str(e)) + sys.exit(-2) + + if os.path.exists(deviceFormatLockFile): + Utils.log("lock file %s exists" % deviceFormatLockFile) + sys.stderr.write("Device format already running\n") + sys.exit(2) + + if options.fstype: + process = Utils.runCommandBG("gluster_provision_block_wrapper.py -t %s %s" % (options.fstype, device), root=True) + else: + process = Utils.runCommandBG("gluster_provision_block_wrapper.py %s" % device, root=True) + if process: + sys.exit(0) + + sys.stderr.write("Device format failed\n") + sys.exit(3) + + +if __name__ == "__main__": + main() diff --git a/src/com.gluster.storage.management.server.scripts/src/get_disk_mount_point.py b/src/com.gluster.storage.management.server.scripts/src/get_disk_mount_point.py index b2274b4d..2f4a39c3 100755 --- a/src/com.gluster.storage.management.server.scripts/src/get_disk_mount_point.py +++ b/src/com.gluster.storage.management.server.scripts/src/get_disk_mount_point.py @@ -17,15 +17,14 @@ # <http://www.gnu.org/licenses/>. import os -import syslog -import Common +import Utils from DiskUtils import * from XmlHandler import ResponseXml def getmountpoint(path): if not path: - Common.log(syslog.LOG_ERR, "Not a valid path:%s" % path) + Utils.log("Not a valid path:%s" % path) rs.appendTagRoute("status.code", "-1") rs.appendTagRoute("status.message", "Error: given path name is empty") return rs.toprettyxml() @@ -41,7 +40,7 @@ def getmountpoint(path): mountPoint = line['MountPoint'] if "/" == mountPoint or not mountPoint: - Common.log(syslog.LOG_ERR, "failed to find mount point of the given path:%s" % path) + Utils.log("failed to find mount point of the given path:%s" % path) rs.appendTagRoute("status.code", "-1") rs.appendTagRoute("status.message", "Error: Unable to find disk mount point") return rs.toprettyxml() @@ -52,7 +51,7 @@ def getmountpoint(path): def main(): if len(sys.argv) != 2: - print >> sys.stderr, "usage: %s <path>" % sys.argv[0] + sys.stderr.write("usage: %s <path>\n" % os.path.basename(sys.argv[0])) sys.exit(-1) path = sys.argv[1] @@ -61,4 +60,3 @@ def main(): if __name__ == "__main__": main() - diff --git a/src/com.gluster.storage.management.server.scripts/src/get_disk_name_by_path.py b/src/com.gluster.storage.management.server.scripts/src/get_disk_name_by_path.py index 72eb80dd..08e80b7e 100755 --- a/src/com.gluster.storage.management.server.scripts/src/get_disk_name_by_path.py +++ b/src/com.gluster.storage.management.server.scripts/src/get_disk_name_by_path.py @@ -17,15 +17,14 @@ # <http://www.gnu.org/licenses/>. import os -import syslog -import Common +import Utils from DiskUtils import * from XmlHandler import ResponseXml def getmountpoint(path): if not path: - Common.log(syslog.LOG_ERR, "Not a valid path:%s" % path) + Utils.log("Not a valid path:%s" % path) rs.appendTagRoute("status.code", "-1") rs.appendTagRoute("status.message", "Error: given path name is empty") return rs.toprettyxml() @@ -43,7 +42,7 @@ def getmountpoint(path): fsTabEntry = line if "/" == mountPoint or not mountPoint: - Common.log(syslog.LOG_ERR, "failed to find mount point of the given path:%s" % path) + Utils.log("failed to find mount point of the given path:%s" % path) rs.appendTagRoute("status.code", "-1") rs.appendTagRoute("status.message", "Error: Unable to find disk mount point") return rs.toprettyxml() @@ -57,7 +56,7 @@ def getmountpoint(path): def main(): if len(sys.argv) != 2: - print >> sys.stderr, "usage: %s <path>" % sys.argv[0] + sys.stderr.write("usage: %s <path>\n" % os.path.basename(sys.argv[0])) sys.exit(-1) path = sys.argv[1] diff --git a/src/com.gluster.storage.management.server.scripts/src/get_file.py b/src/com.gluster.storage.management.server.scripts/src/get_file.py index 826ade6e..61c33eba 100755 --- a/src/com.gluster.storage.management.server.scripts/src/get_file.py +++ b/src/com.gluster.storage.management.server.scripts/src/get_file.py @@ -16,8 +16,6 @@ # <http://www.gnu.org/licenses/>. import Globals -import syslog -import Commands import Utils from VolumeUtils import * from XmlHandler import ResponseXml diff --git a/src/com.gluster.storage.management.server.scripts/src/get_format_device_status.py b/src/com.gluster.storage.management.server.scripts/src/get_format_device_status.py new file mode 100755 index 00000000..9fe2b231 --- /dev/null +++ b/src/com.gluster.storage.management.server.scripts/src/get_format_device_status.py @@ -0,0 +1,119 @@ +#!/usr/bin/python +# Copyright (C) 2009,2010 Gluster, Inc. <http://www.gluster.com> +# This file is part of Gluster Storage Platform. +# +# Gluster Storage Platform is free software; you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 3 of +# the License, or (at your option) any later version. +# +# Gluster Storage Platform is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see +# <http://www.gnu.org/licenses/>. + +import os +import sys +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) + + 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): + try: + fp = open(deviceFormatStatusFile) + line = fp.read() + fp.close() + line = line.strip() + + Utils.removeFile(deviceFormatOutputFile) + Utils.removeFile(deviceFormatStatusFile) + + responseDom = ResponseXml() + responseDom.appendTagRoute("response.device", sys.argv[1]) + responseDom.appendTagRoute("response.completedBlocks", "0") + responseDom.appendTagRoute("response.totalBlocks", "0") + responseDom.appendTagRoute("response.message", line) + if line.upper() == "COMPLETED": + responseDom.appendTagRoute("response.formatStatus", "COMPLETED") + else: + responseDom.appendTagRoute("response.formatStatus", "NOT_RUNNING") + print responseDom.toxml() + sys.exit(0) + except IOError, e: + Utils.log("failed to read format status file %s: %s" % (deviceFormatStatusFile, str(e))) + sys.stderr.write("%s\n" % str(e)) + sys.exit(-2) + + if not os.path.exists(deviceFormatOutputFile): + responseDom = ResponseXml() + responseDom.appendTagRoute("response.device", sys.argv[1]) + responseDom.appendTagRoute("response.completedBlocks", "0") + responseDom.appendTagRoute("response.totalBlocks", "0") + responseDom.appendTagRoute("response.message", None) + responseDom.appendTagRoute("response.formatStatus", "IN_PROGRESS") + print responseDom.toxml() + sys.exit(0) + + try: + fp = open(deviceFormatOutputFile) + content = fp.read() + fp.close() + except IOError, e: + Utils.log("failed to read format output file %s: %s" % (deviceFormatOutputFile, str(e))) + responseDom = ResponseXml() + responseDom.appendTagRoute("response.device", sys.argv[1]) + responseDom.appendTagRoute("response.completedBlocks", "0") + responseDom.appendTagRoute("response.totalBlocks", "0") + responseDom.appendTagRoute("response.message", None) + responseDom.appendTagRoute("response.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("response.device", sys.argv[1]) + responseDom.appendTagRoute("response.completedBlocks", "0") + responseDom.appendTagRoute("response.totalBlocks", "0") + responseDom.appendTagRoute("response.message", content[-1]) + responseDom.appendTagRoute("response.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("response.device", sys.argv[1]) + responseDom.appendTagRoute("response.completedBlocks", values[0]) + responseDom.appendTagRoute("response.totalBlocks", values[1]) + responseDom.appendTagRoute("response.message", lines[-1]) + responseDom.appendTagRoute("response.formatStatus", "IN_PROGRESS") + print responseDom.toxml() + sys.exit(0) + +if __name__ == "__main__": + main() diff --git a/src/com.gluster.storage.management.server.scripts/src/get_rrd_cpu_details.py b/src/com.gluster.storage.management.server.scripts/src/get_rrd_cpu_details.py index a525d531..16670576 100755 --- a/src/com.gluster.storage.management.server.scripts/src/get_rrd_cpu_details.py +++ b/src/com.gluster.storage.management.server.scripts/src/get_rrd_cpu_details.py @@ -17,10 +17,8 @@ # <http://www.gnu.org/licenses/>. import os import sys -import syslog from XmlHandler import ResponseXml import Utils -import Common def getCpuData(period): cpuRrdFile = "/var/lib/rrd/cpu.rrd" @@ -33,12 +31,12 @@ def getCpuData(period): "XPORT:cpusystem:'system'", "XPORT:cpuidle:'idle'"] - rv = Utils.runCommandFG(command, stdout=True, root=True) - message = Common.stripEmptyLines(rv["Stdout"]) + rv = Utils.runCommand(command, output=True, root=True) + message = Utils.stripEmptyLines(rv["Stdout"]) if rv["Stderr"]: - error = Common.stripEmptyLines(rv["Stderr"]) + error = Utils.stripEmptyLines(rv["Stderr"]) message += "Error: [%s]" % (error) - Common.log(syslog.LOG_ERR, "failed to create RRD file for cpu usages %s" % file) + Utils.log("failed to create RRD file for cpu usages %s" % file) rs.appendTagRoute("status.code", rv["Status"]) rs.appendTagRoute("status.message", message) return rs.toxml() @@ -46,7 +44,7 @@ def getCpuData(period): def main(): if len(sys.argv) != 2: - print >> sys.stderr, "usage: %s <period>" % sys.argv[0] + sys.stderr.write("usage: %s <period>\n" % os.path.basename(sys.argv[0])) sys.exit(-1) period = sys.argv[1] diff --git a/src/com.gluster.storage.management.server.scripts/src/get_server_details.py b/src/com.gluster.storage.management.server.scripts/src/get_server_details.py index ce1d97e6..6eb75ca5 100755 --- a/src/com.gluster.storage.management.server.scripts/src/get_server_details.py +++ b/src/com.gluster.storage.management.server.scripts/src/get_server_details.py @@ -17,15 +17,9 @@ # <http://www.gnu.org/licenses/>. import sys -import syslog import socket -import Globals -import Commands import re -import Common import DiskUtils -from ServerUtils import * -from Protocol import * from NetworkUtils import * from Disk import * from XmlHandler import ResponseXml @@ -33,7 +27,6 @@ from optparse import OptionParser def getServerDetails(listall): - serverName = socket.gethostname() meminfo = getMeminfo() cpu = 100 * float(getLoadavg()) @@ -90,17 +83,11 @@ def getServerDetails(listall): responseDom.appendTag(serverTag) serverTag.appendChild(responseDom.createTag("numOfCPUs", int(os.sysconf('SC_NPROCESSORS_ONLN')))) - - # refreshing hal data - DiskUtils.refreshHal() - - diskObj = Disk() - disks = diskObj.getMountableDiskList() - - if disks is None: - print "No disk found!" - syslog.syslog(syslog.LOG_ERR, "Error finding disk information of server:%s" % serverName) - return None + diskDom = DiskUtils.getDiskDom() + if not diskDom: + sys.stderr.write("No disk found!") + Utils.log("Failed to get disk details") + sys.exit(1) serverTag.appendChild(responseDom.createTag("cpuUsage", str(cpu))) serverTag.appendChild(responseDom.createTag("totalMemory", str(convertKbToMb(meminfo['MemTotal'])))) @@ -108,45 +95,11 @@ def getServerDetails(listall): serverTag.appendChild(responseDom.createTag("status", "ONLINE")) serverTag.appendChild(responseDom.createTag("uuid", None)) - totalDiskSpace = 0 - diskSpaceInUse = 0 - diskTag = responseDom.createTag("disks") - for disk in disks: - if not listall: - if not disk['mount_point'].startswith("/export/"): - continue - if disk['interface'] in ['usb', 'mmc']: - continue - partitionTag = responseDom.createTag("disk", None) - partitionTag.appendChild(responseDom.createTag("name", os.path.basename(disk['device']))) - partitionTag.appendChild(responseDom.createTag("mountPoint", disk['mount_point'])) - partitionTag.appendChild(responseDom.createTag("serverName", serverName)) - partitionTag.appendChild(responseDom.createTag("description", disk['description'])) - total, used, free = 0, 0, 0 - if disk['size']: - total, used, free = DiskUtils.getDiskSizeInfo(disk['device']) - if total: - partitionTag.appendChild(responseDom.createTag("space", str(total))) - totalDiskSpace += total - else: - partitionTag.appendChild(responseDom.createTag("space", "NA")) - if used: - partitionTag.appendChild(responseDom.createTag("spaceInUse", str(used))) - diskSpaceInUse += used - partitionTag.appendChild(responseDom.createTag("status", "AVAILABLE")) - else: - partitionTag.appendChild(responseDom.createTag("spaceInUse", "NA")) - partitionTag.appendChild(responseDom.createTag("status", "UNINITIALIZED")) - diskTag.appendChild(partitionTag) - serverTag.appendChild(diskTag) - serverTag.appendChild(responseDom.createTag("totalDiskSpace", str(totalDiskSpace))) - serverTag.appendChild(responseDom.createTag("diskSpaceInUse", str(diskSpaceInUse))) + serverTag.appendChild(diskDom.getElementsByTagRoute("disks")[0]) return serverTag def main(): - ME = os.path.basename(sys.argv[0]) - parser = OptionParser(version="%s %s" % (ME, Globals.GLUSTER_PLATFORM_VERSION)) - + parser = OptionParser() parser.add_option("-N", "--only-data-disks", action="store_false", dest="listall", default=True, help="List only data disks") diff --git a/src/com.gluster.storage.management.server.scripts/src/get_volume_log.py b/src/com.gluster.storage.management.server.scripts/src/get_volume_log.py index 826ade6e..b906c002 100755 --- a/src/com.gluster.storage.management.server.scripts/src/get_volume_log.py +++ b/src/com.gluster.storage.management.server.scripts/src/get_volume_log.py @@ -17,7 +17,6 @@ import Globals import syslog -import Commands import Utils from VolumeUtils import * from XmlHandler import ResponseXml diff --git a/src/com.gluster.storage.management.server.scripts/src/gluster_provision_block_wrapper.py b/src/com.gluster.storage.management.server.scripts/src/gluster_provision_block_wrapper.py new file mode 100755 index 00000000..8c47d958 --- /dev/null +++ b/src/com.gluster.storage.management.server.scripts/src/gluster_provision_block_wrapper.py @@ -0,0 +1,120 @@ +#!/usr/bin/python +# Copyright (C) 2010 Gluster, Inc. <http://www.gluster.com> +# This file is part of Gluster Storage Platform. +# +# Gluster Storage Platform is free software; you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 3 of +# the License, or (at your option) any later version. +# +# Gluster Storage Platform is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see +# <http://www.gnu.org/licenses/>. + +import os +import sys +#import subprocess +import Utils +import DiskUtils +from optparse import OptionParser + +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(): + parser = OptionParser() + parser.add_option("-t", "--type", action="store", type="string", dest="fstype") + (options, args) = parser.parse_args() + + if len(args) != 1: + sys.stderr.write("usage: %s [-t FSTYPE] DEVICE" % os.path.basename(sys.argv[0])) + sys.exit(-1) + + device = args[0] + 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(3) + + 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(4) + + if options.fstype: + command = "gluster-provision-block -t %s %s" % (options.fstype, device) + else: + command = "gluster-provision-block %s" % (device) + + process = Utils.runCommandBG(command, + stdinFileObj=subprocess.PIPE, + stdoutFileObj=fptr, + stderrFileObj=subprocess.PIPE) + if process: + status = process.wait() + else: + Utils.removeFile(deviceFormatOutputFile) + Utils.removeFile(deviceFormatLockFile) + writeStatus(deviceFormatStatusFile, "Device format failed\n") + sys.exit(5) + + ## try: + ## process = subprocess.Popen(command, + ## stdout=fptr, + ## stderr=subprocess.PIPE, + ## stdin=subprocess.PIPE, + ## close_fds=True) + ## status = process.wait() + ## except OSError: + ## os.unlink(deviceFormatOutputFile) + ## Utils.log(syslog.LOG_ERR, "formatting disk command failed. command: %s" % str(command)) + ## writeStatus(deviceFormatStatusFile, "Formatting disk command failed\n") + ## removeLockFile() + ## sys.exit(-5) + + if status != 0: + Utils.removeFile(deviceFormatOutputFile) + Utils.removeFile(deviceFormatLockFile) + writeStatus(deviceFormatStatusFile, "Device format failed\n") + sys.exit(6) + + if Utils.runCommand("/usr/bin/lshal") != 0: + Utils.log("failed running /usr/bin/lshal") + writeStatus(deviceFormatStatusFile, "Completed\n") + Utils.removeFile(deviceFormatOutputFile) + Utils.removeFile(deviceFormatLockFile) + sys.exit(0) + +if __name__ == "__main__": + main() diff --git a/src/com.gluster.storage.management.server.scripts/src/rrd_update_cpu_details.py b/src/com.gluster.storage.management.server.scripts/src/rrd_update_cpu_details.py index 81ca6add..73982971 100755 --- a/src/com.gluster.storage.management.server.scripts/src/rrd_update_cpu_details.py +++ b/src/com.gluster.storage.management.server.scripts/src/rrd_update_cpu_details.py @@ -17,10 +17,8 @@ # <http://www.gnu.org/licenses/>. import os import sys -import syslog from XmlHandler import ResponseXml import Utils -import Common def createMemData(file, step): rs = ResponseXml() @@ -33,12 +31,12 @@ def createMemData(file, step): "RRA:AVERAGE:0.5:24:732", "RRA:AVERAGE:0.5:144:1460"] - rv = Utils.runCommandFG(command, stdout=True, root=True) - message = Common.stripEmptyLines(rv["Stdout"]) + rv = Utils.runCommand(command, output=True, root=True) + message = Utils.stripEmptyLines(rv["Stdout"]) if rv["Stderr"]: - error = Common.stripEmptyLines(rv["Stderr"]) + error = Utils.stripEmptyLines(rv["Stderr"]) message += "Error: [%s]" % (error) - Common.log(syslog.LOG_ERR, "failed to create RRD file for cpu usages %s" % file) + Utils.log("failed to create RRD file for cpu usages %s" % file) rs.appendTagRoute("status.code", rv["Status"]) rs.appendTagRoute("status.message", message) return rs.toxml() @@ -59,18 +57,18 @@ def updateMemData(file): break if None == user: - Common.log(syslog.LOG_ERR, "failed to fetch cpu details from /proc/stat") + Utils.log("failed to fetch cpu details from /proc/stat") rs.appendTagRoute("status.code", "-1") rs.appendTagRoute("status.message", "failed to fetch cpu details") return rs.toxml() command = ["rrdtool", "update", file, "-t", "user:system:idle", "N:%s:%s:%s" % (user, system, idle)] - rv = Utils.runCommandFG(command, stdout=True, root=True) + rv = Utils.runCommand(command, output=True, root=True) if rv["Stderr"]: - error = Common.stripEmptyLines(rv["Stderr"]) + error = Utils.stripEmptyLines(rv["Stderr"]) message = "Error: [%s]" % (error) - Common.log(syslog.LOG_ERR, "failed to update cpu usage into rrd file %s" % file) + Utils.log("failed to update cpu usage into rrd file %s" % file) rs.appendTagRoute("status.code", rv["Status"]) rs.appendTagRoute("status.message", message) return rs.toxml() diff --git a/src/com.gluster.storage.management.server.scripts/src/rrd_update_memory_details.py b/src/com.gluster.storage.management.server.scripts/src/rrd_update_memory_details.py index 23054769..fe4fcce6 100755 --- a/src/com.gluster.storage.management.server.scripts/src/rrd_update_memory_details.py +++ b/src/com.gluster.storage.management.server.scripts/src/rrd_update_memory_details.py @@ -17,10 +17,8 @@ # <http://www.gnu.org/licenses/>. import os import sys -import syslog from XmlHandler import ResponseXml import Utils -import Common def createMemData(file, step): rs = ResponseXml() @@ -35,12 +33,12 @@ def createMemData(file, step): "RRA:AVERAGE:0.5:24:732", "RRA:AVERAGE:0.5:144:1460"] - rv = Utils.runCommandFG(command, stdout=True, root=True) - message = Common.stripEmptyLines(rv["Stdout"]) + rv = Utils.runCommand(command, output=True, root=True) + message = Utils.stripEmptyLines(rv["Stdout"]) if rv["Stderr"]: - error = Common.stripEmptyLines(rv["Stderr"]) + error = Utils.stripEmptyLines(rv["Stderr"]) message += "Error: [%s]" % (error) - Common.log(syslog.LOG_ERR, "failed to create RRD file for memory usages %s" % file) + Utils.log("failed to create RRD file for memory usages %s" % file) rs.appendTagRoute("status.code", rv["Status"]) rs.appendTagRoute("status.message", message) return rs.toxml() @@ -49,11 +47,11 @@ def createMemData(file, step): def updateMemData(file): rs = ResponseXml() command = ["free", "-b", "-o"] - rv = Utils.runCommandFG(command, stdout=True, root=True) + rv = Utils.runCommand(command, output=True, root=True) if rv["Stderr"]: - error = Common.stripEmptyLines(rv["Stderr"]) + error = Utils.stripEmptyLines(rv["Stderr"]) message += "Error: [%s]" % (error) - Common.log(syslog.LOG_ERR, "failed to retrieve memory details") + Utils.log("failed to retrieve memory details") rs.appendTagRoute("status.code", rv["Status"]) rs.appendTagRoute("status.message", message) return rs.toxml() @@ -61,12 +59,11 @@ def updateMemData(file): message = rv["Stdout"].split() command = ["rrdtool", "update", file, "-t", "memused:memfree:memcache:swapused:swapfree", "N:%s:%s:%s:%s:%s" % (message[8], message[9], message[12], message[14], message[15])] - rv = Utils.runCommandFG(command, stdout=True, root=True) + rv = Utils.runCommand(command, output=True, root=True) if rv["Stderr"]: - error = Common.stripEmptyLines(rv["Stderr"]) - print error, command + error = Utils.stripEmptyLines(rv["Stderr"]) message += "Error: [%s]" % (error) - Common.log(syslog.LOG_ERR, "failed to update memory usage into rrd file %s" % file) + Utils.log(syslog.LOG_ERR, "failed to update memory usage into rrd file %s" % file) rs.appendTagRoute("status.code", rv["Status"]) rs.appendTagRoute("status.message", message) return rs.toxml() diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/ServerUtil.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/ServerUtil.java index 2e78b57b..e8073765 100644 --- a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/ServerUtil.java +++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/ServerUtil.java @@ -20,20 +20,17 @@ */ package com.gluster.storage.management.server.utils; -import java.io.BufferedReader; import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.PrintWriter; -import java.net.InetAddress; -import java.net.Socket; +import java.io.ByteArrayOutputStream; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import javax.servlet.ServletContext; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; +import javax.xml.bind.Marshaller; import javax.xml.bind.Unmarshaller; import org.springframework.beans.factory.annotation.Autowired; @@ -44,6 +41,8 @@ import com.gluster.storage.management.core.exceptions.ConnectionException; import com.gluster.storage.management.core.exceptions.GlusterRuntimeException; import com.gluster.storage.management.core.model.Server; import com.gluster.storage.management.core.model.Status; +import com.gluster.storage.management.core.model.VolumeOption; +import com.gluster.storage.management.core.model.VolumeOptions; import com.gluster.storage.management.core.response.GenericResponse; import com.gluster.storage.management.core.utils.ProcessResult; import com.gluster.storage.management.core.utils.ProcessUtil; @@ -86,7 +85,7 @@ public class ServerUtil { */ public void fetchServerDetails(Server server) { // fetch standard server details like cpu, disk, memory details - Object response = executeOnServer(true, server.getName(), "get_server_details.py --only-data-disks", Server.class); + Object response = executeOnServer(true, server.getName(), "get_server_details.py", Server.class); if (response instanceof Status) { throw new GlusterRuntimeException(((Status)response).getMessage()); } @@ -225,10 +224,13 @@ public class ServerUtil { } public static void main(String args[]) throws Exception { - ServerUtil su = new ServerUtil(); - su.setSshUtil(new SshUtil()); - // Object result = new ServerUtil().executeOnServer(true, "serverName", "ls -lrt", String.class); - // System.out.println(result); + //String diskStr = "<server><name>devserver1</name><domainname/><dns1>10.1.10.1</dns1><dns2>8.8.4.4</dns2><networkInterfaces><networkInterface><name>eth0</name><hwAddr>00:50:56:82:00:1d</hwAddr><speed>1000</speed><model>ETHERNET</model><onboot>yes</onboot><bootProto>none</bootProto><ipAddress>10.1.12.41</ipAddress><netMask>255.255.255.0</netMask><defaultGateway>10.1.12.1</defaultGateway></networkInterface></networkInterfaces><numOfCPUs>2</numOfCPUs><cpuUsage>0.0</cpuUsage><totalMemory>2010.5234375</totalMemory><memoryInUse>1267.6015625</memoryInUse><status>ONLINE</status><uuid/><disks><disk><name>sdd</name><description>VMware Virtual disk</description><uuid/><status>UNINITIALIZED</status><init>false</init><type>false</type><interface>pci</interface><fsType/><fsVersion/><mountPoint/><size>10240</size><spaceInUse/><partitions><partition><name>sdd1</name><uuid/><status>UNINITIALIZED</status><init>false</init><type>false</type><interface/><fsType/><mountPoint/><size>10236</size><spaceInUse/></partition></partitions></disk><disk><name>sda</name><description>VMware Virtual disk</description><uuid/><status>UNINITIALIZED</status><init>false</init><type>false</type><interface>pci</interface><fsType/><fsVersion/><mountPoint/><size>10240</size><spaceInUse>2019</spaceInUse><partitions><partition><name>sda1</name><uuid>345d880e-822a-4e46-a518-75cc48b1869f</uuid><status>INITIALIZED</status><init>true</init><type>false</type><interface/><fsType>ext3</fsType><mountPoint>/boot</mountPoint><size>125</size><spaceInUse>11</spaceInUse></partition><partition><name>sda2</name><uuid/><status>UNINITIALIZED</status><init>false</init><type>false</type><interface/><fsType>swap</fsType><mountPoint/><size>125</size><spaceInUse/></partition><partition><name>sda3</name><uuid>f94a0b2a-5ebc-4c13-a618-0328af97a31e</uuid><status>INITIALIZED</status><init>true</init><type>false</type><interface/><fsType>ext3</fsType><mountPoint>/</mountPoint><size>9985</size><spaceInUse>2008</spaceInUse></partition></partitions></disk><disk><name>sdb</name><description>VMware Virtual disk</description><uuid>97ee7ea3-d235-424c-bdda-f5b697f204a2</uuid><status>READY</status><init>true</init><type>true</type><interface>pci</interface><fsType>ext3</fsType><fsVersion>1.0</fsVersion><mountPoint>/export/sdb</mountPoint><size>1024</size><spaceInUse>427</spaceInUse><partitions/></disk><disk><name>sdc</name><description>VMware Virtual disk</description><uuid>87679044-6395-42fb-a80d-41c3b648f248</uuid><status>READY</status><init>true</init><type>true</type><interface>pci</interface><fsType>ext3</fsType><fsVersion>1.0</fsVersion><mountPoint>/export/sdc</mountPoint><size>8192</size><spaceInUse>602</spaceInUse><partitions/></disk></disks></server>"; + String diskStr = "<options><option><key>auth.allow</key><value>*</value></option><option><key>cluster.stripe-block-size</key><value>*:128KB</value></option></options>"; + //diskStr = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><options><option><key>auth.allow</key><value>*</value></option><option><key>cluster.stripe-block-size</key><value>*:128KB</value></option></options>"; + VolumeOptions disk = (VolumeOptions)new ServerUtil().unmarshal(VolumeOptions.class, diskStr, false); + System.out.println(disk.size()); + for(VolumeOption option : disk.getOptions()) { + System.out.println(option.toString()); + } } - } |
