restoring operations default settings for breakpoint mode
[bootmanager.git] / source / utils.py
1 #!/usr/bin/python2
2
3 # Copyright (c) 2003 Intel Corporation
4 # All rights reserved.
5 #
6 # Copyright (c) 2004-2006 The Trustees of Princeton University
7 # All rights reserved.
8 # expected /proc/partitions format
9
10 import os, sys, shutil
11 import popen2
12 import socket
13 import fcntl
14 import string
15 import exceptions
16
17 from Exceptions import *
18
19
20 def makedirs( path ):
21     """
22     from python docs for os.makedirs:
23     Throws an error exception if the leaf directory
24     already exists or cannot be created.
25
26     That is real useful. Instead, we'll create the directory, then use a
27     separate function to test for its existance.
28
29     Return 1 if the directory exists and/or has been created, a BootManagerException
30     otherwise. Does not test the writability of said directory.
31     """
32     try:
33         os.makedirs( path )
34     except OSError:
35         pass
36     try:
37         os.listdir( path )
38     except OSError:
39         raise BootManagerException, "Unable to create directory tree: %s" % path
40     
41     return 1
42
43
44
45 def removedir( path ):
46     """
47     remove a directory tree, return 1 if successful, a BootManagerException
48     if failure.
49     """
50     try:
51         os.listdir( path )
52     except OSError:
53         return 1
54
55     try:
56         shutil.rmtree( path )
57     except OSError, desc:
58         raise BootManagerException, "Unable to remove directory tree: %s" % path
59     
60     return 1
61
62
63
64 def sysexec( cmd, log= None ):
65     """
66     execute a system command, output the results to the logger
67     if log <> None
68
69     return 1 if command completed (return code of non-zero),
70     0 if failed. A BootManagerException is raised if the command
71     was unable to execute or was interrupted by the user with Ctrl+C
72     """
73     if BREAKPOINT_MODE:
74         print ("sysexec >>> %s" % cmd)
75     prog= popen2.Popen4( cmd, 0 )
76     if prog is None:
77         raise BootManagerException, \
78               "Unable to create instance of popen2.Popen4 " \
79               "for command: %s" % cmd
80
81     if log is not None:
82         try:
83             for line in prog.fromchild:
84                 log.write( line )
85         except KeyboardInterrupt:
86             raise BootManagerException, "Interrupted by user"
87
88     returncode= prog.wait()
89     if returncode != 0:
90         raise BootManagerException, "Running %s failed (rc=%d)" % (cmd,returncode)
91
92     prog= None
93     return 1
94
95
96 def sysexec_noerr( cmd, log= None ):
97     """
98     same as sysexec, but capture boot manager exceptions
99     """
100     try:
101         rc= 0
102         rc= sysexec( cmd, log )
103     except BootManagerException, e:
104         pass
105
106     return rc
107
108
109
110 def chdir( dir ):
111     """
112     change to a directory, return 1 if successful, a BootManagerException if failure
113     """
114     try:
115         os.chdir( dir )
116     except OSError:
117         raise BootManagerException, "Unable to change to directory: %s" % dir
118
119     return 1
120
121
122
123 def removefile( filepath ):
124     """
125     removes a file, return 1 if successful, 0 if failure
126     """
127     try:
128         os.remove( filepath )
129     except OSError:
130         raise BootManagerException, "Unable to remove file: %s" % filepath
131
132     return 1
133
134
135
136 # from: http://forums.devshed.com/archive/t-51149/
137 #              Ethernet-card-address-Through-Python-or-C
138
139 def hexy(n):
140     return "%02x" % (ord(n))
141
142 def get_mac_from_interface(ifname):
143     """
144     given a device name, like eth0, return its mac_address.
145     return None if the device doesn't exist.
146     """
147     
148     SIOCGIFHWADDR = 0x8927 # magic number
149
150     s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
151     ifname = string.strip(ifname)
152     ifr = ifname + '\0'*(32-len(ifname))
153
154     try:
155         r= fcntl.ioctl(s.fileno(),SIOCGIFHWADDR,ifr)
156         addr = map(hexy,r[18:24])
157         ret = (':'.join(map(str, addr)))
158     except IOError, e:
159         ret = None
160         
161     return ret
162
163 ### handling breakpoints in the startup process
164 import select, sys, string
165
166 ### global debug settings
167 # NOTE. when BREAKPOINT_MODE turns out enabled,
168 # you have to attend the boot phase, that would hang otherwise 
169
170 # enabling this will cause the node to ask for breakpoint-mode at startup
171 # production code should read False/False
172 PROMPT_MODE=False
173 # default for when prompt is turned off, or it's on but the timeout triggers
174 BREAKPOINT_MODE=False
175 # in seconds : if no input, proceed
176 PROMPT_TIMEOUT=5
177
178 def prompt_for_breakpoint_mode ():
179
180     global BREAKPOINT_MODE
181     if PROMPT_MODE:
182         default_answer=BREAKPOINT_MODE
183         answer=''
184         if BREAKPOINT_MODE:
185             display="[y]/n"
186         else:
187             display="y/[n]"
188         sys.stdout.write ("Want to run in breakpoint mode ? %s "%display)
189         sys.stdout.flush()
190         r,w,e = select.select ([sys.stdin],[],[],PROMPT_TIMEOUT)
191         if r:
192             answer = string.strip(sys.stdin.readline())
193         else:
194             sys.stdout.write("\nTimed-out (%d s)"%PROMPT_TIMEOUT)
195         if answer:
196             BREAKPOINT_MODE = ( answer == "y" or answer == "Y")
197         else:
198             BREAKPOINT_MODE = default_answer
199     label="Off"
200     if BREAKPOINT_MODE:
201         label="On"
202     sys.stdout.write("\nCurrent BREAKPOINT_MODE is %s\n"%label)
203
204 def breakpoint (message, cmd = None):
205
206     if BREAKPOINT_MODE:
207
208         if cmd is None:
209             cmd="/bin/sh"
210             message=message+" -- Entering bash - type ^D to proceed"
211
212         print message
213         os.system(cmd)