Package rtslib :: Module node
[hide private]
[frames] | no frames]

Source Code for Module rtslib.node

  1  ''' 
  2  Implements the base CFSNode class and a few inherited variants. 
  3   
  4  This file is part of RTSLib. 
  5  Copyright (c) 2011-2013 by Datera, Inc 
  6   
  7  Licensed under the Apache License, Version 2.0 (the "License"); you may 
  8  not use this file except in compliance with the License. You may obtain 
  9  a copy of the License at 
 10   
 11      http://www.apache.org/licenses/LICENSE-2.0 
 12   
 13  Unless required by applicable law or agreed to in writing, software 
 14  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 
 15  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 
 16  License for the specific language governing permissions and limitations 
 17  under the License. 
 18  ''' 
 19   
 20  import os 
 21  import stat 
 22  from utils import fread, fwrite, RTSLibError, RTSLibNotInCFS 
 23   
 24   
25 -class CFSNode(object):
26 27 # Where is the configfs base LIO directory ? 28 configfs_dir = '/sys/kernel/config/target' 29 30 # CFSNode private stuff 31
32 - def __init__(self):
33 self._path = self.configfs_dir
34
35 - def _get_path(self):
36 return self._path
37
38 - def _create_in_cfs_ine(self, mode):
39 ''' 40 Creates the configFS node if it does not already exist, depending on 41 the mode. 42 any -> makes sure it exists, also works if the node already does exist 43 lookup -> make sure it does NOT exist 44 create -> create the node which must not exist beforehand 45 ''' 46 if mode not in ['any', 'lookup', 'create']: 47 raise RTSLibError("Invalid mode: %s" % mode) 48 if self.exists and mode == 'create': 49 raise RTSLibError("This %s already exists in configFS." 50 % self.__class__.__name__) 51 elif not self.exists and mode == 'lookup': 52 raise RTSLibNotInCFS("No such %s in configfs: %s." 53 % (self.__class__.__name__, self.path)) 54 55 if not self.exists: 56 try: 57 os.mkdir(self.path) 58 except: 59 raise RTSLibError("Could not create %s in configFS." 60 % self.__class__.__name__)
61
62 - def _exists(self):
63 return os.path.isdir(self.path)
64
65 - def _check_self(self):
66 if not self.exists: 67 raise RTSLibNotInCFS("This %s does not exist in configFS." 68 % self.__class__.__name__)
69
70 - def _list_files(self, path, writable=None):
71 ''' 72 List files under a path depending on their owner's write permissions. 73 @param path: The path under which the files are expected to be. If the 74 path itself is not a directory, an empty list will be returned. 75 @type path: str 76 @param writable: If None (default), returns all parameters, if True, 77 returns read-write parameters, if False, returns just the read-only 78 parameters. 79 @type writable: bool or None 80 @return: List of file names filtered according to their write perms. 81 ''' 82 if not os.path.isdir(path): 83 return [] 84 85 if writable is None: 86 names = os.listdir(path) 87 elif writable: 88 names = [name for name in os.listdir(path) 89 if (os.stat("%s/%s" % (path, name))[stat.ST_MODE] \ 90 & stat.S_IWUSR)] 91 else: 92 names = [os.path.basename(name) for name in os.listdir(path) 93 if not (os.stat("%s/%s" % (path, name))[stat.ST_MODE] \ 94 & stat.S_IWUSR)] 95 names.sort() 96 return names
97 98 # CFSNode public stuff 99
100 - def list_parameters(self, writable=None):
101 ''' 102 @param writable: If None (default), returns all parameters, if True, 103 returns read-write parameters, if False, returns just the read-only 104 parameters. 105 @type writable: bool or None 106 @return: The list of existing RFC-3720 parameter names. 107 ''' 108 self._check_self() 109 path = "%s/param" % self.path 110 return self._list_files(path, writable)
111
112 - def list_attributes(self, writable=None):
113 ''' 114 @param writable: If None (default), returns all attributes, if True, 115 returns read-write attributes, if False, returns just the read-only 116 attributes. 117 @type writable: bool or None 118 @return: A list of existing attribute names as strings. 119 ''' 120 self._check_self() 121 path = "%s/attrib" % self.path 122 return self._list_files(path, writable)
123
124 - def set_attribute(self, attribute, value):
125 ''' 126 Sets the value of a named attribute. 127 The attribute must exist in configFS. 128 @param attribute: The attribute's name. It is case-sensitive. 129 @type attribute: string 130 @param value: The attribute's value. 131 @type value: string 132 ''' 133 self._check_self() 134 path = "%s/attrib/%s" % (self.path, str(attribute)) 135 if not os.path.isfile(path): 136 raise RTSLibError("Cannot find attribute: %s." 137 % str(attribute)) 138 else: 139 try: 140 fwrite(path, "%s" % str(value)) 141 except Exception as e: 142 raise RTSLibError("Cannot set attribute %s: %s" % (attribute, e))
143
144 - def get_attribute(self, attribute):
145 ''' 146 @param attribute: The attribute's name. It is case-sensitive. 147 @return: The named attribute's value, as a string. 148 ''' 149 self._check_self() 150 path = "%s/attrib/%s" % (self.path, str(attribute)) 151 if not os.path.isfile(path): 152 raise RTSLibError("Cannot find attribute: %s." 153 % str(attribute)) 154 else: 155 return fread(path)
156
157 - def set_parameter(self, parameter, value):
158 ''' 159 Sets the value of a named RFC-3720 parameter. 160 The parameter must exist in configFS. 161 @param parameter: The RFC-3720 parameter's name. It is case-sensitive. 162 @type parameter: string 163 @param value: The parameter's value. 164 @type value: string 165 ''' 166 self._check_self() 167 path = "%s/param/%s" % (self.path, str(parameter)) 168 if not os.path.isfile(path): 169 raise RTSLibError("Cannot find parameter: %s." 170 % str(parameter)) 171 else: 172 try: 173 fwrite(path, "%s\n" % str(value)) 174 except Exception as e: 175 raise RTSLibError("Cannot set attribute %s: %s" % (attribute, e))
176
177 - def get_parameter(self, parameter):
178 ''' 179 @param parameter: The RFC-3720 parameter's name. It is case-sensitive. 180 @type parameter: string 181 @return: The named parameter value as a string. 182 ''' 183 self._check_self() 184 path = "%s/param/%s" % (self.path, str(parameter)) 185 if not os.path.isfile(path): 186 raise RTSLibError("Cannot find RFC-3720 parameter: %s." 187 % str(parameter)) 188 else: 189 return fread(path)
190
191 - def delete(self):
192 ''' 193 If the underlying configFS object does not exist, this method does 194 nothing. If the underlying configFS object exists, this method attempts 195 to delete it. 196 ''' 197 if self.exists: 198 os.rmdir(self.path)
199 200 path = property(_get_path, 201 doc="Get the configFS object path.") 202 exists = property(_exists, 203 doc="Is True as long as the underlying configFS object exists. " \ 204 + "If the underlying configFS objects gets deleted " \ 205 + "either by calling the delete() method, or by any " \ 206 + "other means, it will be False.") 207
208 - def dump(self):
209 d = {} 210 attrs = {} 211 params = {} 212 for item in self.list_attributes(writable=True): 213 attrs[item] = int(self.get_attribute(item)) 214 if attrs: 215 d['attributes'] = attrs 216 for item in self.list_parameters(writable=True): 217 params[item] = self.get_parameter(item) 218 if params: 219 d['parameters'] = params 220 return d
221
222 -def _test():
223 import doctest 224 doctest.testmod()
225 226 if __name__ == "__main__": 227 _test() 228