source: trunk/pxeconfig/pxeconfig @ 20

Last change on this file since 20 was 20, checked in by sscpbas, 22 years ago

pxeconfig:

Changed some text and removed some obselete code.

File size: 6.5 KB
RevLine 
[2]1#!/usr/bin/env python
2#
3# Author: Bas van der Vlies <basv@sara.nl>
4# Date  : 16 February 2002
5#
6# Tester: Walter de Jong <walter@sara.nl>
7#
8# CVS info
[20]9#  $Date: 2002/09/30 09:22:02 $
10#  $Revision: 1.11 $
[2]11#
[14]12# Copyright (C) 2002
[6]13#
[14]14# This file is part of the pxeconfig utils
[6]15#
[14]16# This program is free software; you can redistribute it and/or modify it
17# under the terms of the GNU General Public License as published by the
18# Free Software Foundation; either version 2, or (at your option) any
19# later version.
[6]20#
[14]21# This program is distributed in the hope that it will be useful,
22# but WITHOUT ANY WARRANTY; without even the implied warranty of
23# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24# GNU General Public License for more details.
[6]25#
[14]26# You should have received a copy of the GNU General Public License
27# along with this program; if not, write to the Free Software
28# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
29#
[2]30"""
[19]31Usage: pxeconfig
32 [-d|--directory <pxe_config_dir>]
33 [-n|--net <C-net> -s|--start <number> -e|--end <number> -f|--file <filename>]
[10]34
[19]35With this program you can configure which PXE configuration file a node
36will use when it boots. The program can be started interactivly or via
37command line options.
38
39When this program is started interactive it will ask the following questions:
[2]40  1) Network address (Class C-network address only)
[9]41  2) Starting number
[2]42  3) Ending number
[9]43  4) Which PXE config file to use
[2]44
45For example, if the answers are:
46  1) 10.168.44
47  2) 2
48  3) 4
49  4) default.node_install
50
51Then the result is that is create symbolic links in /tftpboot/pxelinux.cfg:
52  0AA82C02 ----> default.node_install
53  0AA82C03 ----> default.node_install
54  0AA82C04 ----> default.node_install
55"""
56
57import string
58import sys
59import os
60import glob
[3]61import getopt
[2]62
63# DEBUG
64#
65DEBUG=0
66
67# Constants
68#
[4]69PXE_CONF_DIR='/tftpboot/pxelinux.cfg'
[19]70NETWORK='network'
71FILENAME='filename'
72START='start'
73END='end'
[2]74
[20]75SHORTOPT_LIST='hd:n:s:e:f:'
76LONGOPT_LIST=['help', 'directory=', 'net=', 'start=', 'end=', 'file=']
[19]77
78def select_pxe_configfile():
[2]79  """
[9]80  Let user choose which pxeconfig file to use.
[2]81  """
82
[4]83  os.chdir(PXE_CONF_DIR)
[2]84
[9]85  # Try to determine to which file the default symlink points, and
86  # if it exists, remove it from the list.
[2]87  #
88  try:
89    default_file = os.readlink('default')
90  except OSError:
91    default_file = None
92    pass
93
94  files = glob.glob('default.*')
95  if not files:
96    print 'There are no pxe config files starting with: default.'
97    sys.exit(1)
98
99  if default_file:
100    files.remove(default_file)
101 
102
103  print 'Which pxe config file must we use: ?' 
104  i = 1   
105  for file in files:
106    print "%d : %s" %(i,file)
107    i = i +1
108
109  while 1:
[16]110    index = raw_input('Select a number: ')
[2]111    try:
112      index = int(index)
113    except ValueError:
114      index = len(files) + 1
115
116    # Is the user smart enough to select
[9]117    # the right value??
[2]118    #
119    if 0 < index <= len(files): break
120
121  return files[index-1]
122
[19]123def create_links(dict):
[2]124  """
[4]125  Create the links in the PXE_CONF_DIR,
[9]126    list : A list containing: network hex address, pxe config file,
[2]127           start number, end number
128  """
[4]129  os.chdir(PXE_CONF_DIR)
[19]130  naddr = dict[NETWORK]
131  pxe_filename = dict[FILENAME]
132  for i in range(dict[START], dict[END]+1):
[2]133    haddr = '%s%02X' %(naddr, i)
134    if DEBUG:
135      print 'linking %s to %s' %(haddr, pxe_filename)
[15]136
137    if os.path.exists(haddr):
138       os.unlink(haddr)
139
[2]140    os.symlink(pxe_filename, haddr)
141
142
[19]143def check_network(net, prefix=''):
[2]144  """
[9]145  This function checks if the give network is a Class C-network and will
[2]146  convert the network address to a hex address if true.
147  """
148  d = string.split(net, '.')
149
150  if len(d) != 3:
[19]151    if prefix:
152      net = prefix + ' : ' + net
153     
154    print '%s is not a valid  C-class network address!!!' %net
[2]155    sys.exit(1)
156
[19]157
158  # Display right message for interactive/commandline
159  if prefix:
160    prefix = prefix + ' ' + net
161  else:
162    prefix = net
163
[2]164  # Check if we have valid network values
165  r = ''
166  for i in d:
[19]167    i = check_number(i, prefix)
[2]168    r = '%s%02X' %(r,i)
169
170  if DEBUG:
171    print r
172
173  return r
174
[19]175def check_number(number, prefix=''):
[2]176  """
177  This functions checks if the input is between 0 < number < 255:
178     number : is a string
[19]179     prefix ; a string that must be displayed if an error occurs
[2]180  """
181  try:
182    n = int(number)
183  except ValueError, detail:
[19]184    print prefix,detail
[2]185    sys.exit(1)
186
187  if 0 <= n <= 255:
188    return n
189  else:
[19]190
191    if prefix:
192      number = prefix +' : ' + number
193
[2]194    print '%s is not a valid number, must be between 0 and 255' %number
195    sys.exit(1)
196
[19]197def interactive(binfo):
[2]198
199  print __doc__
200
[9]201  network = raw_input('Give network address (xxx.xxx.xxx): ') 
[2]202  naddr = check_network(network)
203
204  start = raw_input('Starting number: ') 
205  start = check_number(start)
206
207  end = raw_input('Ending number: ') 
208  end = check_number(end)
209
[19]210  pxe_filename = select_pxe_configfile()
[2]211
[19]212  binfo[NETWORK] = naddr
213  binfo[START] = int(start)
214  binfo[END] = int(end)
215  binfo[FILENAME] = pxe_filename
[2]216
[19]217  if DEBUG:
218    print network, binfo
[2]219
[19]220def check_cmd_line(binfo):
221  if len(binfo.keys()) != 4:
222    print __doc__
[20]223    print 'Not enough arguments to create the links!!'
[19]224    sys.exit(1)
[6]225
[19]226  # check_filename
227  #
228  if not os.path.isfile(os.path.join(PXE_CONF_DIR, binfo[FILENAME])):
229    print '%s: Filename does not exists' %binfo[FILENAME]
230    sys.exit(1)
231
232def check_args(argv, binfo):
[3]233  """
[20]234  This function parses the command line options:
235    argv : a list of command line options.
236    binfo: returning a dict with the netinfo. if used non-interactively
[3]237  """
[4]238  global PXE_CONF_DIR
[19]239
[3]240  try:
241    opts, args = getopt.getopt(argv[1:], SHORTOPT_LIST, LONGOPT_LIST)
242  except getopt.error, detail:
[20]243    print __doc__
[3]244    print detail
245    sys.exit(1)
246
[19]247  # Check given options
248  #
249  for opt,value in opts:
250    if opt in ['-d', '--directory']:
251      if os.path.isdir(value):
252        PXE_CONF_DIR = value
253      else:
254        print 'Directory %s does not exists\n' %value
255        sys.exit(1)
[3]256
[19]257    elif opt in ['-n', '--net']:
258      network = value
259      binfo[NETWORK] = check_network(value, opt)
[4]260
[19]261    elif opt in ['-s', '--start']:
262      binfo[START] = check_number(value, opt)
263
264    elif opt in ['-e', '--end']:
265      binfo[END] = check_number(value, opt)
266
267    elif opt in ['-f', '--file']:
268      binfo[FILENAME] = value
269
[20]270    elif opt in ['-h', '--help']:
271      print __doc__
272      sys.exit(0)
[19]273
[20]274
[2]275def main():
[19]276  # A dictionary holding the boot info
277  #
278  bootinfo = {}
279  check_args(sys.argv, bootinfo)
[2]280
[19]281  if bootinfo:   
282    check_cmd_line(bootinfo)
283  else:
284    interactive(bootinfo)
285
286  create_links(bootinfo)
287
[2]288if __name__ == '__main__':
289  main()
Note: See TracBrowser for help on using the repository browser.