source: trunk/pxeconfig/pxeconfig @ 31

Last change on this file since 31 was 31, checked in by bas, 21 years ago

Updated version info and changelog

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