build docker image from Isabelle application bundle for Linux;
authorwenzelm
Sat, 14 Jan 2017 20:33:55 +0100
changeset 64890 d8ccbd5305bf
parent 64889 56b52fc25c95
child 64891 d047004c1109
build docker image from Isabelle application bundle for Linux;
src/Pure/Admin/build_docker.scala
src/Pure/System/isabelle_tool.scala
src/Pure/build-jars
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Pure/Admin/build_docker.scala	Sat Jan 14 20:33:55 2017 +0100
@@ -0,0 +1,112 @@
+/*  Title:      Pure/Admin/build_docker.scala
+    Author:     Makarius
+
+Build docker image from Isabelle application bundle for Linux.
+*/
+
+package isabelle
+
+
+object Build_Docker
+{
+  private lazy val default_logic = Isabelle_System.getenv("ISABELLE_LOGIC")
+
+  def build_docker(progress: Progress,
+    app_archive: Path,
+    logic: String = default_logic,
+    output: Option[Path] = None,
+    tag: String = "",
+    verbose: Boolean = false)
+  {
+    val distname =
+    {
+      val Name = "^(Isabelle[^/]*)/?.*$".r
+      Isabelle_System.bash("tar tzf " + File.bash_path(app_archive)).check.out_lines match {
+        case Name(name) :: _ => name
+        case _ => error("Cannot determine Isabelle distribution name from " + app_archive)
+      }
+    }
+
+    val dockerfile =
+      """## Dockerfile for """ + distname + """
+
+FROM ubuntu
+SHELL ["/bin/bash", "-c"]
+
+# packages
+RUN apt-get -y update && \
+  apt-get install -y less lib32stdc++6 libwww-perl rlwrap unzip && \
+  apt-get clean
+
+# user
+RUN useradd -m isabelle && (echo isabelle:isabelle | chpasswd)
+USER isabelle
+
+# Isabelle
+WORKDIR /home/isabelle
+COPY Isabelle.tar.gz .
+RUN tar xzf Isabelle.tar.gz && \
+  mv """ + distname + """ Isabelle && \
+  rm -rf Isabelle.tar.gz Isabelle/contrib/jdk/x86-linux && \
+  perl -pi -e 's,ISABELLE_HOME_USER=.*,ISABELLE_HOME_USER="\$USER_HOME/.isabelle",g;' Isabelle/etc/settings && \
+  perl -pi -e 's,ISABELLE_LOGIC=.*,ISABELLE_LOGIC=""" + logic + """,g;' Isabelle/etc/settings && \
+  Isabelle/bin/isabelle build -s -b """ + logic + """
+
+ENTRYPOINT ["Isabelle/bin/isabelle"]
+"""
+
+    output.foreach(File.write(_, dockerfile))
+
+    Isabelle_System.with_tmp_dir("docker")(tmp_dir =>
+      {
+        File.write(tmp_dir + Path.explode("Dockerfile"), dockerfile)
+        File.copy(app_archive, tmp_dir + Path.explode("Isabelle.tar.gz"))
+
+        val quiet_option = if (verbose) "" else " -q"
+        val tag_option = if (tag == "") "" else " -t " + Bash.string(tag)
+        progress.bash("docker build" + quiet_option + tag_option + " " + File.bash_path(tmp_dir),
+          echo = true).check
+      })
+  }
+
+
+  /* Isabelle tool wrapper */
+
+  val isabelle_tool =
+    Isabelle_Tool("build_docker", "build Isabelle docker image", args =>
+    {
+      var logic = default_logic
+      var output: Option[Path] = None
+      var verbose = false
+      var tag = ""
+
+      val getopts =
+        Getopts("""
+Usage: isabelle build_docker [OPTIONS] APP_ARCHIVE
+
+  Options are:
+    -l NAME      default logic (default ISABELLE_LOGIC=""" + quote(default_logic) + """)
+    -o FILE      output generated Dockerfile
+    -t TAG       docker build tag
+    -v           verbose
+
+  Build Isabelle docker image with default logic image, using a standard
+  Isabelle application archive for Linux.
+
+  The remaining DOCKER_ARGS are passed directly to "docker build".
+""",
+          "l:" -> (arg => logic = arg),
+          "o:" -> (arg => output = Some(Path.explode(arg))),
+          "t:" -> (arg => tag = arg),
+          "v" -> (_ => verbose = true))
+
+      val more_args = getopts(args)
+      val app_archive =
+        more_args match {
+          case List(arg) => Path.explode(arg)
+          case _ => getopts.usage()
+        }
+
+      build_docker(new Console_Progress(), app_archive, logic, output, tag, verbose)
+    }, admin = true)
+}
--- a/src/Pure/System/isabelle_tool.scala	Sat Jan 14 20:22:15 2017 +0100
+++ b/src/Pure/System/isabelle_tool.scala	Sat Jan 14 20:33:55 2017 +0100
@@ -101,6 +101,7 @@
     List(
       Build.isabelle_tool,
       Build_Doc.isabelle_tool,
+      Build_Docker.isabelle_tool,
       Build_PolyML.isabelle_tool,
       Build_Stats.isabelle_tool,
       Check_Sources.isabelle_tool,
--- a/src/Pure/build-jars	Sat Jan 14 20:22:15 2017 +0100
+++ b/src/Pure/build-jars	Sat Jan 14 20:33:55 2017 +0100
@@ -10,6 +10,7 @@
 
 declare -a SOURCES=(
   Admin/build_doc.scala
+  Admin/build_docker.scala
   Admin/build_history.scala
   Admin/build_log.scala
   Admin/build_polyml.scala