#!/usr/bin/python import json import os import subprocess import sys scriptdir = os.path.dirname(__file__) devnull = open("/dev/null", "w") xvfb_display = ":100" libdirs = ["lib", "lib64", "lib/x86_64-linux-gnu", "lib/i386-linux-gnu"] def check_binary(check): return subprocess.call(["which", check], stdout=devnull, stderr=subprocess.STDOUT) def check_pkgconfig(check): return subprocess.call(["pkg-config", "--exists", check]) == 1 def check_python(check): return subprocess.call(["python", "-c", check], stdout=devnull, stderr=subprocess.STDOUT) == 1 def check_gtkmodule(check): # Not sure we can do better than this, the gtkmodule stuff is private missing = True for libdir in libdirs: if os.path.exists("/usr/%s/gtk-2.0/modules/lib%s.so" % (libdir, check)): missing = False return missing def check_include(check): return not os.path.exists(os.path.join("/usr/include/", check)) def check_dbus(check): return not os.path.exists("/usr/share/dbus-1/services/%s.service" % check) def check_metacity_theme(check): return not os.path.exists("/usr/share/themes/%s/metacity-1/metacity-theme-3.xml" % check) def check_gstreamer(check): missing = True for libdir in libdirs: if os.path.exists("/usr/%s/gstreamer-0.10/libgst%s.so" % (libdir, check)): missing = False return missing checkers = { "binary": check_binary, "python": check_python, "pkgconfig": check_pkgconfig, "gtkmodule": check_gtkmodule, "dbus": check_dbus, "gstreamer": check_gstreamer, "metacity-theme": check_metacity_theme, "include": check_include } def install_packages(distro, packages): args = ["sudo"] if "SUGAR_BUILDBOT" in os.environ: print "Missing packages %s" % " ".join(packages) sys.exit(1) print "Installing required system packages" if distro == "fedora": args.extend(["yum", "install"]) elif distro == "ubuntu": args.extend(["apt-get", "install"]) args.extend(packages) subprocess.call(args) def load_deps_json(name): path = os.path.join(scriptdir, "deps", "%s.json" % name) return json.load(open(path)) def run_checks(distro, checks, packages): failed_checks = [] to_install = [] for check in checks: check_name = check["check"] checker = checkers[check["checker"]] if checker(check_name): if distro in packages[check_name]: package = packages[check_name][distro] # Might be none, if so skip on this distro if package: to_install.append(package) else: failed_checks.append(check) if to_install: install_packages(distro, to_install) if failed_checks: print "Failed checks\n" else: return True for check in failed_checks: print "[%s] %s" % (check["checker"], check["check"]) return False def start_xvfb(): xvfb_proc = subprocess.Popen(args=["Xvfb", xvfb_display], stdout=devnull, stderr=subprocess.STDOUT) orig_display = os.environ.get("DISPLAY", None) os.environ["DISPLAY"] = xvfb_display return (xvfb_proc, orig_display) def stop_xvfb(proc, orig_display): if orig_display: os.environ["DISPLAY"] = xvfb_display else: del os.environ["DISPLAY"] xvfb_proc.terminate() def check_distro(): distro = "unsupported" # Fedora try: fedora_release = open("/etc/fedora-release").read().strip() if fedora_release == "Fedora release 17 (Beefy Miracle)": distro = "fedora" except IOError: pass # Ubuntu try: distributor = subprocess.check_output(["lsb_release", "-si"]).strip() release = subprocess.check_output(["lsb_release", "-sr"]).strip() if distributor == "Ubuntu" and release == "12.04": distro = "ubuntu" except OSError: pass arch = subprocess.check_output(["uname", "-i"]).strip() if arch not in ["i386", "x86_64"]: distro = "unsupported" return distro def apply_ubuntu_tweaks(): wrapper_config = open("/etc/X11/Xwrapper.config").read() if "allowed_users=anybody" not in wrapper_config: if "SUGAR_BUILDBOT" in os.environ: print "\nPlease allow anybody to run the X server with \n" \ " sudo dpkg-reconfigure x11-common" else: print "\nWe are going to allow anybody to run the X server" ubuntu_tweaks = os.path.join(scriptdir, "ubuntu-tweaks") subprocess.call(["sudo", ubuntu_tweaks]) def apply_distro_tweaks(distro): if distro == "ubuntu": apply_ubuntu_tweaks() def warn_if_unsupported(distro): if distro == "unsupported": print "*********************************************************\n" \ "You are running an unsupported distribution. You might be\n" \ "able to make sugar work by installing or building \n" \ "packages but it certainly won't work out of the box.\n" \ "You are strongly encouraged to pick one of the supported \n" \ "distributions listed in the README.\n" \ "*********************************************************\n" distro = check_distro() packages = load_deps_json("packages") checks = load_deps_json("prerequisites") if not run_checks(distro, checks, packages): sys.exit(1) xvfb_proc, orig_display = start_xvfb() checks = [] checks.extend(load_deps_json("system-buildtime")) checks.extend(load_deps_json("system-buildtime")) checks.extend(load_deps_json("sugar-buildtime")) checks.extend(load_deps_json("sugar-build-buildtime")) checks.extend(load_deps_json("sugar-build-runtime")) checks.extend(load_deps_json("sugar-runtime")) checks.extend(load_deps_json("activities-runtime")) run_checks(distro, checks, packages) warn_if_unsupported(distro) apply_distro_tweaks(distro) stop_xvfb(xvfb_proc, orig_display)