#!/usr/bin/python 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_dbus(check): return not os.path.exists("/usr/share/dbus-1/services/%s.service" % 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 } pre_checks = \ [{ "check": "Xvfb", "checker": "binary", "packages": { "fedora": "Xvfb", "ubuntu": "xvfb" } }, { "check": "pkg-config", "checker": "binary", "packages": { "fedora": "pkgconfig", "ubuntu": "pkgconfig" } }] checks = \ [ # Sugar buildtime { "check": "gcc", "checker": "binary", "packages": { "fedora": "gcc", "ubuntu": "gcc" } }, { "check": "autoreconf", "checker": "binary", "packages": { "fedora": "autoconf", "ubuntu": "autoconf" } }, { "check": "aclocal", "checker": "binary", "packages": { "fedora": "automake", "ubuntu": "automake" } }, { "check": "libtool", "checker": "binary", "packages": { "fedora": "libtool", "ubuntu": "libtool" } }, { "check": "icon-slicer", "checker": "binary", "packages": { "fedora": "icon-slicer", "ubuntu": "icon-slicer" } }, { "check": "intltoolize", "checker": "binary", "packages": { "fedora": "intltool", "ubuntu": "intltool" } }, { "check": "xcursorgen", "checker": "binary", "packages": { "fedora": "xorg-x11-apps", "ubuntu": "x11-apps" } }, { "check": "gnome-doc-common", "checker": "binary", "packages": { "fedora": "gnome-common", "ubuntu": "gnome-common" } }, { "check": "python2", "checker": "pkgconfig", "packages": { "fedora": "python-devel", "ubuntu": "python-dev" } }, { "check": "glib-2.0", "checker": "pkgconfig", "packages": { "fedora": "glib2-devel", "ubuntu": "libglib2.0-dev" } }, { "check": "gtk+-3.0", "checker": "pkgconfig", "packages": { "fedora": "gtk3-devel", "ubuntu": "libgtk-3-dev" } }, { "check": "sm", "checker": "pkgconfig", "packages": { "fedora": "libSM-devel", "ubuntu": "libsm-dev" } }, { "check": "ice", "checker": "pkgconfig", "packages": { "fedora": "libICE-devel", "ubuntu": "libice-dev" } }, { "check": "alsa", "checker": "pkgconfig", "packages": { "fedora": "alsa-lib-devel", "ubuntu": "libasound2-dev" } }, { "check": "librsvg-2.0", "checker": "pkgconfig", "packages": { "fedora": "librsvg2-devel", "ubuntu": "librsvg2-dev" } }, { "check": "gobject-introspection-1.0", "checker": "pkgconfig", "packages": { "fedora": "gobject-introspection-devel", "ubuntu": "libgirepository1.0-dev" } }, { "check": "pygtk-2.0", "checker": "pkgconfig", "packages": { "fedora": "pygtk2-devel", "ubuntu": "python-gtk2-dev" } }, { "check": "gconf-2.0", "checker": "pkgconfig", "packages": { "fedora": "GConf2-devel", "ubuntu": "libgconf2-dev" } }, { "check": "pycairo", "checker": "pkgconfig", "packages": { "fedora": "pycairo-devel", "ubuntu": "python-cairo-dev" } }, { "check": "icon-naming-utils", "checker": "pkgconfig", "packages": { "fedora": "icon-naming-utils", "ubuntu": "icon-naming-utils" } }, # Sugar runtime { "check": "org.freedesktop.Telepathy.AccountManager", "checker": "dbus", "packages": { "fedora": "telepathy-mission-control", "ubuntu": "telepathy-mission-control-5" } }, { "check": "dconf", "checker": "binary", "packages": { "fedora": "dconf", "ubuntu": "dconf" } }, { "check": "gnome-keyring-daemon", "checker": "binary", "packages": { "fedora": "gnome-keyring", "ubuntu": "gnome-keyring" } }, { "check": "metacity", "checker": "binary", "packages": { "fedora": "metacity", "ubuntu": "metacity" } }, { "check": "espeak", "checker": "binary", "packages": { "fedora": "espeak", "ubuntu": "espeak" } }, { "check": "import wnck", "checker": "python", "packages": { "fedora": "gnome-python2-libwnck", "ubuntu": "python-wnck" } }, { "check": "import simplejson", "checker": "python", "packages": { "fedora": "python-simplejson", "ubuntu": "python-simplejson" } }, { "check": "import hippo", "checker": "python", "packages": { "fedora": "hippo-canvas-python", "ubuntu": "python-hippocanvas" } }, { "check": "import telepathy", "checker": "python", "packages": { "fedora": "python-telepathy", "ubuntu": "python-telepathy" } }, { "check": "import cjson", "checker": "python", "packages": { "fedora": "python-cjson", "ubuntu": "python-cjson" } }, { "check": "import xapian", "checker": "python", "packages": { "fedora": "xapian-bindings-python", "ubuntu": "python-xapian" } }, { "check": "import dateutil", "checker": "python", "packages": { "fedora": "python-dateutil", "ubuntu": "python-dateutil" } }, { "check": "import gtksourceview2", "checker": "python", "packages": { "fedora": "pygtksourceview", "ubuntu": "python-gtksourceview2" } }, { "check": "import vte", "checker": "python", "packages": { "fedora": "vte", "ubuntu": "python-vte" } }, { "check": "import decorator", "checker": "python", "packages": { "fedora": "python-decorator", "ubuntu": "python-decorator" } }, { "check": "import gi", "checker": "python", "packages": { "fedora": "pygobject3", "ubuntu": "pygobject" } }, { "check": "from gi.repository import EvinceDocument", "checker": "python", "packages": { "fedora": "evince-libs", "ubuntu": "gir1.2-evince-3.0" } }, { "check": "import rsvg", "checker": "python", "packages": { "fedora": "gnome-python2-rsvg", "ubuntu": "python-rsvg" } }, { "check": "org.freedesktop.Telepathy.ConnectionManager.gabble", "checker": "dbus", "packages": { "fedora": "telepathy-gabble", "ubuntu": "telepathy-gabble" } }, { "check": "org.freedesktop.Telepathy.ConnectionManager.salut", "checker": "dbus", "packages": { "fedora": "telepathy-salut", "ubuntu": "telepathy-salut" } }, # Activities runtime { "check": "from gi.repository import WebKit", "checker": "python", "packages": { "fedora": "webkitgtk3", "ubuntu": "gir1.2-webkit-3.0" } }, { "check": "import pygst", "checker": "python", "packages": { "fedora": "gstreamer-python", "ubuntu": "python-gst0.10" } }, { "check": "video4linux2", "checker": "gstreamer", "packages": { "fedora": "gstreamer-plugins-good", "ubuntu": "gstreamer0.10-plugins-good" } }, # System modules buildtime { "check": "flex", "checker": "binary", "packages": { "fedora": "flex", "ubuntu": "flex" } }, { "check": "bison", "checker": "binary", "packages": { "fedora": "bison", "ubuntu": "bison" } }, { "check": "gtk-doc", "checker": "pkgconfig", "packages": { "fedora": "gtk-doc", "ubuntu": "gtk-doc-tools" } }, { "check": "cairo-gobject", "checker": "pkgconfig", "packages": { "fedora": "cairo-gobject-devel", "ubuntu": "libcairo2-dev" } }, # sugar-build runtime { "check": "atk-bridge", "checker": "gtkmodule", "packages": { "fedora": "at-spi2-atk", "ubuntu": "libatk-adaptor" } }, { "check": "curl", "checker": "binary", "packages": { "fedora": "curl", "ubuntu": "curl" } }, { "check": "dbus-launch", "checker": "binary", "packages": { "fedora": "dbus-x11", "ubuntu": "dbus-x11" } }, { "check": "import dogtail", "checker": "python", "packages": { "fedora": "dogtail", "ubuntu": "python-dogtail" } }, # sugar-build buildtime { "check": "xrandr", "checker": "pkgconfig", "packages": { "fedora": "libXrandr-devel", "ubuntu": "libxrandr-dev" } }, { "check": "x11", "checker": "pkgconfig", "packages": { "fedora": "libX11-devel", "ubuntu": "libx11-dev" } }, # Workarounds for distro bugs # Ubuntu: libtoolize doesn't work without installing tar { "check": "tar", "checker": "binary", "packages": { "fedora": "tar", "ubuntu": "tar" } }] 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 run_checks(distro, checks): failed_checks = [] packages = [] for check in checks: checker = checkers[check["checker"]] if checker(check["check"]): if distro in check["packages"]: packages.append(check["packages"][distro]) else: failed_checks.append(check) if packages: install_packages(distro, packages) if failed_checks: print "Failed checks\n" for check in failed_checks: print "[%s] %s" % (info["checker"], info["check"]) 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"]) release = subprocess.check_output(["lsb_release", "-sr"]) 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 == "fedora": 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() run_checks(distro, pre_checks) xvfb_proc, orig_display = start_xvfb() run_checks(distro, checks) warn_if_unsupported(distro) apply_distro_tweaks(distro) stop_xvfb(xvfb_proc, orig_display)