def is_owner_for_dir(path): head, tail = os.path.split(path) try: if os.stat(head).st_uid == os.geteuid(): return True except FileNotFoundError: path = head pass while True: head, tail = os.path.split(path) if head == path: break path = head if os.path.isdir(head): try: if os.stat(head).st_uid == os.geteuid(): return True except FileNotFoundError: path = head err.log(path) continue return False
def check_dependencies_helper(self, dep): dep_check = True log.log("Checking dep " + dep.name) if dep.name in self.installed_deps and self.installed_deps[ dep.name].provided == True: if self.installed_deps[dep.name].dep.version.eq( self.deps_dict[dep.name].version): log.log("Dependency (" + dep.name + ") found!") return dep_check else: err.log( "Dependency (" + dep.name + ") installed but dependency needs a different version!") if dep.is_executable(): installed_dep = dep.find_executable() if installed_dep: if installed_dep.dep.version.eq(dep.version): log.log("Dependency (" + dep.name + ") found!") self.installed_deps[dep.name] = dep.find_executable() else: res = self.check_dependency(dep) dep_check = dep_check and res else: res = self.check_dependency(dep) dep_check = dep_check and res else: res = self.check_dependency(dep) dep_check = dep_check and res return dep_check
def check_dependency(self, dep): packman = str_to_class(get_package_manager_name())() res, path = packman.check_dependency(dep) if res == package_manager.installed: log.log("Dependency (" + dep.name + ") found!") self.installed_deps[dep.name] = installed_dependency( dep, False, path, None) return True elif res == package_manager.not_installed: warn.log("Dependency (" + dep.name + " : " + dep.version.to_string() + ") not found!") if (self.source_only or not packman.install_dependency(dep) and not self.check_only): ### fallback self.download_dependency_and_unpack(dep, len(dep.bin_url) > 0) sb = source_builder() installed = None if dep.bin_url: installed = sb.install_binary(self.installed_deps, dep, self.prefix) else: sb.build(self.installed_deps, dep) installed = sb.install(self.installed_deps, dep, self.prefix) self.installed_deps[dep.name] = installed else: self.installed_deps[dep.name] = installed_dependency( dep, True, packman.prefix(dep), "") return True elif res == package_manager.not_satisfiable: if (not self.check_only): warn.log("Dependency (" + dep.name + " : " + dep.version.to_string() + ") not satisfiable, doing a source install!") self.download_dependency_and_unpack(dep, len(dep.bin_url) > 0) sb = source_builder() installed = None if dep.bin_url: installed = sb.install_binary(self.installed_deps, dep, self.prefix) else: sb.build(self.installed_deps, dep) installed = sb.install(self.installed_deps, dep, self.prefix) self.installed_deps[dep.name] = installed return True else: warn.log("Dependency (" + dep.name + " : " + dep.version.to_string() + ") not satisfiable!") return False else: err.log("Dependency (" + dep.name + ") installed but version is too low (" + packman.get_version(dep).to_string() + ")") return False
def install(self, installed, dep, prefix): old_cwd = os.getcwd() tmpd = os.path.join(get_temp_dir(), dep.name) atexit.register(lambda: cleanup_tmp(tmpd)) full_dir = os.path.join(tmpd, os.listdir(tmpd)[0], "build") os.chdir(full_dir) builder = str_to_class(dep.build_sys)() if not builder.install(installed, dep): err.log("Install stage for " + dep.name + " failed!") os.chdir(old_cwd) filenames = list() old_filenames = list() for path, subdirs, files in os.walk(tmpd + ".tmp"): for fn in files: full_path = os.path.join(path, fn) rel_path = os.path.relpath(full_path, tmpd + ".tmp") fixed_path = os.path.join(prefix, rel_path) filenames.append(fixed_path) old_filenames.append(full_path) ### for now ignore errors when making the prefix folder try: os.makedirs(prefix) except: pass ### check whether currently installed if self.check_install(prefix, filenames): err.log("Dependency " + dep.name + " is already installed at location " + prefix) for i in range(0, len(filenames)): try: os.makedirs(os.path.dirname(filenames[i])) except: pass ### install to the prefix shutil.move(old_filenames[i], filenames[i]) ### chown back to user if prefix is home rooted if os.path.commonprefix([get_home_dir(), filenames[i]]): os.chown(prefix, get_original_uid()[0], get_original_uid()[1]) for root, dirs, files in os.walk(prefix): for d in dirs: os.chown(os.path.join(root, d), get_original_uid()[0], get_original_uid()[1]) for f in files: os.chown(os.path.join(root, f), get_original_uid()[0], get_original_uid()[1]) return installed_dependency(dep, True, prefix, filenames)
def get_package_manager_name(): if is_linux(): eo, ee, ec = execute_cmd("apt-get --help") if ec == 0: return "apt_get" else: eo, ee, ec = execute_cmd("yum --help") if ec == 0: return "yum" else: err.log("Unsupported Linux distributiosn") elif is_apple(): return "brew" else: err.log("Unsupported OS")
def download_dependency_and_unpack(self, dep, use_bin): log.log("Downloading " + dep.name) url = "" if use_bin: url = dep.bin_url else: url = dep.source_url if not url: err.log("Can't do a source build for dependency (" + dep.name + ")") base_name = os.path.basename(url) urllib.request.urlretrieve(url, os.path.join(self.temp_dir, base_name)) shutil.unpack_archive(os.path.join(self.temp_dir, base_name), os.path.join(self.temp_dir, dep.name)) log.log("Unpacked " + base_name) os.remove(os.path.join(self.temp_dir, base_name))
def remove_dependency(self, dep_name, strict): packman = str_to_class(get_package_manager_name())() if not dep_name in self.installed_deps: err.log("Dependency (" + dep_name + ") not installed") dep = self.installed_deps[dep_name].dep if self.installed_deps[dep_name].files: log.log("Removing " + dep.name + " " + dep.package_name) for f in self.installed_deps[dep_name].files: try: os.remove(f) os.rmdir(os.path.dirname(f)) except: pass elif self.installed_deps[dep_name].provided: packman.remove_dependency(dep) else: if strict: err.log("Dependency (" + dep_name + ") was not installed via eosio.depman") self.installed_deps.pop(dep.name, None)
def import_build_systems(): old_cwd = os.getcwd() cur_bs = "" try: prefix = os.path.dirname(os.path.realpath(__file__))+"/build_systems" try: shutil.rmtree(prefix+"/__pycache__") except: pass build_systems = os.listdir(prefix) try: for bs in build_systems: cur_bs = bs f, p, d = imp.find_module(bs[:-3], [prefix]) imp.load_module(bs[:-3], f, p, d) except Exception as ex: warn.log(str(ex)) raise ex err.log("Failed to import build system <"+cur_bs+">") except Exception as ex: warn.log(str(ex)) raise ex err.log("Failed to open package managers directory")
def build(self, installed, dep): old_cwd = os.getcwd() tmpd = os.path.join(get_temp_dir(), dep.name) atexit.register(lambda: cleanup_tmp(tmpd)) full_dir = os.path.join(tmpd, os.listdir(tmpd)[0]) os.chdir(full_dir) try: os.mkdir(os.path.join(full_dir, "build")) except: pass os.chdir("./build") builder = None if len(dep.bin_url) > 0: builder = noop_build_system() else: builder = str_to_class(dep.build_sys)() if not builder.pre_build(installed, dep): err.log("Pre-build stage for " + dep.name + " failed!") if not builder.build(installed, dep): err.log("Build stage for " + dep.name + " failed!") os.chdir(old_cwd)
def import_package_managers(): old_cwd = os.getcwd() cur_pm = "" try: prefix = os.path.dirname( os.path.realpath(__file__)) + "/package_managers" try: shutil.rmtree(prefix + "/__pycache__") except: pass package_managers = os.listdir(prefix) try: for pm in package_managers: cur_pm = pm f, p, d = imp.find_module(pm[:-3], [prefix]) imp.load_module(pm[:-3], f, p, d) except Exception as ex: warn.log(str(ex)) raise ex err.log("Failed to import package manager <" + cur_pm + ">") except Exception as ex: warn.log(str(ex)) raise ex err.log("Failed to open package managers directory")
def get_file_dir(): if is_apple() or is_linux(): return "/usr/local/etc" else: err.log("Windows is currently not supported")
def remove_dependency(self, dep): log.log("Removing " + dep.name + " " + dep.package_name) if (os.getuid() != 0): err.log("Removing via apt-get requires sudo!") eo, ee, ec = execute_cmd("apt-get --yes remove " + dep.package_name) return ec == 0
def add_repos(self): packman = str_to_class(get_package_manager_name())() for repo in self.repos: if not packman.add_repo(repo): err.log("Repo (" + repo + ") not available")
def check_if_uid_satisfied(self, pfx): self.prefix = os.path.abspath(os.path.realpath( os.path.expanduser(pfx))) if not is_owner_for_dir(self.prefix): err.log("Prefix for installation <" + self.prefix + "> needs root access, use sudo")
def get_prefix(self, dep_name): if dep_name in self.installed_deps: return self.installed_deps[dep_name].path else: err.log("Dependency (" + dep_name + ") not available")
def install_dependency(self, dep): log.log("Installing " + dep.name + " " + dep.package_name) if (os.getuid() != 0): err.log("Installing via apt-get requires sudo!") eo, ee, ec = execute_cmd("apt-get --yes install " + dep.package_name) return ec == 0
def parse(self, fname): dep_file = open(fname, "r") dep_str = "" for line in dep_file: dep_str += line tagged_dependencies = dict() dependencies = dict() repos = list() obj = self.parser.parse(dep_str) os_name, dist, ver = util.get_os() for child in obj.children: if child.data == "dependencies": for cc in child.children[1:]: dep_name = cc.children[0] is_strict = False if len(cc.children[1].children) > 3: ge, version, dep_type, build_type = cc.children[ 1].children is_strict = (str(ge) != ">=") else: version, dep_type, build_type = cc.children[1].children vers = None if version == "any": vers = dependency.version(-1, -1) else: vers = dependency.version(int(version.split(".")[0]), int(version.split(".")[1])) dependencies[str(dep_name)] = dependency.dependency( str(dep_name), vers, str(dep_type), str(build_type)) dependencies[str(dep_name)].strict = is_strict elif child.data == "urls": for cc in child.children[1:]: for ccc in cc.children[1:]: should_add = True if len(ccc.children) == 3: url_type, system_type, url = ccc.children else: url_type, system_type, constraint, url = ccc.children cons = constraint.children[0] cons = cons.lstrip('\'').rstrip('\'') should_add = eval(cons) os_str = system_type.children[0] if (len(system_type.children) > 1): os_str += "<" + system_type.children[1].children[ 0] + ">" if should_add and \ os_str == "all" or \ os_str == dist or \ os_str == dist+"<"+ver+">": if not cc.children[0] in dependencies: err.log("Dependency " + cc.children[0] + " not defined in dependencies section") if url_type == "bin": if not dependencies[cc.children[0]].bin_url: dependencies[cc.children[0]].bin_url = str( url) else: if not dependencies[cc.children[0]].source_url: dependencies[ cc.children[0]].source_url = str(url) elif child.data == "relative-prefix": print("REL") print(child.children[1:]) elif child.data == "repo": for cc in child.children[1:]: sys_type = child.children[1].children[0].children[0] sys_type += "<" + child.children[1].children[0].children[ 1].children[0] + ">" if should_add and \ sys_type == "all" or \ sys_type == dist or \ sys_type == dist+"<"+ver+">": for ccc in cc.children[1:]: repos.append( ccc.children[0].lstrip('"').rstrip('"')) elif child.data == "packages": for cc in child.children[1:]: for ccc in cc.children[1:]: should_add = True if len(ccc.children) == 2: system_type, package_name = ccc.children else: system_type, constraint, package_name = ccc.children cons = constraint.children[0] cons = cons.lstrip('\'').rstrip('\'') should_add = eval(cons) os_str = system_type.children[0] if (len(system_type.children) > 1): os_str += "<" + system_type.children[1].children[ 0] + ">" if should_add and \ os_str == "all" or \ os_str == dist or \ os_str == dist+"<"+ver+">": if not cc.children[0] in dependencies: err.log("Dependency " + cc.children[0] + " not defined in dependencies section") if dependencies[ cc.children[0]].package_name == "***": dependencies[cc.children[0]].package_name = ( package_name) elif child.data == "commands": for cc in child.children[1:]: for ccc in cc.children[1:]: should_add = True if len(ccc.children) == 3: command_type, system_type, cmd = ccc.children else: command_type, system_type, constraint, cmd = ccc.children cons = constraint.children[0] cons = cons.lstrip('\'').rstrip('\'') should_add = eval(cons) os_str = system_type.children[0] if (len(system_type.children) > 1): os_str += "<" + system_type.children[1].children[ 0] + ">" if should_add and \ os_str == "all" or \ os_str == dist or \ os_str == dist+"<"+ver+">": if not cc.children[0] in dependencies: err.log("Dependency " + cc.children[0] + " not defined in dependencies section") if command_type.children[0] == "pre-build": if not dependencies[ cc.children[0]].pre_build_cmds: dependencies[ cc.children[0]].pre_build_cmds = ( cmd.lstrip("\"").rstrip("\"")) elif command_type.children[0] == "build": if not dependencies[cc.children[0]].build_cmds: dependencies[cc.children[0]].build_cmds = ( cmd.lstrip("\"").rstrip("\"")) else: if not dependencies[ cc.children[0]].install_cmds: dependencies[ cc.children[0]].install_cmds = ( cmd.lstrip("\"").rstrip("\"")) elif child.data == "groups": for cc in child.children[1:]: group = cc.children[0].lstrip('[').rstrip(']') for ccc in cc.children[1:]: os_str = ccc.children[1].children[0] if (len(ccc.children[1].children) > 1): os_str += "<" + ccc.children[1].children[ 1].children[0] + ">" if should_add and \ os_str == "all" or \ os_str == dist or \ os_str == dist+"<"+ver+">": if not group in tagged_dependencies: tagged_dependencies[group] = list() tagged_dependencies[group].append( str(ccc.children[0])) return [dependencies, tagged_dependencies, repos]
arg_parser.add_argument('--list', dest='list', action='store_true', default=False) arg_parser.add_argument('file', type=str) args = arg_parser.parse_args() try: handler = dependency_handler(args.prefix, args.install) deps_filename = "eosio.deps" atexit.register(lambda: handler.write_installed_deps_file()) if args.verbose: verbose_log.silence = False set_log_colorize(args.no_color) if not args.file: err.log("Must specify dependency file") deps_filename = args.file handler.read_dependency_file(deps_filename) handler.read_installed_deps_file() if args.check: handler.check_only = True if not handler.check_dependencies(args.install_group): exit(-1) exit(0) if args.query: log.log(args.query + " : version (" + handler.deps_dict[args.query].version.to_string() + ") -- installed at (" + handler.get_prefix(strip(args.query)) + ")")