| 1 | # ---------------------------------------------------------------------- |
|---|
| 2 | # Copyright (c) 2006, 2007,2008 dCache.ORG (R) |
|---|
| 3 | # (All rights reversed) |
|---|
| 4 | # |
|---|
| 5 | # This program is free software; you can redistribute it and/or |
|---|
| 6 | # modify it under the terms of version 2 of the GNU General Public |
|---|
| 7 | # License published by the Free Software Foundation. |
|---|
| 8 | # |
|---|
| 9 | # This program is distributed in the hope that it will be useful, |
|---|
| 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 12 | # GNU General Public License for more details. |
|---|
| 13 | # |
|---|
| 14 | # You should have received a copy of the GNU General Public License |
|---|
| 15 | # along with this program; if not, contact Novell, Inc. |
|---|
| 16 | # ---------------------------------------------------------------------- |
|---|
| 17 | # |
|---|
| 18 | from org.pcells.services.connection import * |
|---|
| 19 | from dmg.protocols.ssh import * |
|---|
| 20 | from dmg.cells.nucleus import NoRouteToCellException |
|---|
| 21 | from java.lang import System |
|---|
| 22 | from java.io import File |
|---|
| 23 | from java.io import FileNotFoundException |
|---|
| 24 | import string |
|---|
| 25 | import sys |
|---|
| 26 | import re |
|---|
| 27 | import thread |
|---|
| 28 | |
|---|
| 29 | class OurDomainEventListener( DomainEventListener ) : |
|---|
| 30 | |
|---|
| 31 | def connectionOpened( self , connection ) : |
|---|
| 32 | # |
|---|
| 33 | # As soon as we are connected we query the PoolManager |
|---|
| 34 | # for all currently active pools. |
|---|
| 35 | # |
|---|
| 36 | connection.sendObject( \ |
|---|
| 37 | "PoolManager" , \ |
|---|
| 38 | "psu ls -l pgroup" , \ |
|---|
| 39 | ourMessageListener , \ |
|---|
| 40 | 98 ) ; |
|---|
| 41 | |
|---|
| 42 | def connectionClosed( self , connection ) : |
|---|
| 43 | print "Connection closed" |
|---|
| 44 | |
|---|
| 45 | def connectionOutOfBand( self , connection , subject ) : |
|---|
| 46 | print "Connection out of band" |
|---|
| 47 | |
|---|
| 48 | class Pool : |
|---|
| 49 | |
|---|
| 50 | global poolGroupMapping |
|---|
| 51 | def __init__( self , poolName ) : |
|---|
| 52 | |
|---|
| 53 | self.poolName = poolName |
|---|
| 54 | self.paras = {} |
|---|
| 55 | self.isOk = 0 |
|---|
| 56 | self.isDefined = 0 |
|---|
| 57 | |
|---|
| 58 | |
|---|
| 59 | def addProperties( self , poolString ) : |
|---|
| 60 | self.poolString = poolString |
|---|
| 61 | if isinstance( poolString , NoRouteToCellException ) : |
|---|
| 62 | self.isOk = 0 |
|---|
| 63 | else : |
|---|
| 64 | self.isOk = 1 |
|---|
| 65 | for i in string.split(poolString,"\n") : |
|---|
| 66 | y = string.split(i) |
|---|
| 67 | if ( len(y) > 3 ) : self.paras[y[0]] = y[3] |
|---|
| 68 | elif ( len(y) > 2 ) : self.paras[y[0]] = y[2] |
|---|
| 69 | |
|---|
| 70 | def details( self ) : |
|---|
| 71 | |
|---|
| 72 | if self.isOk : |
|---|
| 73 | if self.paras["LargeFileStore"] == "Precious" : |
|---|
| 74 | rc = "No-HSM" |
|---|
| 75 | else : |
|---|
| 76 | rc = "HSM" |
|---|
| 77 | |
|---|
| 78 | regexp = re.compile( r"\[(?P<usedSpace>.*)\]" ) |
|---|
| 79 | used = regexp.search(self.paras["Used"]) |
|---|
| 80 | usedSpace = string.atof(used.group("usedSpace")) |
|---|
| 81 | |
|---|
| 82 | #return "%-20s %-10s %20f %s"%(self.poolName,rc,usedSpace,poolGroupMapping.get(self.poolName)) |
|---|
| 83 | return "%-20s %-10s %20f"%(self.poolName,rc,usedSpace) |
|---|
| 84 | else : |
|---|
| 85 | return "%-20s %10s"%(self.poolName,"Cell Not Found") |
|---|
| 86 | |
|---|
| 87 | |
|---|
| 88 | def __cmp__( self , otherObj ) : |
|---|
| 89 | if otherObj == None : return -1 |
|---|
| 90 | if self.poolName < otherObj.poolName : return -1 |
|---|
| 91 | elif self.poolName > otherObj.poolName : return 1 |
|---|
| 92 | return 0 |
|---|
| 93 | |
|---|
| 94 | |
|---|
| 95 | class PoolGroupContainer : |
|---|
| 96 | |
|---|
| 97 | |
|---|
| 98 | def __init__( self , initString ) : |
|---|
| 99 | self.poolGroups = {} |
|---|
| 100 | state = 0 |
|---|
| 101 | for line in string.split(initString,"\n") : |
|---|
| 102 | if string.strip(line) == "" : continue |
|---|
| 103 | splittedLine = string.split(line) |
|---|
| 104 | if state == 0 : |
|---|
| 105 | groupName = splittedLine[0] |
|---|
| 106 | dir = [] |
|---|
| 107 | dir.append( groupName ) |
|---|
| 108 | dir.append( [] ) |
|---|
| 109 | dir.append( [] ) |
|---|
| 110 | self.poolGroups[groupName] = dir |
|---|
| 111 | state = 1 |
|---|
| 112 | elif state == 1 : |
|---|
| 113 | state = 2 |
|---|
| 114 | elif state == 2 : |
|---|
| 115 | if splittedLine[0] == "poolList" : |
|---|
| 116 | state = 3 |
|---|
| 117 | else : |
|---|
| 118 | self.poolGroups[groupName][1].append(splittedLine[0]) |
|---|
| 119 | elif state == 3 : |
|---|
| 120 | if len(splittedLine) == 1 : |
|---|
| 121 | groupName = splittedLine[0] |
|---|
| 122 | dir = [] |
|---|
| 123 | dir.append( groupName ) |
|---|
| 124 | dir.append( [] ) |
|---|
| 125 | dir.append( [] ) |
|---|
| 126 | self.poolGroups[groupName] = dir |
|---|
| 127 | state = 1 |
|---|
| 128 | else : |
|---|
| 129 | self.poolGroups[groupName][2].append(splittedLine[0]) |
|---|
| 130 | self.reshuffle() |
|---|
| 131 | |
|---|
| 132 | def reshuffle( self ) : |
|---|
| 133 | self.pools = {} |
|---|
| 134 | for x in self.poolGroups.values() : |
|---|
| 135 | poolGroup = x[0] |
|---|
| 136 | for pool in x[2] : |
|---|
| 137 | if self.pools.get(pool) == None : self.pools[pool] = [] |
|---|
| 138 | self.pools[pool].append(poolGroup) |
|---|
| 139 | |
|---|
| 140 | def get( self , poolName ) : |
|---|
| 141 | return self.pools.get( poolName , "" ) |
|---|
| 142 | |
|---|
| 143 | def details(self) : |
|---|
| 144 | print self.poolGroups |
|---|
| 145 | print "--------------" |
|---|
| 146 | print self.pools |
|---|
| 147 | |
|---|
| 148 | class OurDomainConnectionListener( DomainConnectionListener ) : |
|---|
| 149 | |
|---|
| 150 | # |
|---|
| 151 | # this class only has one object in the application which |
|---|
| 152 | # is used whenever data arrives from the channel. |
|---|
| 153 | # |
|---|
| 154 | global poolGroupMapping |
|---|
| 155 | def __init__( self ) : |
|---|
| 156 | self.expectedReplies = 0 |
|---|
| 157 | self.repliesArrived = 0 |
|---|
| 158 | self.listOfPools = {} |
|---|
| 159 | self.mapping = {} |
|---|
| 160 | self.poolGroups = None |
|---|
| 161 | |
|---|
| 162 | def domainAnswerArrived( self , obj , id ) : |
|---|
| 163 | |
|---|
| 164 | if id == 98 : |
|---|
| 165 | poolGroupMapping = PoolGroupContainer( obj ) |
|---|
| 166 | #self.poolGroups = PoolGroupContainer( obj ) |
|---|
| 167 | |
|---|
| 168 | connection.sendObject( \ |
|---|
| 169 | "PoolManager" , \ |
|---|
| 170 | "psu ls pool" , \ |
|---|
| 171 | ourMessageListener , \ |
|---|
| 172 | 99 ) ; |
|---|
| 173 | elif id == 99 : |
|---|
| 174 | # |
|---|
| 175 | # this is the list of defined pools. |
|---|
| 176 | # Subsequently ask for the active ones. |
|---|
| 177 | # |
|---|
| 178 | defPoolList = string.split( obj , "\n" ) ; |
|---|
| 179 | for poolName in defPoolList : |
|---|
| 180 | if string.strip(poolName) == "" : continue |
|---|
| 181 | definedPool = Pool( poolName ) |
|---|
| 182 | definedPool.isDefined = 1 |
|---|
| 183 | self.listOfPools[poolName] = definedPool |
|---|
| 184 | |
|---|
| 185 | connection.sendObject( \ |
|---|
| 186 | "PoolManager" , \ |
|---|
| 187 | "xgetcellinfo" , \ |
|---|
| 188 | ourMessageListener , \ |
|---|
| 189 | 100 ) ; |
|---|
| 190 | |
|---|
| 191 | elif id == 100 : |
|---|
| 192 | # |
|---|
| 193 | # this is the list of actie pools. |
|---|
| 194 | # as soon as we know how many pools we expect |
|---|
| 195 | # we start the pool reply counter. |
|---|
| 196 | # |
|---|
| 197 | regexp = re.compile( r".*\[(?P<poolList>.*)\].*" ) |
|---|
| 198 | pools = regexp.search(obj.toString()) |
|---|
| 199 | if pools == None : |
|---|
| 200 | print "Syntax error in return : "+obj |
|---|
| 201 | return |
|---|
| 202 | |
|---|
| 203 | poolList = string.split( pools.group("poolList") , "," ) ; |
|---|
| 204 | poolList = poolList[:-1] |
|---|
| 205 | self.expectedReplies=len(poolList) |
|---|
| 206 | |
|---|
| 207 | poolCounter = 0 |
|---|
| 208 | for poolName in poolList : |
|---|
| 209 | poolCounter = poolCounter + 1 |
|---|
| 210 | self.mapping[poolCounter]=poolName |
|---|
| 211 | connection.sendObject( poolName , "info" , ourMessageListener , 1000+poolCounter ) |
|---|
| 212 | |
|---|
| 213 | else : |
|---|
| 214 | |
|---|
| 215 | # |
|---|
| 216 | # get the pool name from our 'id' to name mapping |
|---|
| 217 | # |
|---|
| 218 | self.repliesArrived = self.repliesArrived + 1 |
|---|
| 219 | poolName = self.mapping[id-1000] |
|---|
| 220 | # |
|---|
| 221 | # get the pool object from theour listOfPools |
|---|
| 222 | # |
|---|
| 223 | internalPool = self.listOfPools[poolName] |
|---|
| 224 | # |
|---|
| 225 | # if not found, create a new one |
|---|
| 226 | # |
|---|
| 227 | if internalPool == None : internalPool = Pool( poolName ) |
|---|
| 228 | # |
|---|
| 229 | # add the properties |
|---|
| 230 | # |
|---|
| 231 | internalPool.addProperties( obj ) |
|---|
| 232 | # |
|---|
| 233 | # continue unless we got all replies |
|---|
| 234 | # |
|---|
| 235 | if self.expectedReplies == self.repliesArrived : |
|---|
| 236 | sortedList = self.listOfPools.values() |
|---|
| 237 | sortedList.sort() |
|---|
| 238 | for pool in sortedList : |
|---|
| 239 | print pool.details() |
|---|
| 240 | |
|---|
| 241 | System.exit(0) |
|---|
| 242 | |
|---|
| 243 | #---------------------------------------------------------------------- |
|---|
| 244 | # |
|---|
| 245 | # Main Routine |
|---|
| 246 | # |
|---|
| 247 | #---------------------------------------------------------------------- |
|---|
| 248 | # |
|---|
| 249 | if len(sys.argv) < 5 : |
|---|
| 250 | print "Usage : ... <hostname> <portNumber> <userName> <passwd>" |
|---|
| 251 | System.exit(4) |
|---|
| 252 | # |
|---|
| 253 | # Define the ListenerObject for all incoming message |
|---|
| 254 | # |
|---|
| 255 | ourMessageListener = OurDomainConnectionListener() |
|---|
| 256 | poolGroupMapping = None |
|---|
| 257 | # |
|---|
| 258 | # Define Host and portnumber |
|---|
| 259 | # |
|---|
| 260 | connection=Ssh1DomainConnection(sys.argv[1],int(sys.argv[2])) |
|---|
| 261 | connection.setLoginName(sys.argv[3]) |
|---|
| 262 | # |
|---|
| 263 | # Establish the secret : either password or identity file |
|---|
| 264 | # |
|---|
| 265 | secret=sys.argv[4] |
|---|
| 266 | if secret[0] == "/" : |
|---|
| 267 | connection.setPassword("") |
|---|
| 268 | try : |
|---|
| 269 | connection.setIdentityFile( File(secret) ) |
|---|
| 270 | except FileNotFoundException, e : |
|---|
| 271 | print "Authentication Failed ...",e.getMessage() |
|---|
| 272 | System.exit(1) |
|---|
| 273 | else : |
|---|
| 274 | connection.setPassword(secret) |
|---|
| 275 | |
|---|
| 276 | connection.addDomainEventListener( OurDomainEventListener() ) |
|---|
| 277 | # |
|---|
| 278 | # and now go |
|---|
| 279 | # |
|---|
| 280 | try : |
|---|
| 281 | connection.go() |
|---|
| 282 | except SshAuthenticationException, e : |
|---|
| 283 | print "Authentication Failed ...",e.getMessage() |
|---|
| 284 | System.exit(1) |
|---|
| 285 | |
|---|