source: trunk/pxeconfig/pxeconfig @ 28

Last change on this file since 28 was 24, checked in by sscpbas, 21 years ago

pxeconfig:

changed -v to -V for version info

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