source: trunk/src/pxeconfigd.py @ 210

Last change on this file since 210 was 206, checked in by bas, 11 years ago

added a new option to skip hostname lookup failures

  • Property keywords set to Id
  • Property svn:executable set to *
  • Property svn:keywords set to Id
File size: 4.6 KB
RevLine 
[14]1# Copyright (C) 2002
[6]2#
[14]3# This file is part of the pxeconfig utils
[6]4#
[14]5# This program is free software; you can redistribute it and/or modify it
6# under the terms of the GNU General Public License as published by the
7# Free Software Foundation; either version 2, or (at your option) any
8# later version.
[6]9#
[14]10# This program is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13# GNU General Public License for more details.
14#
15# You should have received a copy of the GNU General Public License
16# along with this program; if not, write to the Free Software
17# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
18#
[29]19# SVN info
20#  $Id: pxeconfigd.py 206 2012-12-18 11:53:42Z bas $
[2]21"""
22Author: Bas van der Vlies <basv@sara.nl>
23Date  : 12 February 2002
24Desc. : This script is used to control how a node is booted with PXE
[3]25        enabled network cards. The node boots and fetch a pxe
26        config file which tells how the node must boot. This daemon
27        enables a client to remove his/here pxe config file. With the
[206]28        next boot it will use the default one.
[3]29
[206]30        command line option:
31          -V/--version
32            Prints the version number and exits
[2]33         
34        Note:
[206]35          This server can ONLY be started from inetd/xinetd.
[2]36"""
37import time
38import socket
39import sys
40import os
41import string
42import syslog
[3]43import getopt
[2]44
[171]45# PXE modules
46from pxe_global import *
47
[2]48# DEBUG
49#
50DEBUG=1
51
52# Some Global Constants
53#
54BUFSIZE=4096
55STDIN=0
56STDOUT=1
[171]57SHORTOPT_LIST='V'
58LONGOPT_LIST=['version']
[2]59
60PXE_CONF_DIR = '/tftpboot/pxelinux.cfg'
[206]61VERSION = '4.2.0'
[2]62
63# Give the current time
64#
65def now():
66    return time.ctime(time.time())
67
68
[186]69def remove_link(ip, arp_cmd):
70        """
71        This removes the pxe config filename for the host that is connected:
72                ip      : ip address of the client host
73                arp_cmd : For Dynamic ips, look up the mac address via arp
74        """
[2]75
[186]76        ## translate ip address ---> hex address
77        #
78        d = string.split(ip, '.')
79        haddr = '%02X%02X%02X%02X' %(int(d[0]), int(d[1]), int(d[2]), int(d[3])) 
[2]80
[186]81        file = os.path.join(PXE_CONF_DIR, haddr)
[196]82        if DEBUG:
83                print file
[2]84
[186]85        if not os.path.exists(file): 
[2]86
[186]87                ##
88                # No ARP command set, just return
89                #
90                if not arp_cmd:
91                        return
[2]92
[186]93                else:
94                        ##
95                        #  arp -n 192.168.146.112
96                        # Address          HWtype  HWaddress           Flags Mask Iface
97                        # 192.168.146.112  ether   00:23:ae:fd:cf:74   C          vlan133
98
99                        cmd = '%s %s' %(arp_cmd, ip)
100                        lines = os.popen(cmd).readlines()
101                        for line in lines:
102                                if line.startswith(ip):
103                                        t = line.split()
104                                        mac_addr = t[2] 
105                                        haddr = '01-%s' %(mac_addr.replace(':', '-').lower())
[196]106
[186]107                                        file = os.path.join(PXE_CONF_DIR, haddr) 
[196]108                                        if DEBUG:
109                                                print file
110
[186]111                                        if not os.path.exists(file): 
112                                                return
113
114        if DEBUG:
115                print 'file = %s' %file
116
117        if os.path.islink(file): 
118                try:
119                        os.unlink(file)
120                        syslog.openlog("pxeconfigd")
121                        syslog.syslog(syslog.LOG_INFO, file)
122                        syslog.closelog()
123                except OSError:
124                        err_msg = "No permission at directory: %s" %PXE_CONF_DIR
125                        os.write(STDOUT, err_msg)
126                        sys.exit(1)
127
128
[2]129# This function handles the client connection. It closes
130# the connection if there is no data
131#
[171]132def handleConnection(settings):
133        """
134        Determines which host connects to the server
135        """ 
136       
137        # Determine client address
138        #
139        try:
140                client_addr = socket.fromfd(sys.stdin.fileno(), socket.AF_INET, 
[2]141                          socket.SOCK_STREAM)
[171]142                client_ip = client_addr.getpeername()[0] 
143        except socket.error, detail:
144                error =  "pxeconfigd can only be started from inetd!!!"
145                raise PxeConfig, error
146               
147       
148        if DEBUG:
[189]149                print 'ip = %s' %(client_ip) 
[2]150
[172]151        try:
[171]152                cmd = '%s %s' %(settings['daemon_script_hook'], client_ip)
153                print cmd
154                os.system(cmd)
[172]155        except KeyError:
156                pass
[2]157
[186]158        try:
159                arp_cmd = settings['arp_command']
160        except KeyError:
161                arp_cmd = None
162
163        remove_link(client_ip, arp_cmd)
[171]164        sys.exit(0)
[2]165
[171]166def check_args(argv, settings):
167        """
168        Must we use another directory for the PXE configuration
169        """
170        global PXE_CONF_DIR
171       
172        try:
173                opts, args = getopt.getopt(argv[1:], SHORTOPT_LIST, LONGOPT_LIST)
174        except getopt.error, detail:
175                print __doc__
176                print detail
177                sys.exit(1) 
178               
179        for opt, value in opts:
180                if opt in ['-V', '--version']:
181                        print VERSION
182                        sys.exit(0)
[2]183
[171]184        try:
185                PXE_CONF_DIR = settings['pxe_config_dir']
186        except KeyError:
187                pass 
188               
189        PXE_CONF_DIR = os.path.realpath(PXE_CONF_DIR) 
190        if not os.path.isdir(PXE_CONF_DIR):
191                error =  'pxeconfig directory: %s does not exists' %(PXE_CONF_DIR)
192                raise PxeConfig, error
[2]193
194def server():
195  """Start the daemon
196  """
[186]197  parser_config, default_settings = ReadConfig()
198  check_args(sys.argv, default_settings)
199  handleConnection(default_settings)
[2]200
201if __name__ == '__main__':
202  server()
Note: See TracBrowser for help on using the repository browser.