4 warnings.filterwarnings("ignore", "", DeprecationWarning)
7 import sys, os, string, re
9 #==============================================================
11 #==============================================================
13 str = "\nSALOME2 Installation Wizard\n\n"
14 str = str + "\tUsage : \n\tInstall [-g|b] [-f <xml-file>] [-t <target-dir>] [-tmp <tmp-dir>]\n"
16 str = str + " -g Runs the Installation Wizard in the GUI mode.\n"
17 str = str + " In this case only <xmlfile> is taken into account \n"
18 str = str + " from the parameters list. This key is used by default.\n"
20 str = str + " -b Runs the Installation Wizard in the batch mode.\n"
21 str = str + " All the found parameters are taken in to account.\n"
23 str = str + " -f <xml-file> The configuration file to be parsed by the Installation Wizard.\n"
24 str = str + " If this parameter is missed then the script tries to define\n"
25 str = str + " the Red Hat version and use the corresponding xml. For example,\n"
26 str = str + " for Red Hat 8.0 config_RedHat8_0.xml file is supposed to be used\n"
27 str = str + " by default. If the appropriate xml file is not found, the config.xml\n"
28 str = str + " is used by default.\n"
30 str = str + " -t <target-dir> The target directory the products to be installed to.\n"
31 str = str + " This parameter overloads the target directory described in the\n"
32 str = str + " configuration file.\n"
34 str = str + " -tmp <tmp-dir> The directory which should be used for the temporary files.\n"
35 str = str + " This parameter overloads the temporary directory described in the\n"
36 str = str + " configuration file.\n"
38 str = str + " -h Prints this help information.\n"
41 #==============================================================
43 #==============================================================
47 #==============================================================
49 #==============================================================
50 def error_exit (str = ""):
52 if len(str): res = "\n" + str + "\n"
59 #==============================================================
60 # Cheks whether the passed parameter is a key.
61 #==============================================================
65 return re.match(r'^-[a-zA-Z]', val)
68 #==============================================================
69 # From the list of parameters extracts value following 'key'
70 #==============================================================
71 def extract_parameter ( key, args ) :
74 if ( length == 0 ) : return None
78 for i in range(0, length-1):
80 if ( is_key ( args[i+1]) ) :
81 print " No value after key ", key
85 if ( i < length - 2 and is_key ( args[i+2] ) == 0 ) : #control that only one value follows key
86 #(not a list). In this case params are correct.
87 print "Too much values after key ", key
98 #===============================================================
99 # Extracts list of values following specified 'key' from 'args[]'
100 #===============================================================
101 def extract_list (key, args) :
104 if ( args is None or lenght == 0 ):
110 for i in range(0, length) :
112 if (is_key ( args[i+1])) :
115 for i in range (i+1, lenght):
116 if is_key(args[i]) : break
120 return list; #empty list is returned if no values after key
123 #==============================================================
124 # Method find the $key in the list and return 1 if success
126 #==============================================================
127 def find_key (key, argv) :
129 if (not is_key(key)) : return 0
136 #==============================================================
137 # Parse the list of parameters
138 #==============================================================
139 def parse_parameters (args) :
141 if find_key('-h', args) :
142 print get_help_info();
146 xmlfile = extract_parameter("-f", args)
147 target_dir = extract_parameter("-t", args)
148 tmp_dir = extract_parameter("-tmp", args)
149 if find_key('-b', args):
152 return [xmlfile, target_dir, tmp_dir, is_gui]
155 #=================================================================
156 # Checks boolean value: yes/no, true/false, 1/0
157 #=================================================================
159 return str(val).strip() in ["yes","true", "1"]
161 #=================================================================
162 # The first algorithm to create the dependencies list by their level
163 #=================================================================
164 def get_next_level(list, products):
168 expr = "(" + list[0].name
169 for i in range(1, len(list)):
170 expr = expr + "|"+ list[i].name
173 #expr=re.compile(expr)
175 for product in products:
176 deps = re.sub(r'\s+', "", product.dependencies)
177 if re.search(expr, deps):
178 result.append(product)
183 def create_levels(prods):
186 products = copy.deepcopy(prods)
190 #1. find the products with empty lists of dependencies
192 for product in products:
193 if len(re.sub(r'\s', "", product.dependencies)) == 0 :
197 raise RuntimeError, "Products that depend on nothing are not found"
199 # remove the first level products from the common list of products
200 for product in list :
201 products.remove(product)
206 while (len(products)) :
207 res = get_next_level(list, products)
209 raise RuntimeError, "Empty list of products is found"
212 products.remove(product)
219 for i in result.keys():
220 for product in result[i]:
221 str = str + product.name + " "
225 #=================================================================
226 # The second algorithm
227 #=================================================================
228 def get_dependencies_set(prods) :
232 products = copy.deepcopy(prods)
236 while (len(products)) :
239 #find the products with empty list of dependencies
240 for product in products:
241 product.dependencies = re.sub(r'\s+$', "", product.dependencies)
242 product.dependencies = re.sub(r'^\s+', "", product.dependencies)
244 if len(product.dependencies) == 0 :
245 tmplist.append(product);
246 deps = deps + " " + product.name
250 #remove the products names from other products dependencies
252 products.remove(item)
254 regexpr1 = "((^|,(\s+)?)"+item.name+"$|^"+item.name+"(\s+)?,(\s+)?)"
255 regexpr2 = ",(\s+)?"+item.name+"(\s+)?,(\s+)?"
257 for product in products:
258 product.dependencies = re.sub(r'\s+$', "", product.dependencies)
259 product.dependencies = re.sub(r'^\s+', "", product.dependencies)
261 product.dependencies = re.sub(regexpr1, "", product.dependencies)
262 product.dependencies = re.sub(regexpr2, ",", product.dependencies)
266 #=================================================================
267 # The third algorithm (same as SALOME_InstallWizard.cxx uses)
268 #=================================================================
269 def get_dependencies(prods) :
271 for product in prods:
272 if check_bool(product.disable): continue
274 deps = product.dependencies.split(",")
276 if dep and not dep in list:
279 if product and not product in list:
280 list.append( product.name )
282 return " ".join( list )
284 #==============================================================
285 # Creates dir, returns the part of path that existed early.
286 # Access may be defined.
287 #==============================================================
288 def create_dir (directory, access = 0777):
290 dirs = string.split(directory, "/")
291 existing = ""; dir = ""
294 if len(item) == 0: continue
296 if os.path.exists(dir):
299 os.mkdir(dir, access )
300 #root= existing + "/"+item
301 if dir == existing + "/"+item :
303 #else : root = existing
307 #==============================================================
309 #==============================================================
312 def __init__(self, theName,
315 theSupportred = None,
317 theDependencies = None,
318 theInstalldiskspace = None,
319 theTemporarydiskspace = None,
321 thePickUpEnvironment = None):
325 self.version = theVersion
326 self.install = theInstall
327 self.supported = theSupportred
328 self.disable = theDisable
329 self.dependencies = theDependencies
330 self.installdiskspace = theInstalldiskspace
331 self.temporarydiskspace = theTemporarydiskspace
332 self.script = theScript
333 self.pickupEnv = thePickUpEnvironment
335 #===================================================================
337 #===================================================================
339 def __init__(self, theVersion='', theCaption='', theCopyright='', theLicense='', theOS=''):
340 self.version = theVersion
341 self.caption = theCaption
342 self.copyright = theCopyright
343 self.license = theLicense
347 #===================================================================
349 #===================================================================
351 def __init__(self, theTargetdir=".", theTmpdir="."):
352 self.targetdir = theTargetdir
353 self.tmpdir = theTmpdir
356 #===================================================================
358 #===================================================================
359 class ConfigParser(xmllib.XMLParser):
361 xmllib.XMLParser.__init__(self)
363 self.currentdata = []
367 def handle_data(self, data):
368 self.currentdata.append(data)
370 def start_product(self, attrs):
371 aProduct = Product(attrs['name'],
376 attrs['dependancies'],
377 attrs['installdiskspace'],
378 attrs['temporarydiskspace'],
381 if attrs.has_key( 'pickupenv' ):
382 aProduct.pickupEnv = attrs['pickupenv']
384 self.products.append(aProduct)
386 def end_product(self):
389 def start_config(self, attrs):
390 self.config = Config(attrs['version'],
395 def end_config(self):
398 def start_path (self, attrs):
399 self.path = Path(attrs['targetdir'],
405 def getProduct(self, prod):
406 for product in self.products:
407 if product.name == prod:
411 #================================================================
412 # get the path using file name
413 #================================================================
414 def get_current_path(file_name):
415 path = "."; where = string.rfind(file_name,'/');
417 path = (file_name)[: where]
419 path = os.getcwd() + "/"
422 #================================================================
423 # checks dir existing
424 #================================================================
426 if (os.path.islink(dir)) :
427 native_dir = os.readlink(dir)
428 if not os.path.exists(native_dir) :
429 print "Invalid link " + dir + ". The directory " + native_dir + " a link points to does not exist."
432 if not os.path.exists(dir):
433 print "Directory " + dir + " does not exist"
437 #===============================================================
438 # Checks the disk space. Exit from interpreter if there is no
440 #===============================================================
441 def check_disk_space(products, script_dir, target_dir, tmp_dir):
442 import re, string, os
445 for product in products :
446 product.install = re.sub(r'^\s+', "", product.install)
447 product.install = re.sub(r'\s+$', "", product.install)
449 if check_bool(product.disable) or product.install == "use native" or product.install == "not install":
451 spaces = string.split( product.installdiskspace,',')
452 prod_space = spaces[0]
453 if (len(spaces) == 2 ) and (product.install == "install binaries") :
454 prod_space = spaces[1]
455 install_space = install_space + string.atoi(prod_space)
456 temporary_space = temporary_space + string.atoi(product.temporarydiskspace)
457 res = os.system(scripts_dir + "checkSize.sh" + " " + target_dir + " " + str(install_space))
459 print "There is no enough space to install the products."
462 res = os.system(scripts_dir + "checkSize.sh" + " " + tmp_dir + " " + str(temporary_space))
464 print "There is no enough space for tmp directory."
469 #===============================================================
470 # Removes temporary directory
471 #===============================================================
472 def remove_dir( rem_path = "" ):
473 if len( rem_path ) and os.path.exists( rem_path ):
474 os.system( "rm -rf " + rem_path )
477 #================================================================
479 #================================================================
481 if __name__ == "__main__":
483 cur_dir = get_current_path(sys.argv[0])
485 [xml_file, target_dir, tmp_dir, is_gui] = parse_parameters(sys.argv)
487 # define xml file -----------------
488 if (xml_file is None) :
489 xml_file_name = "config.xml"
490 if os.path.exists("/etc/redhat-release"):
491 data = open("/etc/redhat-release").readline()
492 res = re.search(r'Red\s+Hat\s+Linux\s+release\s+([\d.]*)', data)
494 num = re.sub("[.]", "_", (res.groups())[0])
495 filename = "config_RedHat" + num+ ".xml"
496 if (os.path.exists(cur_dir + filename)):
497 xml_file_name = filename
499 res = re.search(r'Mandrakelinux\s+release\s+([\d.]*)', data)
501 num = re.sub("[.]", "_", (res.groups())[0])
502 filename = "config_Mandrake" + num+ ".xml"
503 if (os.path.exists(cur_dir + filename)):
504 xml_file_name = filename
505 xml_file = cur_dir + xml_file_name
507 if xml_file is None or not os.path.exists(xml_file):
508 error_exit("No xml file is found, try to run with options -f <xmlfile>")
510 if not os.access(xml_file, os.R_OK):
511 print "There is no read access for "+ xml_file
514 #---- GUI ----------------
517 if not env.has_key("PATH") :
519 if not env.has_key("LD_LIBRARY_PATH") :
520 env["LD_LIBRARY_PATH"]= ""
522 env["LD_LIBRARY_PATH"] = ".:" + env["LD_LIBRARY_PATH"]
523 env["PATH"] = ".:"+ env["PATH"]
525 sys.exit(os.system("cd " + cur_dir + "; ./bin/SALOME_InstallWizard " + xml_file +"&"))
529 #----- TUI ---------------------
531 #print xml_file, target_dir, tmp_dir, is_gui
533 message("Parsing xml config file: " + xml_file)
534 filehandle = open(xml_file)
535 data = filehandle.read()
537 parser = ConfigParser()
543 what_to_do = { "install sources" : "install_source",
544 "install binaries" : "install_binary",
545 "use native" : "try_native",
546 "not install" : "try_preinstalled"}
547 # define tmp dir -----------
549 tmp_dir = parser.path.tmpdir
550 if tmp_dir is None or tmp_dir == "":
553 tmp_dir = tmp_dir + "/INSTALLWORK" + str(random.randint(10000,100000))
555 if not os.path.exists(tmp_dir):
556 message("Creating temporary directory: " + tmp_dir); root_path = create_dir(tmp_dir, 0755) ;
557 if not os.path.exists(tmp_dir):
558 error_exit("Invalid temporary directory " + tmp_dir + ". Use -tmp key to set directory or correct xml file\n\n")
560 if not os.access(tmp_dir, os.W_OK) :
561 str = "There is no write permissions for directory " + tmp_dir + ". Use -tmp key to set temporary directory or correct xml file"
564 # define target dir --------
565 if target_dir is None:
566 target_dir = parser.path.targetdir
568 if not os.path.exists(target_dir):
569 message("Creating target directory: " + target_dir); create_dir(target_dir, 0755)
570 if not os.path.exists(target_dir):
571 error_exit("Invalid target directory " + target_dir + ". Use -t key to set directory or correct xml file\n\n")
573 if not os.access(target_dir, os.W_OK) :
574 str = "There is no write permissions for directory " + target_dir + ". Use -t key to set target directory or correct xml file."
577 # define products dir ------------
578 source_dir = cur_dir + "Products" ;
579 if not check_dir(source_dir):
580 remove_dir(root_path)
583 subdir = {"install sources" : "SOURCES",
584 "install binaries" : "BINARIES/"+parser.config.os,
589 # define scripts dir ------------
590 scripts_dir = cur_dir + "config_files/"
591 if not check_dir(scripts_dir):
592 remove_dir(root_path)
594 os.chdir(scripts_dir)
596 #list_of_dep = create_levels(parser.products)
597 #list_of_dep = get_dependencies_set(parser.products)
598 list_of_dep = get_dependencies(parser.products)
600 message("Checking available disk space")
601 if check_disk_space(parser.products, scripts_dir, target_dir, tmp_dir) :
603 message("Starting...")
605 for product in parser.products :
607 if check_bool(product.disable): continue
609 message("Processing " + product.name + "...")
610 cmd = scripts_dir + product.script + " " + \
611 what_to_do[product.install]+ " " + \
613 source_dir + "/" + subdir[product.install] + " " + \
615 '"' + list_of_dep + '"' + " " + \
619 #if res : break; # try_preinstalled can return 1
622 message("Creating environment files")
623 for product in parser.products :
625 if check_bool(product.disable): continue
627 if check_bool(product.pickupEnv):
628 cmd = scripts_dir + product.script + " " + \
631 source_dir + "/" + subdir[product.install] + " " + \
633 '"' + list_of_dep + '"' + " " + \
638 message("Cleaning temporary directory")
639 remove_dir(root_path)