- Timestamp:
- 04/15/09 14:36:04 (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/pxeconfig.in
r137 r139 1 # !@PYTHON@1 ##!@PYTHON@ 2 2 # 3 3 # set ts=4, sw=4 … … 5 5 # Author: Bas van der Vlies <basv@sara.nl> 6 6 # Date : 16 February 2002 7 #8 # Tester: Walter de Jong <walter@sara.nl>9 7 # 10 8 # SVN info … … 29 27 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA 30 28 # 31 """ 32 Usage: pxeconfig [-f,--filename <name>] <hosts> 29 import sys 30 import pxeconfig 33 31 34 Specifying hostnames:35 To specify a range use the [] to indicate a range,36 a couple of examples herebelow.37 38 The first five nodes of rack 1639 - gb-r16n[1-5]40 41 The first five nodes and node 12 and 18 of rack 16 to 2042 - gb-r[16-20]n[1-5,12,18]43 44 The first five nodes de in rack 16 with padding enabled45 - gb-r[16]n[01-5]46 47 The ranges ([]) are not only limited to numbers, letters can also be used.48 49 With this program you can configure which PXE configuration file a node50 will use when it boots.51 52 See following link for usage and examples:53 - https://subtrac.sara.nl/oss/pxeconfig/wiki/PxeUsage54 """55 56 import string57 import sys58 import os59 import glob60 import getopt61 import socket62 import ConfigParser63 import re64 65 # import from the sara_python_modules66 from sara import AdvancedParser67 68 # Constants69 #70 PXE_CONF_DIR = '/tftpboot/pxelinux.cfg'71 NETWORK = 'network'72 START = 'start'73 END = 'end'74 VERSION = '3.0.0'75 76 class PxeConfig(Exception):77 def __init__(self, msg=''):78 self.msg = msg79 Exception.__init__(self, msg)80 81 def __repr__(self):82 return self.msg83 84 def ReadConfig(file):85 """86 Parse the config file87 """88 if not os.path.isfile(file):89 error = 'File %s does not exist' %file90 raise PxeConfig, error91 92 config = ConfigParser.RawConfigParser()93 try:94 config.read(file)95 except ConfigParser.MissingSectionHeaderError,detail:96 raise PxeConfig, detail97 98 # Not yet uses99 #100 #projects = {}101 #for section in config.sections():102 # projects[section] = {}103 # for option in config.options(section):104 # projects[section][option] = config.get(section, option)105 106 stanza = config.defaults()107 return stanza108 109 def select_pxe_configfile():110 """111 Let user choose which pxeconfig file to use.112 """113 114 os.chdir(PXE_CONF_DIR)115 116 # Try to determine to which file the default symlink points, and117 # if it exists, remove it from the list.118 #119 try:120 default_file = os.readlink('default')121 except OSError:122 default_file = None123 pass124 125 files = glob.glob('default.*')126 if not files:127 error = 'There are no pxe config files starting with: default.'128 raise PxeConfig, error129 130 if default_file:131 files.remove(default_file)132 133 # sort the files134 #135 files.sort()136 137 print 'Which pxe config file must we use: ?'138 i = 1139 for file in files:140 print "%d : %s" %(i,file)141 i = i + 1142 143 while 1:144 index = raw_input('Select a number: ')145 try:146 index = int(index)147 except ValueError:148 index = len(files) + 1149 150 # Is the user smart enough to select151 # the right value??152 #153 if 0 < index <= len(files):154 break155 156 return files[index-1]157 158 def manage_links(haddr, options):159 """160 Create the links in the PXE_CONF_DIR,161 list : A list containing: network hex address, pxe config file,162 start number, end number163 """164 if options.VERBOSE:165 print 'manage_links(%s)' %(haddr)166 167 os.chdir(PXE_CONF_DIR)168 pxe_filename = options.filename169 170 if options.REMOVE:171 if options.DEBUG or options.DRY_RUN or options.VERBOSE:172 print 'removing %s/%s' %(PXE_CONF_DIR, haddr)173 174 if os.path.exists(haddr) and not options.DRY_RUN:175 os.unlink(haddr)176 177 else:178 if options.DEBUG or options.DRY_RUN or options.VERBOSE:179 print 'linking %s to %s' %(haddr, pxe_filename)180 181 if not options.DRY_RUN:182 if os.path.exists(haddr):183 os.unlink(haddr)184 os.symlink(pxe_filename, haddr)185 186 def net_2_hex(net, options):187 """188 This function checks if the give network is a Class C-network and will189 convert the network address to a hex address if true.190 """191 if options.DEBUG:192 str = 'net_2_hex : %s' %(net)193 print str194 195 d = string.split(net, '.')196 if len(d) != 3:197 error = '%s is not a valid C-class network address' %(net)198 raise PxeConfig, error199 200 # Check if we have valid network values201 r = ''202 for i in d:203 r = '%s%02X' %(r, int(i))204 205 if options.DEBUG:206 print 'C-network converted to hex: ', r207 208 return r209 210 def hosts_2_hex(hosts, options):211 """212 Convert hostname(s) to a net address that can be handled by manage_links function213 """214 if options.DEBUG:215 str = 'host_2_hex: %s' %hosts216 print str217 218 for host in hosts:219 try:220 addr = socket.gethostbyname(host)221 except socket.error,detail:222 error = '%s not an valid hostname: %s' %(host,detail)223 raise PxeConfig, error224 225 net = string.splitfields(addr, '.')226 cnet = string.joinfields(net[0:3], '.')227 228 haddr = '%s%02X' %(net_2_hex(cnet, options), int(net[3]))229 230 manage_links(haddr, options)231 232 233 def add_options(p):234 """235 add the default options236 """237 p.set_defaults(238 DEBUG = False,239 VERBOSE = False,240 DRY_RUN = False,241 REMOVE = False,242 VERSION = False,243 )244 245 p.add_option('-d', '--debug',246 action = 'store_true',247 dest = 'DEBUG',248 help = 'Toggle debug mode (default : False)'249 )250 251 p.add_option('-f', '--filename',252 action = 'store',253 dest = 'filename',254 help = 'Specifies which PXE filename must be use'255 )256 257 p.add_option('-n', '--dry-run',258 action = 'store_true',259 dest = 'DRY_RUN',260 help = 'Do not execute any command'261 )262 263 p.add_option('-r', '--remove',264 action = 'store_true',265 dest = 'REMOVE',266 help = 'Removes the PXE filename for a host(s)'267 )268 269 p.add_option('-v', '--verbose',270 action = 'store_true',271 dest = 'VERBOSE',272 help = 'Make the program more verbose (default: False)'273 )274 275 p.add_option('-V', '--version',276 action = 'store_true',277 dest = 'VERSION',278 help = 'Print the program version number and exit'279 )280 281 def parser(argv, settings):282 """283 Make use of sara advance parser module. It can handle regex in hostnames284 """285 parser = AdvancedParser.AdvancedParser(usage=__doc__)286 add_options(parser)287 288 options, args = parser.parse_args()289 290 if not args:291 print __doc__292 sys.exit(0)293 294 if options.VERSION:295 print VERSION296 sys.exit(0)297 298 # debug can be specified by the command line or options file299 #300 if not options.DEBUG:301 try:302 if settings['debug']:303 options.DEBUG = int(settings['debug'])304 except KeyError:305 pass306 307 if options.filename:308 if not os.path.isfile(os.path.join(PXE_CONF_DIR, options.filename)):309 error = '%s: Filename does not exists' %(options.filename)310 raise PxeConfig, error311 else:312 options.filename = select_pxe_configfile()313 314 if options.DEBUG:315 print args, options316 317 hosts_2_hex(args, options)318 319 320 def main():321 # A dictionary holding the boot info322 #323 global PXE_CONF_DIR324 325 configfile = '@pxeconfig_conf@'326 settings = ReadConfig(configfile)327 328 try:329 PXE_CONF_DIR = settings['pxe_config_dir']330 331 except KeyError:332 pass333 334 PXE_CONF_DIR = os.path.realpath(PXE_CONF_DIR)335 if not os.path.isdir(PXE_CONF_DIR):336 error = 'pxeconfig directory: %s does not exists' %(PXE_CONF_DIR)337 raise PxeConfig, error338 339 parser(sys.argv, settings)340 341 342 32 if __name__ == '__main__': 343 33 try: 344 main()345 except PxeConfig, detail:34 pxeconfig.main() 35 except pxeconfig.PxeConfig, detail: 346 36 print detail 347 37 sys.exit(1)
Note: See TracChangeset
for help on using the changeset viewer.