From 66dc2e7ea7011ae63e1d404ebffeaa7782a7f2f5 Mon Sep 17 00:00:00 2001 From: Daniel Narvaez Date: Wed, 14 Nov 2012 15:32:49 +0000 Subject: Refactor check-system to use a devbot module This is necessary to be able to share code, all the commands will be gradually refactored to follow this pattern. --- (limited to 'devbot/system.py') diff --git a/devbot/system.py b/devbot/system.py new file mode 100644 index 0000000..e3e5d67 --- /dev/null +++ b/devbot/system.py @@ -0,0 +1,187 @@ +import json +import os +import subprocess +import sys + +from devbot import config +from devbot import distro + +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 run_with_sudo(args): + args_with_sudo = ["sudo"] + args_with_sudo.extend(args) + + print " ".join(args_with_sudo) + subprocess.call(args_with_sudo) + +def install_packages(distro_name, packages): + if "SUGAR_BUILDBOT" in os.environ: + print "Missing packages %s" % " ".join(packages) + sys.exit(1) + + print "Installing required system packages" + + if distro_name == "fedora": + args = ["yum", "install"] + elif distro_name == "ubuntu": + args = ["apt-get", "install"] + + args.extend(packages) + run_with_sudo(args) + +def load_deps_json(name): + path = os.path.join(scriptdir, "deps", "%s.json" % name) + return json.load(open(path)) + +def run_checks(distro_name, checks, packages): + failed_checks = [] + to_install = [] + + for check in checks: + checker = checkers[check["checker"]] + if checker(check["check"]): + check_name = check.get("check_name", check["check"]) + if distro_name in packages[check_name]: + package_list = packages[check_name][distro_name] + if not isinstance(package_list, list): + package_list = [package_list] + + for package in package_list: + # Might be none, if so skip on this distro_name + if package and package not in packages: + to_install.append(package) + else: + failed_checks.append(check) + + if to_install: + install_packages(distro_name, 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(xvfb_proc, orig_display): + if orig_display: + os.environ["DISPLAY"] = xvfb_display + else: + del os.environ["DISPLAY"] + + xvfb_proc.terminate() + +def apply_ubuntu_tweaks(): + # FIXME we don't want the package to depend on external scripts + devbot_dir = os.path.abspath(os.path.dirname(__file__)) + scripts_dir = os.path.join(os.path.dirname(devbot_dir), "scripts") + + 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(scripts_dir, "ubuntu-tweaks") + run_with_sudo([ubuntu_tweaks]) + +def apply_distro_tweaks(distro_name): + if distro_name == "ubuntu": + apply_ubuntu_tweaks() + +def warn_if_unsupported(distro_name): + if distro_name == "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" + +def check(): + distro_name = distro.get_distro_name() + + packages = config.load_packages() + + checks = config.load_prerequisites() + if not run_checks(distro_name, checks, packages): + sys.exit(1) + + xvfb_proc, orig_display = start_xvfb() + + run_checks(distro_name, config.load_checks(), config.load_packages()) + + warn_if_unsupported(distro_name) + apply_distro_tweaks(distro_name) + + stop_xvfb(xvfb_proc, orig_display) -- cgit v0.9.1