Adds build functionality to the dev server. 

A few changes here. 

1. A simple webui for building packages in the source tree. 
2. A shell script that you can run on your netbook to kick of a build of a given package, download the result, and install it. 
3. Refactored update/build functionality into classes so that the build env paths can be shared. 
4. devkit.sh downloads an upsatart task that starts ssh at boot time.

More info in the dev server manual - 
https://docs.google.com/a/google.com/Doc?docid=0AT6qlIKi36JQY2M1Y3B2bWNfMTZkems5eGducg&hl=en

Review URL: http://chromereview.prom.corp.google.com/1187017

git-svn-id: svn://chrome-svn/chromeos/trunk@207 06c00378-0e64-4dae-be16-12b19f9950a1
diff --git a/buildutil.py b/buildutil.py
index 2fe36bc..1aeb27f 100644
--- a/buildutil.py
+++ b/buildutil.py
@@ -3,17 +3,117 @@
 # found in the LICENSE file.
 
 import os
+import web
+from datetime import datetime
+import time 
 
-def GetPackages():
+class BuildObject:
   """
-    Lists all of the packages that can be built with a make_pkg.sh script.
+    Common base class that defines key paths in the source tree.
   """
-  pkgs = [] 
-  cli = os.popen("find %s -name make_pkg.sh" % root_dir).read().split('\n')
-  for pkg in cli:
-    if pkg == "":
-      continue
-    pkg_name = pkg.split('/')[-2]
-    web.debug(pkg_name)
-    li.append(pkg_name)
+  def __init__(self, root_dir, static_dir):
+    self.app_id = "87efface-864d-49a5-9bb3-4b050a7c227a"
+    self.root_dir = root_dir
+    self.scripts_dir = "%s/scripts" % self.root_dir
+    self.static_dir = static_dir
+    self.x86_pkg_dir = "%s/build/x86/local_packages" % self.root_dir
+
+  def AssertSystemCallSuccess(self, err, cmd="unknown"):
+    """
+      TODO(rtc): This code should probably live somewhere else.
+    """
+    if err != 0:
+      raise Exception("%s failed to execute % cmd")
+    
+
+class BuildUtil(BuildObject):
+
+  def GetPackageName(self, pkg_path):
+    cmd = "cat %s/debian/control | grep Package | cut -d \" \" -f 2-" % pkg_path
+    return os.popen(cmd).read().strip() 
+
+  def GetLastBuildTime(self, pkg_name):
+    # TODO(rtc): convert this to local time. 
+    cmd = "stat -c %s %s/%s*" % ("%Y", self.x86_pkg_dir, pkg_name)
+    utc_time = os.popen(cmd).read().strip()
+    return datetime.fromtimestamp(int(utc_time))
+
+  def GetPackageBuildPath(self, pkg_name):
+    cmd = "stat -c %s %s/%s*" % ("%n", self.x86_pkg_dir, pkg_name)
+    return os.popen(cmd).read().strip()
+
+  def GetPackageBuildFile(self, build_path):
+    return build_path.replace(self.x86_pkg_dir + "/", "")
+
+  def BuildPackage(self, pkg="all"):
+    """
+      Builds the given package and copies the output to the static dir so that
+      it can be downloaded. 
+      
+      If pkg=all is specified then the kernel and all platform packages
+      will be built. A new system image will also be created.
+
+      If pkg=packages is specified then all platform packages
+      will be built and a new system image will be created.
+    """
+    if pkg == "all":
+      err = os.system("%s/build_all.sh" % self.scripts_dir)
+      self.AssertSystemCallSuccess(err)
+      return None
+
+    if pkg == "packages":
+      err = os.system("%s/build_platform_packages.sh" % self.scripts_dir)
+      self.AssertSystemCallSuccess(err)
+      err = os.system("%s/build_image.sh" % self.scripts_dir)
+      self.AssertSystemCallSuccess(err)
+      return None
+
+    pkg_properties = self.GetPackages().get(pkg, None)
+    if pkg_properties == None:
+      raise Exception("Unknown package name %s" % pkg)
+
+    cmd = "%s/make_pkg.sh" % pkg_properties.get("source_path")
+    err = os.system(cmd)
+    self.AssertSystemCallSuccess(err, cmd)
+
+    cmd = "cp %s %s" % (pkg_properties.get("output_path"), self.static_dir)
+    err = os.system(cmd)
+    self.AssertSystemCallSuccess(err, cmd)
+
+    return pkg_properties.get("output_file_name")
+
+
+  def GetPackages(self):
+    """
+      Lists all of the packages that can be built with a make_pkg.sh script.
+
+      Returns a dictionary with the following keys
+        name: the name of the package. 
+        build_time: the time the package was last built (in UTC).
+        source_path: the path to the package in the source tree. 
+        output_path: the path to the deb created by make_pkg.sh.
+        output_file_name: the name of the deb created by make_pkg.sh
+    """
+    pkgs = {} 
+    cli = os.popen("find %s -name make_pkg.sh" % self.root_dir).read().split('\n')
+    for pkg in cli:
+      if pkg == "":
+        continue
+      pkg_path = pkg.replace("/make_pkg.sh", "", 1)
+      pkg_name = self.GetPackageName(pkg_path)
+      if pkg_name == "":
+        web.debug("unable to find a package info for %s" % pkg_path)
+        continue
+
+      build_time = self.GetLastBuildTime(pkg_name)
+      build_path = self.GetPackageBuildPath(pkg_name)
+      build_file = self.GetPackageBuildFile(build_path)
+      pkgs[pkg_name] = {
+        "name": pkg_name,
+        "build_time": build_time,
+        "source_path": pkg_path,
+        "output_path": build_path,
+        "output_file_name": build_file
+      }
+    return pkgs