/[gli]/branches/overhaul/src/GLIUtility.py
Gentoo

Contents of /branches/overhaul/src/GLIUtility.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1805 - (show annotations) (download) (as text)
Sun Mar 18 18:23:17 2007 UTC (8 years, 1 month ago) by agaffney
File MIME type: text/x-python
File size: 29030 byte(s)
remove /tmp/spawn_exitcode after grabbing contents
1 """
2 # Copyright 1999-2005 Gentoo Foundation
3 # This source code is distributed under the terms of version 2 of the GNU
4 # General Public License as published by the Free Software Foundation, a copy
5 # of which can be found in the main directory of this project.
6 Gentoo Linux Installer
7
8 The GLIUtility module contians all utility functions used throughout GLI.
9 """
10
11 import string, os, re, shutil, sys, random, commands, crypt, pty, select
12 from GLIException import *
13
14 ##
15 # Check to see if a string is actually a string, and if it is not null. Returns bool.
16 # @param string_a string to be checked.
17 def is_realstring(string):
18 # Make sure it is a string
19 if not isinstance(string, (str, unicode)):
20 return False
21
22 return True
23
24 ##
25 # Checks to see if x is a numeral by doing a type conversion.
26 # @param x value to be checked
27 def is_numeric(x):
28 try:
29 float(x)
30 except ValueError:
31 return False
32 else:
33 return True
34
35 ##
36 # Check to see if a string is a valid ip. Returns bool.
37 # @param ip ip to be checked.
38 def is_ip(ip):
39 # Make sure it is a string
40 if not is_realstring(ip):
41 return False
42
43 # Compile the regular expression that validates an IP. It will also check for valid ranges.
44 expr = re.compile('(([0-9]|[01]?[0-9]{2}|2([0-4][0-9]|5[0-5]))\.){3}([0-9]|[01]?[0-9]{2}|2([0-4][0-9]|5[0-5]))$')
45
46 # Run the test.
47 res = expr.match(ip)
48
49 # Return True only if there are results.
50 return(res != None)
51
52 ##
53 # Check to see if mac is a valid MAC address. Make sure use format_mac
54 # before using this function. Returns bool.
55 # @param mac mac address to be checked.
56 def is_mac(mac):
57 expr = re.compile('([0-9A-F]{2}:){5}[0-9A-F]{2}')
58 res = expr.match(mac)
59 return(res != None)
60
61 ##
62 # Format's a mac address properly. Returns the correctly formatted MAC. (a string)
63 # @param mac mac address to be formatted
64 def format_mac(mac):
65 mac = string.replace(mac, '-', ':')
66 mac = string.upper(mac)
67
68 mac = string.split(mac, ':')
69 for i in range(0, len(mac)):
70 if len(mac[i]) < 2:
71 mac[i] = "0" + mac[i]
72 return string.join(mac, ":")
73
74 ##
75 # Removes leading zero's from an IP address. For example
76 # trim_ip('192.168.01.002') => '192.168.1.2'
77 # @param ip IP address to be trimmed
78 def trim_ip(ip):
79 # Remove leading zero's on the first octet
80 ip = re.sub('^0{1,2}','',ip)
81
82 # Remove leading zero's from the other octets
83 res = re.sub('((?<=\.)(00|0)(?P<num>\d))','\g<num>',ip)
84
85 return(res)
86
87 ##
88 # Check to see if the string passed is a valid device. Returns bool.
89 # @param device device to be checked
90 def is_device(device):
91 # Make sure it is a string
92 if not is_realstring(device):
93 return False
94
95 # Make sure the string starts with /dev/
96 if device[0:5] != '/dev/':
97 return False
98
99 # Check to make sure the device exists
100 return os.access(device, os.F_OK)
101
102 ##
103 # Check to see if the string is a valid hostname. Returns bool.
104 # @param hostname host to be checked
105 def is_hostname(hostname):
106 # Make sure it is a string
107 if not is_realstring(hostname):
108 return False
109
110 expr = re.compile('^([a-zA-Z0-9-_\.])+\.[a-zA-Z]{2,4}$')
111 res = expr.match(hostname)
112
113 return(res != None)
114
115 ##
116 # Check to see if the string is a valid path. Returns bool.
117 # @param path Path to be checked.
118 def is_path(path):
119 # Make sure it is a string
120 if not is_realstring(path):
121 return False
122
123 # Create a regular expression that matches all words and the symbols '-_./' _ is included in the \w
124 expr = re.compile('^[\w\.\-\/~]+$')
125
126 # Run the match
127 res = expr.match(path)
128
129 # Return True only if there are results
130 return(res != None)
131
132 ##
133 # Check to see if the string is a valid file. Returns bool.
134 # @param file file to be checked for validity.
135 def is_file(file):
136 # Make sure it is a string
137 if not is_realstring(file):
138 return False
139
140 # Check to make sure the device exists
141 return os.access(file, os.F_OK)
142
143 ##
144 # Parse a URI. Returns a tuple (protocol, username, password, host, port, path)
145 # Returns None if URI is invalid.
146 # @param uri URI to be parsed
147 def parse_uri(uri):
148 # Compile the regex
149 expr = re.compile('(\w+)://(?:([^:@]+)(?::([^@]+))?@)?(?:([a-zA-Z0-9.-]+)(?::(\d+))?)?(/.*)')
150
151 # Run it against the URI
152 res = expr.match(uri)
153
154 if not res:
155 # URI doesn't match regex and therefore is invalid
156 return None
157
158 # Get tuple of matches
159 # 0 - Protocol
160 # 1 - Username
161 # 2 - Password
162 # 3 - Host
163 # 4 - Port
164 # 5 - Path
165 uriparts = res.groups()
166 return uriparts
167
168 ##
169 # Check to see if the string is a valid URI. Returns bool.
170 # @param uri URI to be validated
171 # @param checklocal=True Whether to look for a local uri.
172 def is_uri(uri, checklocal=True):
173 # Make sure it is a string
174 if not is_realstring(uri):
175 return False
176
177 # Set the valid uri types
178 valid_uri_types = ('ftp', 'rsync', 'http', 'file', 'https', 'scp')
179
180 # Parse the URI
181 uriparts = parse_uri(uri)
182 if not uriparts:
183 # Invalid URI
184 return False
185
186 # Check for valid uri type
187 if not uriparts[0] in valid_uri_types:
188 return False
189
190 # If checklocal and the URI is a local file, check to see if the file exists
191 if uriparts[0] == "file" and checklocal:
192 if not is_file(uriparts[5]):
193 return False
194
195 return True
196
197 ##
198 # Converts a string to a boolean value. anything not "True" is deemed false.
199 # @param input must be a string so it can be converted to boolean.
200 def strtobool(input):
201 if type(input) != str:
202 raise GLIException("GLIUtilityError", 'fatal','strtobool',"The input must be a string!")
203
204 if string.lower(input) == 'true':
205 return True
206 else:
207 return False
208
209 ##
210 # Check to see if device is a valid ethernet device. Returns bool.
211 # @param device device to be checked
212 def is_eth_device(device):
213 # Make sure it is a string
214 if not is_realstring(device):
215 return False
216
217 # Old way w/ reg ex here:
218 # Create a regular expression to test the specified device.
219 #expr = re.compile('^(eth|wlan|ppp)([0-9]{1,2})(:[0-9]{1,2})?$')
220 # Run the match
221 #res = expr.match(device)
222 # Return True only if there are results
223 #return(res != None)
224
225 status, output = spawn("/sbin/ifconfig -a | grep -e '^[A-Za-z]'| cut -d ' ' -f 1 | grep '"+ device + "'", return_output=True)
226 if output:
227 return True
228 return False
229
230 ##
231 # Will return a list of devices found in ifconfig.
232 def get_eth_devices():
233 status, output = spawn("/sbin/ifconfig -a | grep -e '^[A-Za-z]'| cut -d ' ' -f 1", return_output=True)
234 return output.split()
235
236 ##
237 # Checks to see if device is a valid NFS device
238 # @param device device to be checked
239 def is_nfs(device):
240 if not is_realstring(device):
241 return False
242
243 colon_location = device.find(':')
244
245 if colon_location == -1:
246 return False
247
248 host = device[:colon_location]
249 path = device[colon_location+1:]
250
251 return((is_ip(host) or is_hostname(host)) and is_path(path))
252
253 ##
254 # Sets the network ip (used for the livecd environment)
255 # @param dev device to be configured
256 # @param ip ip address of device
257 # @param broadcast broadcast address of device
258 # @param netmask netmask address of device
259 def set_ip(dev, ip, broadcast, netmask):
260 if not is_ip(ip) or not is_ip(netmask) or not is_ip(broadcast):
261 raise GLIException("GLIUtilityError", 'fatal','set_ip', ip + ", " + netmask + "and, " + broadcast + "must be a valid IP's!")
262 if not is_eth_device(dev):
263 raise GLIException("GLIUtilityError", 'fatal','set_ip', dev + "is not a valid ethernet device!")
264
265 options = "%s inet %s broadcast %s netmask %s" % (dev, ip, broadcast, netmask)
266
267 status = spawn("ifconfig " + options)
268
269 if not exitsuccess(status):
270 return False
271
272 return True
273
274 ##
275 # Sets the default route (used for the livecd environment)
276 # @param route ip addresss of gateway.
277 def set_default_route(route):
278 if not is_ip(route):
279 raise GLIException("GLIUtilityError", 'fatal', 'set_default_route', route + " is not an ip address!")
280 status = spawn("route add default gw " + route)
281
282 if not exitsuccess(status):
283 return False
284
285 return True
286
287 ##
288 # Will run a command with various flags for the style of output and logging.
289 #
290 # @param cmd The command to be run
291 # @param quiet=False Whether or not to filter output to /dev/null
292 # @param logfile=None if provied will log output to the given filename
293 # @param display_on_tty8=False will output to tty8 instead of the screen.
294 # @param chroot=None will run the command inside the new chroot env.
295 # @param append_log=False whether to start over on the logfile or append.
296 # @param return_output=False Returns the output along with the exit status
297 def spawn(cmd, quiet=False, logfile=None, display_on_tty8=False, chroot=None, append_log=False, return_output=False, linecount=0, match=None, cc=None, status_message=None):
298 # This is a hack since spawn() can't access _logger...set to True for verbose output on console
299 debug = False
300
301 if chroot:
302 wrapper = open(chroot+"/var/tmp/spawn.sh", "w")
303 wrapper.write("#!/bin/bash -l\n" + cmd + "\nexit $?\n")
304 wrapper.close()
305 cmd = "chmod a+x " + chroot + "/var/tmp/spawn.sh && chroot " + chroot + " /var/tmp/spawn.sh"
306
307 if debug:
308 print "Command: " + cmd
309
310 output = ""
311
312 cmd = "(" + cmd + " 2>&1; echo $? > /tmp/spawn_exitcode)"
313 if logfile:
314 if append_log:
315 # fd_logfile = open(logfile,'a')
316 cmd += " | tee -a " + logfile
317 else:
318 # fd_logfile = open(logfile,'w')
319 cmd += " | tee " + logfile
320
321 if display_on_tty8:
322 fd_tty = open('/dev/tty8','w')
323
324 # Set initial sub-progress display
325 if cc:
326 cc.addNotification("progress", (0, status_message))
327
328 # open a read only pipe
329 ro_pipe = os.popen(cmd, 'r')
330
331 # read a line from the pipe and loop until
332 # pipe is empty
333 # data = ro_pipe.readline()
334 seenlines = 0
335 last_percent = 0
336
337 while 1:
338 # data = ro_pipe.read(16384)
339 data = os.read(ro_pipe.fileno(), 16384)
340 if debug:
341 print "DEBUG: read some data...length " + str(len(data))
342 if not data:
343 if linecount and cc:
344 if debug:
345 print "DEBUG: end of stream...progress is 1"
346 cc.addNotification("progress", (1, status_message))
347 break
348
349 # print "DEBUG: spawn(): data is " + str(len(data)) + " bytes long"
350
351 # if logfile:
352 # fd_logfile.write(data)
353 ## fd_logfile.flush()
354
355 if display_on_tty8:
356 fd_tty.write(data)
357 fd_tty.flush()
358
359 if return_output:
360 output += data
361
362 if linecount and cc:
363 lastpos = -1
364 while 1:
365 lastpos = data.find("\n", lastpos + 1)
366 if lastpos == -1: break
367 # if match:
368 # if not re.match(match, uri):
369 # continue
370 seenlines += 1
371 if debug:
372 print "DEBUG: seenlines=" + str(seenlines)
373 percent = float(seenlines) / linecount
374 if debug:
375 print "DEBUG: percent=" + str(percent)
376 # print "DEBUG: spawn(): seenlines=" + str(seenlines) + ", linecount=" + str(linecount) + ", percent=" + str(percent)
377 if int(percent * 100) >= (last_percent + 5):
378 last_percent = int(percent * 100)
379 if debug:
380 print "DEBUG: setting next progress point...last_percent=" + str(last_percent)
381 cc.addNotification("progress", (percent, status_message))
382 # print "DEBUG: spawn(): send notification " + str((percent, status_message))
383
384 # data = ro_pipe.readline()
385
386 # close the file descriptors
387 # if logfile: fd_logfile.close()
388 if display_on_tty8: fd_tty.close()
389
390 # close the pipe and save return value
391 ro_pipe.close()
392 ret = int(open("/tmp/spawn_exitcode", "r").readline().strip())
393 os.unlink("/tmp/spawn_exitcode")
394
395 if return_output:
396 return ret, output
397 else:
398 return ret
399
400 ##
401 # Will check the status of a spawn result to see if it did indeed return successfully.
402 # @param status Parameter description
403 def exitsuccess(status):
404 if os.WIFEXITED(status) and os.WEXITSTATUS(status) == 0:
405 return True
406 return False
407
408 ##
409 # Will produce a bash shell with a special prompt for the installer.
410 def spawn_bash():
411 os.putenv("PROMPT_COMMAND","echo \"Type 'exit' to return to the installer.\"")
412 os.system("reset && bash") #don't care what this returns.
413
414 ##
415 # Will download or copy a file/uri to a location
416 # @param uri uri to be fetched.
417 # @param path destination for the file.
418 def get_uri(uri, path, cc=None):
419 uri = uri.strip()
420 status = 0
421
422 if re.match('^(ftp|http(s)?)://',uri):
423 if cc:
424 status = spawn("wget --progress=dot " + uri + " -O " + path + r""" 2>&1 | sed -u -e 's:^.\+\([0-9]\+\)%.\+$:\1:' | while read line; do [ "$line" = "$tmp_lastline" ] || echo $line | grep -e '^[1-9]'; tmp_lastline=$line; done""", linecount=100, cc=cc, status_message="Fetching " + uri.split('/')[-1])
425 else:
426 status = spawn("wget --quiet " + uri + " -O " + path)
427 elif re.match('^rsync://', uri):
428 status = spawn("rsync --quiet " + uri + " " + path)
429 elif uri.startswith("scp://"):
430 # Get tuple of matches
431 # 0 - Protocol
432 # 1 - Username
433 # 2 - Password
434 # 3 - Host
435 # 4 - Port
436 # 5 - Path
437 uriparts = parse_uri(uri)
438 scpcmd = "scp "
439 if uriparts[4]:
440 scpcmd += "-P " + uriparts[4] + " "
441 if uriparts[1]:
442 scpcmd += uriparts[1] + "@"
443 scpcmd += uriparts[3] + ":" + uriparts[5] + " " + path
444 pid, child_fd = pty.fork()
445 if not pid:
446 os.execvp("scp", scpcmd.split())
447 else:
448 while 1:
449 r, w, e = select.select([child_fd], [], [])
450 if child_fd in r:
451 try:
452 data = os.read(child_fd, 1024)
453 except:
454 pid2, status = os.waitpid(pid, 0)
455 break
456 if data.endswith("assword: "):
457 if uriparts[2]:
458 os.write(child_fd, uriparts[2] + "\n")
459 else:
460 os.write(child_fd, "\n")
461 elif data.endswith("Are you sure you want to continue connecting (yes/no)? "):
462 os.write(child_fd, "yes\n")
463 else:
464 pid2, status = os.waitpid(pid, os.WNOHANG)
465 if pid2:
466 break
467
468 elif re.match('^file://', uri):
469 r_file = uri[7:]
470 if os.path.isfile(r_file):
471 shutil.copy(r_file, path)
472 if not os.path.isfile(path):
473 raise GLIException("GLIUtilityError", 'fatal', 'get_uri', "Cannot copy " + r_file + " to " + path)
474 else:
475 # Just in case a person forgets file://
476 if os.path.isfile(uri):
477 shutil.copy(uri, path)
478 if not os.path.isfile(path):
479 raise GLIException("GLIUtilityError", 'fatal', 'get_uri', "Cannot copy " + r_file + " to " + path)
480 else:
481 raise GLIException("GLIUtilityError", 'fatal', 'get_uri', "File does not exist or URI is invalid!")
482
483 if exitsuccess(status) and is_file(path):
484 return True
485
486 return False
487
488 ##
489 # Pings a host. Used to test network connectivity.
490 # @param host host to be pinged.
491 def ping(host):
492 host = str(host)
493 if not (is_hostname(host) or is_ip(host)):
494 return False #invalid IP or hostname
495 status = spawn("ping -n -c 2 " + host)
496 if not exitsuccess(status):
497 return False
498 return True
499
500 ##
501 # Pass in the eth device's number (0, 1, 2, etc).
502 # Returns network information in a tuple.
503 # Order is hw_addr, ip_addr, mask, bcast, route, and
504 # whether it's up (True or False).
505 # @param device device to gather info from.
506 def get_eth_info(device):
507 """Pass in the eth device's number (0, 1, 2, etc).
508 Returns network information in a tuple.
509 Order is hw_addr, ip_addr, mask, bcast, route, and
510 whether it's up (True or False).
511 """
512
513 hw_addr = 'None'
514 ip_addr = 'None'
515 mask = 'None'
516 bcast = 'None'
517 gw = 'None'
518 up = False
519
520 if len(str(device)) == 1:
521 device = "eth" + str(device)
522
523 if not is_eth_device(device):
524 raise GLIException("GLIUtilityError", 'fatal', "get_eth_info", device + " is not a valid ethernet device!")
525
526 status, device_info = spawn("/sbin/ifconfig " + device, return_output=True)
527 if exitsuccess(status):
528 for line in device_info.splitlines():
529 line = line.strip()
530 if 'HWaddr' in line:
531 hw_addr = line.split('HWaddr',1)[1].strip()
532 if 'inet addr' in line:
533 ip_addr = line.split(' ')[0].split(':')[1]
534 if 'Bcast' in line:
535 bcast = line.split(' ')[1].split(':')[1]
536 if 'Mask' in line:
537 mask = line.split(' ')[2].split(':')[1]
538 if line.startswith('UP'):
539 up = True
540 else:
541 raise GLIException("GLIUtilityError", 'fatal', "get_eth_info", device_info)
542 gw = spawn(r"/sbin/route -n | grep -e '^0\.0\.0\.0' | sed -e 's:^0\.0\.0\.0 \+::' -e 's: \+.\+$::'", return_output=True)[1].strip()
543
544 return (hw_addr, ip_addr, mask, bcast, gw, up)
545
546 ##
547 # Will take a uri and get and unpack a tarball into the destination.
548 # @param tarball_uri URI of tarball
549 # @param target_directory destination
550 # @param temp_directory="/tmp" a temporary location (used for dealing with the
551 # ramdisk size limitations of the livecd env.
552 # @param keep_permissions=False Whether or not to keep permissions (-p)
553 def fetch_and_unpack_tarball(tarball_uri, target_directory, temp_directory="/tmp", keep_permissions=False, cc=None):
554 "Fetches a tarball from tarball_uri and extracts it into target_directory"
555
556 # Get tarball info
557 tarball_filename = tarball_uri.split("/")[-1]
558
559 # Get the tarball
560 if not get_uri(tarball_uri, temp_directory + "/" + tarball_filename, cc):
561 raise GLIException("GLIUtilityError", 'fatal', 'fetch_and_unpack_tarball',"Could not fetch " + tarball_uri)
562
563 # Reset tar options
564 tar_options = "xv"
565
566 # If the tarball is bzip'd
567 if tarball_filename.split(".")[-1] == "tbz" or tarball_filename.split(".")[-1] == "bz2":
568 format_option = "j"
569
570 # If the tarball is gzip'd
571 elif tarball_filename.split(".")[-1] == "tgz" or tarball_filename.split(".")[-1] == "gz":
572 format_option = "z"
573
574 tar_options += format_option
575
576 # If we want to keep permissions
577 if keep_permissions:
578 tar_options = tar_options + "p"
579
580 # Get number of files in tarball
581 tarfiles = 0
582 if cc:
583 cc.addNotification("progress", (0, "Determining the number of files in " + tarball_filename))
584 tarfiles = int(spawn("tar -t" + format_option + "f " + temp_directory + "/" + tarball_filename + " 2>/dev/null | wc -l", return_output=True)[1].strip())
585
586 # Unpack the tarball
587 exitstatus = spawn("tar -" + tar_options + " -f " + temp_directory + "/" + tarball_filename + " -C " + target_directory, display_on_tty8=True, logfile="/tmp/compile_output.log", append_log=True, linecount=tarfiles, cc=cc, status_message="Unpacking " + tarball_filename) # change this to the logfile variable
588
589 if not exitsuccess(exitstatus):
590 raise GLIException("GLIUtilityError", 'fatal', 'fetch_and_unpack_tarball',"Could not unpack " + tarball_uri + " to " + target_directory)
591
592 ##
593 # OLD Will generate a random password. Used when the livecd didn't auto-scramble the root password.
594 # can probably be removed but is good to keep around.
595 def generate_random_password():
596 s = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890$%^&*[]{}-=+_,|'\"<>:/"
597 s = list(s)
598
599 for i in range(0,len(s)/2):
600 x = random.randint(0,len(s)-1)
601 y = random.randint(0,len(s)-1)
602 tmp = s[x]
603 s[x] = s[y]
604 s[y] = tmp
605
606 passwd = ""
607 for i in range(0,random.randint(8,12)):
608 passwd += s[i]
609
610 return passwd
611
612 ##
613 # Will grab a value from a specified file after sourcing it
614 # @param filename file to get the value from
615 # @param value value to look for
616 def get_value_from_config(filename, value):
617 #OLD WAY: return string.strip(commands.getoutput("source " + filename + " && echo $" + value))
618 status, output = spawn("source " + filename + " && echo $" + value, return_output=True)
619 return string.strip(output)
620
621
622 ##
623 # Will take a password and return it hashed in md5 format
624 # @param password the password to be hashed
625 def hash_password(password):
626 salt = "$1$"
627 chars = "./abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
628 for i in range(0, 8):
629 salt += chars[random.randint(0, len(chars)-1)]
630 salt += "$"
631 passwd_hash = crypt.crypt(password, salt)
632
633 return passwd_hash
634
635 ##
636 # Returns the real name (manufacturer and model) of a network interface
637 # @param interface Name of interface (like in ifconfig)
638 def get_interface_realname(interface):
639 # TODO: rewrite with 2.4 support
640 if is_file("/sys/class/net/" + interface + "/device"):
641 return spawn("lspci | grep $(basename $(readlink /sys/class/net/" + interface + r"/device)) | sed -e 's|^.\+ Ethernet controller: ||'", return_output=True)[1].strip()
642 else:
643 return "No Information Found"
644
645 def list_stage_tarballs_from_mirror(mirror, arch):
646 return spawn("wget -O - " + mirror + "/releases/" + arch + "/current/stages/" + r" 2> /dev/null | grep 'bz2\"' | sed -e 's:^.\+href=\"\(.\+\)\".\+$:\1:i' -e 's:.\+/\(.\+\)$:\1:'", return_output=True)[1].strip().split("\n")
647
648 def list_mirrors(http=True, ftp=True, rsync=True):
649 mirrors = []
650 mirrortypes = ""
651 if http:
652 mirrortypes += "http"
653 if ftp:
654 if mirrortypes:
655 mirrortypes += '\|'
656 mirrortypes += "ftp"
657 if rsync:
658 if mirrortypes:
659 mirrortypes += '\|'
660 mirrortypes += "rsync"
661 mirrorlist = spawn(r"wget -O - 'http://www.gentoo.org/main/en/mirrors.xml?passthru=1' 2>/dev/null | /bin/sed -ne '/^[[:space:]]*<uri link=\"\(" + mirrortypes + r"\):\/\/[^\"]\+\">.\+<\/uri>/{s/^[[:space:]]*<uri link=\"\([^\"]\+\)\">\(.*\)<\/uri>.*$/\1|\2/;p}'", return_output=True)[1].strip().split("\n")
662 for mirror in mirrorlist:
663 mirror = mirror.strip()
664 mirrors.append(mirror.split("|"))
665 return mirrors
666
667 def generate_keymap_list():
668 keymap_list = []
669 path = "/usr/share/keymaps"
670
671 # find /usr/share/keymaps -iname *.map.gz -printf "%f \n"
672 put, get = os.popen4("find "+path+" -iname *.map.gz -printf \"%f \n\"")
673 for keymap in get.readlines():
674 # strip the last 9 chars ( .map.gz\n )
675 keymap.strip()
676 keymap = keymap[:-9]
677 keymap_list.append(keymap)
678
679 # sort the keymap list
680 keymap_list.sort()
681
682 return keymap_list
683
684 def generate_consolefont_list():
685 consolefont_list=[]
686 path = "/usr/share/consolefonts"
687
688 # find /usr/share/consolefonts -iname *.gz -printf "%f \n"
689 put, get = os.popen4("find "+path+" -iname *.gz -printf \"%f \n\"")
690 for consolefont in get.readlines():
691 # strip the last 5 chars ( .gz\n )
692 consolefont.strip()
693 consolefont = consolefont[:-5]
694
695 # test if its psfu or psf or fnt
696 # and remove it if necessary
697 if consolefont[-4:]== "psfu":
698 consolefont = consolefont[:-5]
699 if consolefont[-3:]== "psf":
700 consolefont = consolefont[:-4]
701 if consolefont[-3:]=="fnt":
702 consolefont = consolefont[:-4]
703
704 consolefont_list.append(consolefont)
705
706 # sort the keymap list
707 consolefont_list.sort()
708
709 return consolefont_list
710
711 def generate_consoletranslation_list():
712 consoletranslation_list=[]
713 path = "/usr/share/consoletrans"
714
715 # find /usr/share/keymaps -iname *.trans -printf "%f \n"
716 put, get = os.popen4("find "+path+" -iname *.trans -printf \"%f \n\"")
717 for consoletran in get.readlines():
718 # strip the last 8 chars ( .trans\n )
719 consoletran.strip()
720 consoletran = consoletran[:-8]
721 consoletranslation_list.append(consoletran)
722
723 consoletranslation_list.sort()
724
725 return consoletranslation_list
726
727 def get_global_use_flags():
728 use_desc = {}
729 f = open("/usr/portage/profiles/use.desc", "r")
730 for line in f:
731 line = line.strip()
732 if line == "# The following flags are NOT to be set or unset by users":
733 break
734 if not line or line.startswith("#"): continue
735 dash_pos = line.find(" - ")
736 if dash_pos == -1: continue
737 flagname = line[:dash_pos] or line[dash_pos-1]
738 desc = line[dash_pos+3:]
739 use_desc[flagname] = desc
740 f.close()
741 return use_desc
742
743 def get_local_use_flags():
744 use_local_desc = {}
745 f = open("/usr/portage/profiles/use.local.desc", "r")
746 for line in f:
747 line = line.strip()
748 if not line or line.startswith("#"): continue
749 dash_pos = line.find(" - ")
750 if dash_pos == -1: continue
751 colon_pos = line.find(":", 0, dash_pos)
752 pkg = line[:colon_pos]
753 flagname = line[colon_pos+1:dash_pos] or line[colon_pos+1]
754 desc = "(" + pkg + ") " + line[dash_pos+3:]
755 use_local_desc[flagname] = desc
756 f.close()
757 return use_local_desc
758
759 def get_cd_snapshot_uri():
760 snapshot_loc = spawn("ls /mnt/{cdrom,livecd}/snapshots/portage-* 2>/dev/null | head -n 1", return_output=True)[1].strip()
761 if snapshot_loc:
762 snapshot_loc = "file://" + snapshot_loc
763 return snapshot_loc
764
765 def validate_uri(uri):
766 # Get tuple of matches
767 # 0 - Protocol
768 # 1 - Username
769 # 2 - Password
770 # 3 - Host
771 # 4 - Port
772 # 5 - Path
773 uriparts = parse_uri(uri)
774 if not uriparts:
775 return False
776 if uriparts[0] in ('http', 'https', 'ftp'):
777 ret = spawn("wget --spider " + uri)
778 return exitsuccess(ret)
779 elif uriparts[0] == "file":
780 return is_file(uriparts[5])
781 return True
782
783 def get_directory_listing_from_uri(uri):
784 uriparts = parse_uri(uri)
785 if not uriparts:
786 return []
787 if uriparts[0] == "file":
788 dirlist = os.listdir(uriparts[5])
789 dirlist.sort()
790 dirs = []
791 files = []
792 for entry in dirlist:
793 if os.path.isdir(uriparts[5] + entry):
794 dirs.append(entry + "/")
795 else:
796 files.append(entry)
797 if not uriparts[5] == "/":
798 dirlist = ["../"]
799 else:
800 dirlist = []
801 dirlist += dirs + files
802 elif uriparts[0] == "http":
803 dirlist = spawn("wget -O - http://" + uriparts[3] + uriparts[5] + r" 2> /dev/null | grep -i href | grep -v 'http://' | grep -v 'ftp://' | sed -e 's:^.\+href=\"\(.\+\)\".\+$:\1:i'", return_output=True)[1].strip().split("\n")
804 dirs = []
805 files = []
806 for entry in dirlist:
807 if not entry.startswith("/") and entry.find("?") == -1:
808 if entry.endswith("/"):
809 dirs.append(entry)
810 else:
811 files.append(entry)
812 dirs.sort()
813 files.sort()
814 if not uriparts[5] == "/":
815 dirlist = ["../"]
816 else:
817 dirlist = []
818 dirlist += dirs + files
819 elif uriparts[0] == "ftp":
820 dirlist = spawn("wget -O - ftp://" + uriparts[3] + uriparts[5] + r" 2> /dev/null | grep -i href | sed -e 's:^.\+href=\"\(.\+\)\".\+$:\1:i' -e 's|^ftp://[^/]\+/|/|'", return_output=True)[1].strip().split("\n")
821 dirs = []
822 files = []
823 for entry in dirlist:
824 if entry.startswith(uriparts[5]):
825 entry = entry[len(uriparts[5]):]
826 if entry.endswith("/"):
827 dirs.append(entry)
828 else:
829 files.append(entry)
830 dirs.sort()
831 files.sort()
832 if not uriparts[5] == "/":
833 dirlist = ["../"]
834 else:
835 dirlist = []
836 dirlist += dirs + files
837 elif uriparts[0] == "scp":
838 tmpdirlist = ""
839 dirlist = []
840 sshcmd = ["ssh"]
841 if uriparts[4]:
842 sshcmd.append("-p")
843 sshcmd.append(uriparts[4])
844 if uriparts[1]:
845 sshcmd.append(uriparts[1] + "@" + uriparts[3])
846 else:
847 sshcmd.append(uriparts[3])
848 sshcmd.append("ls --color=no -1F " + uriparts[5] + r" 2>/dev/null | sed -e 's:\*$::'")
849 # print str(sshcmd)
850 pid, child_fd = pty.fork()
851 if not pid:
852 os.execvp("ssh", sshcmd)
853 else:
854 got_password_prompt = False
855 while 1:
856 r, w, e = select.select([child_fd], [], [])
857 if child_fd in r:
858 try:
859 data = os.read(child_fd, 1024)
860 except:
861 pid2, status = os.waitpid(pid, 0)
862 break
863 if data.endswith("assword: "):
864 if uriparts[2]:
865 os.write(child_fd, uriparts[2] + "\n")
866 else:
867 os.write(child_fd, "\n")
868 got_password_prompt = True
869 elif data.endswith("Are you sure you want to continue connecting (yes/no)? "):
870 os.write(child_fd, "yes\n")
871 else:
872 if got_password_prompt:
873 if not tmpdirlist and data.endswith("assword: "):
874 raise GLIException("IncorrectPassword", "notice", "get_directory_listing_from_uri", "Your SSH password was incorrect")
875 tmpdirlist += data
876 else:
877 pid2, status = os.waitpid(pid, os.WNOHANG)
878 if pid2:
879 break
880 for tmpentry in tmpdirlist.strip().split("\n"):
881 dirlist.append(tmpentry.strip())
882 dirs = []
883 files = []
884 for entry in dirlist:
885 if entry.endswith("/"):
886 dirs.append(entry)
887 else:
888 files.append(entry)
889 dirs.sort()
890 files.sort()
891 if not uriparts[5] == "/":
892 dirlist = ["../"]
893 else:
894 dirlist = []
895 dirlist += dirs + files
896 else:
897 dirlist = ["this/", "type/", "isn't/", "supported", "yet"]
898 return dirlist
899
900 def cdata(text):
901 if text.startswith("<![CDATA["):
902 return text
903 else:
904 return "<![CDATA[\n" + text + "\n]]>"
905
906 def uncdata(text):
907 if text.startswith("<![CDATA["):
908 return text[9:-5]
909 else:
910 return text
911
912 def get_grp_pkgs_from_cd():
913 """
914 if not is_file("/usr/livecd/grppkgs.txt"):
915 return ""
916 #raise GLIException("GLIUtilityError", "fatal", "get_grp_pkgs_from_cd", "Required file /usr/livecd/grppkgs.txt does not exist")
917 status,output = spawn('cat /usr/livecd/grppkgs.txt',return_output=True)
918 output = output.split()
919 #remove the first part before a / for comparision
920 results = []
921 for pkg in output:
922 results.append(pkg[(pkg.find('/')+1):])
923 return results
924 """
925 return spawn(r"find /var/db/pkg -mindepth 2 -maxdepth 2 -type d | sed -e 's:^/var/db/pkg/::' -e 's:-[0-9].*$::'", return_output=True)[1].strip().split("\n")
926
927 def get_keymaps():
928 return GLIUtility.spawn(r"find /usr/share/keymaps -iname *.map.gz | sed -e 's:^.\+/::' -e 's:\..\+$::' | sort", return_output=True)[1].strip().split("\n")
929
930 def get_chosts(arch):
931 chosts = []
932 if arch == "x86":
933 chosts = ["i386-pc-linux-gnu", "i486-pc-linux-gnu", "i586-pc-linux-gnu", "i686-pc-linux-gnu"]
934 if arch == "amd64":
935 chosts = ["x86_64-pc-linux-gnu"]
936 if arch == "alpha":
937 chosts = ["alpha-unknown-linux-gnu"]
938 if arch == "ppc":
939 chosts = ["powerpc-unknown-linux-gnu"]
940 if arch == "ppc64":
941 chosts = ["powerpc64-unknown-linux-gnu"]
942 if arch in ["sparc", "sparc64"]:
943 chosts = ["sparc-unknown-linux-gnu"]
944 if arch == "hppa":
945 chosts = ["hppa-unknown-linux-gnu", "hppa1.1-unknown-linux-gnu", "hppa2.0-unknown-linux-gnu"]
946 if arch == "mips":
947 chosts = ["mips-unknown-linux-gnu"]
948 return chosts
949
950 # Starts portmap.
951 def start_portmap():
952 status = spawn('/etc/init.d/portmap start') #, display_on_tty8=True)
953 if not exitsuccess(status):
954 return False
955 else:
956 return True

Properties

Name Value
svn:eol-style native

  ViewVC Help
Powered by ViewVC 1.1.20