def basic_options(self): """basic runtime options""" all_stops = [x[0] for x in EasyBlock.get_steps()] strictness_options = [filetools.IGNORE, filetools.WARN, filetools.ERROR] try: default_robot_path = get_paths_for("easyconfigs", robot_path=None)[0] except: self.log.warning("basic_options: unable to determine default easyconfig path") default_robot_path = False # False as opposed to None, since None is used for indicating that --robot was not used descr = ("Basic options", "Basic runtime options for EasyBuild.") opts = OrderedDict({ "only-blocks":("Only build listed blocks", None, "extend", None, "b", {'metavar':"BLOCKS"}), "force":(("Force to rebuild software even if it's already installed " "(i.e. if it can be found as module)"), None, "store_true", False, "f"), "job":("Submit the build as a job", None, "store_true", False), "skip":("Skip existing software (useful for installing additional packages)", None, "store_true", False, "k"), "robot":("Path to search for easyconfigs for missing dependencies." , None, "store_or_None", default_robot_path, "r", {'metavar':"PATH"}), "stop":("Stop the installation after certain step", "choice", "store_or_None", "unpack", "s", all_stops), "strict":("Set strictness level", "choice", "store", filetools.WARN, strictness_options), "logtostdout":("Redirect main log to stdout", None, "store_true", False, "l"), }) self.log.debug("basic_options: descr %s opts %s" % (descr, opts)) self.add_group_parser(opts, descr)
def main(testing_data=(None, None)): """ Main function: @arg options: a tuple: (options, paths, logger, logfile, hn) as defined in parse_options This function will: - read easyconfig - build software """ # disallow running EasyBuild as root if os.getuid() == 0: sys.stderr.write("ERROR: You seem to be running EasyBuild with root privileges.\n" \ "That's not wise, so let's end this here.\n" \ "Exiting.\n") sys.exit(1) # steer behavior when testing main testing = testing_data[0] is not None args, logfile = testing_data # initialise options (options, orig_paths, opt_parser, cmd_args) = eboptions.parse_options(args=args) # initialise logging for main if options.logtostdout: fancylogger.logToScreen(enable=True, stdout=True) else: if logfile is None: # mkstemp returns (fd,filename), fd is from os.open, not regular open! fd, logfile = tempfile.mkstemp(suffix='.log', prefix='easybuild-') os.close(fd) fancylogger.logToFile(logfile) print_msg('temporary log file in case of crash %s' % (logfile), log=None, silent=testing) global log log = fancylogger.getLogger(fname=False) # hello world! log.info(this_is_easybuild()) # set strictness of filetools module if options.strict: filetools.strictness = options.strict if not options.robot is None: if options.robot: log.info("Using robot path: %s" % options.robot) else: log.error("No robot path specified, and unable to determine easybuild-easyconfigs install path.") # determine easybuild-easyconfigs package install path easyconfigs_paths = get_paths_for("easyconfigs", robot_path=options.robot) easyconfigs_pkg_full_path = None if easyconfigs_paths: easyconfigs_pkg_full_path = easyconfigs_paths[0] if not options.robot: search_path = easyconfigs_pkg_full_path else: search_path = options.robot else: log.info("Failed to determine install path for easybuild-easyconfigs package.") if options.robot: easyconfigs_paths = [options.robot] + easyconfigs_paths configOptions = {} if options.pretend: configOptions['install_path'] = os.path.join(os.environ['HOME'], 'easybuildinstall') # default location of configfile is set as default in the config option config.init(options.config, **configOptions) # search for modules if options.search: search_module(search_path, options.search) # process software build specifications (if any), i.e. # software name/version, toolchain name/version, extra patches, ... (try_to_generate, software_build_specs) = process_software_build_specs(options) paths = [] if len(orig_paths) == 0: if software_build_specs.has_key('name'): paths = [obtain_path(software_build_specs, easyconfigs_paths, try_to_generate=try_to_generate, exit_on_error=not testing)] elif not any([options.aggregate_regtest, options.search, options.regtest]): print_error(("Please provide one or multiple easyconfig files, or use software build " "options to make EasyBuild search for easyconfigs"), log=log, opt_parser=opt_parser, exit_on_error=not testing) else: # look for easyconfigs with relative paths in easybuild-easyconfigs package, # unless they we found at the given relative paths if easyconfigs_pkg_full_path: # create a mapping from filename to path in easybuild-easyconfigs package install path easyconfigs_map = {} for (subpath, _, filenames) in os.walk(easyconfigs_pkg_full_path): for filename in filenames: easyconfigs_map.update({filename: os.path.join(subpath, filename)}) # try and find non-existing non-absolute eaysconfig paths in easybuild-easyconfigs package install path for i in range(len(orig_paths)): if not os.path.isabs(orig_paths[i]) and not os.path.exists(orig_paths[i]): if orig_paths[i] in easyconfigs_map: log.info("Found %s in %s: %s" % (orig_paths[i], easyconfigs_pkg_full_path, easyconfigs_map[orig_paths[i]])) orig_paths[i] = easyconfigs_map[orig_paths[i]] # indicate that specified paths do not contain generated easyconfig files paths = [(path, False) for path in orig_paths] log.debug("Paths: %s" % paths) # run regtest if options.regtest or options.aggregate_regtest: log.info("Running regression test") if paths: regtest_ok = regtest(options, [path[0] for path in paths]) else: # fallback: easybuild-easyconfigs install path regtest_ok = regtest(options, [easyconfigs_pkg_full_path]) if not regtest_ok: log.info("Regression test failed (partially)!") sys.exit(31) # exit -> 3x1t -> 31 if any([options.search, options.regtest]): cleanup_logfile_and_exit(logfile, testing, True) # building a dependency graph implies force, so that all dependencies are retained # and also skips validation of easyconfigs (e.g. checking os dependencies) validate_easyconfigs = True retain_all_deps = False if options.dep_graph: log.info("Enabling force to generate dependency graph.") options.force = True validate_easyconfigs = False retain_all_deps = True # read easyconfig files easyconfigs = [] for (path, generated) in paths: path = os.path.abspath(path) if not (os.path.exists(path)): print_error("Can't find path %s" % path) try: files = find_easyconfigs(path) for f in files: if not generated and try_to_generate and software_build_specs: ec_file = easyconfig.tweak(f, None, software_build_specs) else: ec_file = f easyconfigs.extend(process_easyconfig(ec_file, options.only_blocks, validate=validate_easyconfigs)) except IOError, err: log.error("Processing easyconfigs in path %s failed: %s" % (path, err))