src/Pure/Build/build_manager.scala
author Fabian Huch <huch@in.tum.de>
Sat, 01 Feb 2025 22:28:32 +0100
changeset 82040 0dc7b3253aaa
parent 82039 e0ba5e9850df
child 82041 e7acf8c4572e
permissions -rw-r--r--
clarified options: extra ssh connection to cluster of build_manager;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
     1
/*  Title:      Pure/Build/build_manager.scala
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
     2
    Author:     Fabian Huch, TU Muenchen
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
     3
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
     4
Isabelle manager for automated and quasi-interactive builds, with web frontend.
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
     5
*/
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
     6
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
     7
package isabelle
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
     8
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
     9
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
    10
import scala.collection.mutable
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
    11
import scala.annotation.tailrec
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
    12
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
    13
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
    14
object Build_Manager {
80344
f05a71fa1a3f tuned comments;
Fabian Huch <huch@in.tum.de>
parents: 80343
diff changeset
    15
  /** task state synchronized via db **/
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
    16
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
    17
  object Component {
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
    18
    def parse(s: String): Component =
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
    19
      space_explode('/', s) match {
80546
d507229c5771 proper parse (amending dd86d35375a7);
Fabian Huch <huch@in.tum.de>
parents: 80545
diff changeset
    20
        case name :: Nil => Component(name)
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
    21
        case name :: rev :: Nil => Component(name, rev)
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
    22
        case _ => error("Malformed component: " + quote(s))
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
    23
      }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
    24
80543
ee58db0396d8 clarified;
Fabian Huch <huch@in.tum.de>
parents: 80542
diff changeset
    25
    val Isabelle = "Isabelle"
80499
433475f17d73 clarified: components vs. extra components;
Fabian Huch <huch@in.tum.de>
parents: 80498
diff changeset
    26
    val AFP = "AFP"
433475f17d73 clarified: components vs. extra components;
Fabian Huch <huch@in.tum.de>
parents: 80498
diff changeset
    27
80543
ee58db0396d8 clarified;
Fabian Huch <huch@in.tum.de>
parents: 80542
diff changeset
    28
    def isabelle(rev: String = "") = Component(Isabelle, rev)
80499
433475f17d73 clarified: components vs. extra components;
Fabian Huch <huch@in.tum.de>
parents: 80498
diff changeset
    29
    def afp(rev: String = "") = Component(AFP, rev)
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
    30
  }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
    31
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
    32
  case class Component(name: String, rev: String = "") {
80542
dd86d35375a7 log and display components with empty (unknown) revisions to indicate that they are present;
Fabian Huch <huch@in.tum.de>
parents: 80541
diff changeset
    33
    override def toString: String = name + if_proper(rev, "/" + rev)
80407
fc26d6200560 clarified;
Fabian Huch <huch@in.tum.de>
parents: 80406
diff changeset
    34
fc26d6200560 clarified;
Fabian Huch <huch@in.tum.de>
parents: 80406
diff changeset
    35
    def is_local: Boolean = rev.isEmpty
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
    36
  }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
    37
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
    38
  sealed trait Build_Config {
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
    39
    def name: String
80499
433475f17d73 clarified: components vs. extra components;
Fabian Huch <huch@in.tum.de>
parents: 80498
diff changeset
    40
    def extra_components: List[Component]
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
    41
    def fresh_build: Boolean
80319
f83f402bc9a4 use build_cluster in ci builds;
Fabian Huch <huch@in.tum.de>
parents: 80315
diff changeset
    42
    def build_cluster: Boolean
80411
a9fce67fb8b2 overhauled ci_build: clarified, removed unused, removed implicit Jenkins assumptions;
Fabian Huch <huch@in.tum.de>
parents: 80410
diff changeset
    43
    def command(job_url: Url, build_hosts: List[Build_Cluster.Host]): String
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
    44
  }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
    45
80261
e3f472221f8f add triggers to ci jobs: on commit vs timed;
Fabian Huch <huch@in.tum.de>
parents: 80260
diff changeset
    46
  object CI_Build {
80412
a7f8249533e9 moved ci_build module to build_ci;
Fabian Huch <huch@in.tum.de>
parents: 80411
diff changeset
    47
    def apply(job: Build_CI.Job): CI_Build =
80319
f83f402bc9a4 use build_cluster in ci builds;
Fabian Huch <huch@in.tum.de>
parents: 80315
diff changeset
    48
      CI_Build(job.name, job.hosts.build_cluster, job.components.map(Component(_, "default")))
80416
c369b0419172 clarified: more operations;
Fabian Huch <huch@in.tum.de>
parents: 80414
diff changeset
    49
c369b0419172 clarified: more operations;
Fabian Huch <huch@in.tum.de>
parents: 80414
diff changeset
    50
    def task(job: Build_CI.Job): Task =
80469
a3bae6dd7344 add timeout to build manager tasks/jobs (e.g. for cluster builds that don't terminate after error on host);
Fabian Huch <huch@in.tum.de>
parents: 80468
diff changeset
    51
      Task(CI_Build(job), job.hosts.hosts_spec, job.timeout, other_settings = job.other_settings,
80416
c369b0419172 clarified: more operations;
Fabian Huch <huch@in.tum.de>
parents: 80414
diff changeset
    52
        isabelle_rev = "default")
80261
e3f472221f8f add triggers to ci jobs: on commit vs timed;
Fabian Huch <huch@in.tum.de>
parents: 80260
diff changeset
    53
  }
e3f472221f8f add triggers to ci jobs: on commit vs timed;
Fabian Huch <huch@in.tum.de>
parents: 80260
diff changeset
    54
80499
433475f17d73 clarified: components vs. extra components;
Fabian Huch <huch@in.tum.de>
parents: 80498
diff changeset
    55
  case class CI_Build(name: String, build_cluster: Boolean, extra_components: List[Component])
80319
f83f402bc9a4 use build_cluster in ci builds;
Fabian Huch <huch@in.tum.de>
parents: 80315
diff changeset
    56
    extends Build_Config {
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
    57
    def fresh_build: Boolean = true
80411
a9fce67fb8b2 overhauled ci_build: clarified, removed unused, removed implicit Jenkins assumptions;
Fabian Huch <huch@in.tum.de>
parents: 80410
diff changeset
    58
    def command(job_url: Url, build_hosts: List[Build_Cluster.Host]): String =
80412
a7f8249533e9 moved ci_build module to build_ci;
Fabian Huch <huch@in.tum.de>
parents: 80411
diff changeset
    59
      " build_ci" +
80411
a9fce67fb8b2 overhauled ci_build: clarified, removed unused, removed implicit Jenkins assumptions;
Fabian Huch <huch@in.tum.de>
parents: 80410
diff changeset
    60
      " -u " + Bash.string(job_url.toString) +
80319
f83f402bc9a4 use build_cluster in ci builds;
Fabian Huch <huch@in.tum.de>
parents: 80315
diff changeset
    61
      if_proper(build_cluster, build_hosts.map(host => " -H " + Bash.string(host.print)).mkString) +
80281
17d2f775907a add cluster/hosts configurations to build manager: allows running jobs in parallel on distinct hardware;
Fabian Huch <huch@in.tum.de>
parents: 80280
diff changeset
    62
      " " + name
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
    63
  }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
    64
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
    65
  object User_Build {
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
    66
    val name: String = "user"
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
    67
  }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
    68
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
    69
  case class User_Build(
80646
b4e116523cb6 build_manager: store submitting user;
Fabian Huch <huch@in.tum.de>
parents: 80645
diff changeset
    70
    user: String,
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
    71
    afp_rev: Option[String] = None,
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
    72
    prefs: List[Options.Spec] = Nil,
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
    73
    requirements: Boolean = false,
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
    74
    all_sessions: Boolean = false,
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
    75
    base_sessions: List[String] = Nil,
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
    76
    exclude_session_groups: List[String] = Nil,
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
    77
    exclude_sessions: List[String] = Nil,
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
    78
    session_groups: List[String] = Nil,
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
    79
    sessions: List[String] = Nil,
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
    80
    build_heap: Boolean = false,
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
    81
    clean_build: Boolean = false,
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
    82
    export_files: Boolean = false,
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
    83
    fresh_build: Boolean = false,
80254
6b3374d208b8 add verbose option to build_task;
Fabian Huch <huch@in.tum.de>
parents: 80252
diff changeset
    84
    presentation: Boolean = false,
6b3374d208b8 add verbose option to build_task;
Fabian Huch <huch@in.tum.de>
parents: 80252
diff changeset
    85
    verbose: Boolean = false
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
    86
  ) extends Build_Config {
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
    87
    def name: String = User_Build.name
80499
433475f17d73 clarified: components vs. extra components;
Fabian Huch <huch@in.tum.de>
parents: 80498
diff changeset
    88
    def extra_components: List[Component] = afp_rev.map(Component.afp).toList
80319
f83f402bc9a4 use build_cluster in ci builds;
Fabian Huch <huch@in.tum.de>
parents: 80315
diff changeset
    89
    def build_cluster: Boolean = true
80411
a9fce67fb8b2 overhauled ci_build: clarified, removed unused, removed implicit Jenkins assumptions;
Fabian Huch <huch@in.tum.de>
parents: 80410
diff changeset
    90
    def command(job_url: Url, build_hosts: List[Build_Cluster.Host]): String = {
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
    91
      " build" +
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
    92
        if_proper(afp_rev, " -A:") +
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
    93
        base_sessions.map(session => " -B " + Bash.string(session)).mkString +
80281
17d2f775907a add cluster/hosts configurations to build manager: allows running jobs in parallel on distinct hardware;
Fabian Huch <huch@in.tum.de>
parents: 80280
diff changeset
    94
        build_hosts.map(host => " -H " + Bash.string(host.print)).mkString +
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
    95
        if_proper(presentation, " -P:") +
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
    96
        if_proper(requirements, " -R") +
80422
23569f8a62e9 proper build command;
Fabian Huch <huch@in.tum.de>
parents: 80421
diff changeset
    97
        exclude_session_groups.map(session => " -X " + Bash.string(session)).mkString +
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
    98
        if_proper(all_sessions, " -a") +
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
    99
        if_proper(build_heap, " -b") +
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   100
        if_proper(clean_build, " -c") +
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   101
        if_proper(export_files, " -e") +
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   102
        if_proper(fresh_build, " -f") +
80422
23569f8a62e9 proper build command;
Fabian Huch <huch@in.tum.de>
parents: 80421
diff changeset
   103
        session_groups.map(session => " -g " + Bash.string(session)).mkString +
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   104
        Options.Spec.bash_strings(prefs, bg = true) +
80254
6b3374d208b8 add verbose option to build_task;
Fabian Huch <huch@in.tum.de>
parents: 80252
diff changeset
   105
        if_proper(verbose, " -v") +
80422
23569f8a62e9 proper build command;
Fabian Huch <huch@in.tum.de>
parents: 80421
diff changeset
   106
        exclude_sessions.map(session => " -x " + Bash.string(session)).mkString +
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   107
        sessions.map(session => " " + Bash.string(session)).mkString
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   108
    }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   109
  }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   110
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   111
  enum Priority { case low, normal, high }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   112
80339
7b948ca986ec clarified;
Fabian Huch <huch@in.tum.de>
parents: 80338
diff changeset
   113
  object Build {
7b948ca986ec clarified;
Fabian Huch <huch@in.tum.de>
parents: 80338
diff changeset
   114
    def name(kind: String, id: Long): String = kind + "/" + id
7b948ca986ec clarified;
Fabian Huch <huch@in.tum.de>
parents: 80338
diff changeset
   115
  }
80410
Fabian Huch <huch@in.tum.de>
parents: 80409
diff changeset
   116
80339
7b948ca986ec clarified;
Fabian Huch <huch@in.tum.de>
parents: 80338
diff changeset
   117
  sealed trait Build extends Name.T
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   118
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   119
  sealed case class Task(
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   120
    build_config: Build_Config,
80281
17d2f775907a add cluster/hosts configurations to build manager: allows running jobs in parallel on distinct hardware;
Fabian Huch <huch@in.tum.de>
parents: 80280
diff changeset
   121
    hosts_spec: String,
80469
a3bae6dd7344 add timeout to build manager tasks/jobs (e.g. for cluster builds that don't terminate after error on host);
Fabian Huch <huch@in.tum.de>
parents: 80468
diff changeset
   122
    timeout: Time,
80414
4b10ae56ed01 add Isabelle settings to managed tasks and ci jobs;
Fabian Huch <huch@in.tum.de>
parents: 80412
diff changeset
   123
    other_settings: List[String] = Nil,
80337
02f8a35ed8e2 clarified names: more canonical;
Fabian Huch <huch@in.tum.de>
parents: 80336
diff changeset
   124
    uuid: UUID.T = UUID.random(),
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   125
    submit_date: Date = Date.now(),
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   126
    priority: Priority = Priority.normal,
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   127
    isabelle_rev: String = ""
80339
7b948ca986ec clarified;
Fabian Huch <huch@in.tum.de>
parents: 80338
diff changeset
   128
  ) extends Build {
80337
02f8a35ed8e2 clarified names: more canonical;
Fabian Huch <huch@in.tum.de>
parents: 80336
diff changeset
   129
    def name: String = uuid.toString
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   130
    def kind: String = build_config.name
80646
b4e116523cb6 build_manager: store submitting user;
Fabian Huch <huch@in.tum.de>
parents: 80645
diff changeset
   131
    def user: Option[String] = Some(build_config).collect { case build: User_Build => build.user }
80499
433475f17d73 clarified: components vs. extra components;
Fabian Huch <huch@in.tum.de>
parents: 80498
diff changeset
   132
    def components: List[Component] = Component.isabelle(isabelle_rev) :: extra_components
433475f17d73 clarified: components vs. extra components;
Fabian Huch <huch@in.tum.de>
parents: 80498
diff changeset
   133
    def extra_components: List[Component] = build_config.extra_components
80281
17d2f775907a add cluster/hosts configurations to build manager: allows running jobs in parallel on distinct hardware;
Fabian Huch <huch@in.tum.de>
parents: 80280
diff changeset
   134
80319
f83f402bc9a4 use build_cluster in ci builds;
Fabian Huch <huch@in.tum.de>
parents: 80315
diff changeset
   135
    def build_cluster = build_config.build_cluster
80281
17d2f775907a add cluster/hosts configurations to build manager: allows running jobs in parallel on distinct hardware;
Fabian Huch <huch@in.tum.de>
parents: 80280
diff changeset
   136
    def build_hosts: List[Build_Cluster.Host] =
17d2f775907a add cluster/hosts configurations to build manager: allows running jobs in parallel on distinct hardware;
Fabian Huch <huch@in.tum.de>
parents: 80280
diff changeset
   137
      Build_Cluster.Host.parse(Registry.global, hosts_spec)
80649
f5ae78dd49d1 build_manager: display more info;
Fabian Huch <huch@in.tum.de>
parents: 80647
diff changeset
   138
f5ae78dd49d1 build_manager: display more info;
Fabian Huch <huch@in.tum.de>
parents: 80647
diff changeset
   139
    def >(t: Task): Boolean =
f5ae78dd49d1 build_manager: display more info;
Fabian Huch <huch@in.tum.de>
parents: 80647
diff changeset
   140
      priority.ordinal > t.priority.ordinal ||
f5ae78dd49d1 build_manager: display more info;
Fabian Huch <huch@in.tum.de>
parents: 80647
diff changeset
   141
        (priority == t.priority && submit_date.time < t.submit_date.time)
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   142
  }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   143
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   144
  sealed case class Job(
80337
02f8a35ed8e2 clarified names: more canonical;
Fabian Huch <huch@in.tum.de>
parents: 80336
diff changeset
   145
    uuid: UUID.T,
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   146
    kind: String,
80337
02f8a35ed8e2 clarified names: more canonical;
Fabian Huch <huch@in.tum.de>
parents: 80336
diff changeset
   147
    id: Long,
80281
17d2f775907a add cluster/hosts configurations to build manager: allows running jobs in parallel on distinct hardware;
Fabian Huch <huch@in.tum.de>
parents: 80280
diff changeset
   148
    build_cluster: Boolean,
17d2f775907a add cluster/hosts configurations to build manager: allows running jobs in parallel on distinct hardware;
Fabian Huch <huch@in.tum.de>
parents: 80280
diff changeset
   149
    hostnames: List[String],
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   150
    components: List[Component],
80469
a3bae6dd7344 add timeout to build manager tasks/jobs (e.g. for cluster builds that don't terminate after error on host);
Fabian Huch <huch@in.tum.de>
parents: 80468
diff changeset
   151
    timeout: Time,
80646
b4e116523cb6 build_manager: store submitting user;
Fabian Huch <huch@in.tum.de>
parents: 80645
diff changeset
   152
    user: Option[String],
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   153
    start_date: Date = Date.now(),
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   154
    cancelled: Boolean = false
80339
7b948ca986ec clarified;
Fabian Huch <huch@in.tum.de>
parents: 80338
diff changeset
   155
  ) extends Build { def name: String = Build.name(kind, id) }
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   156
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   157
  object Status {
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   158
    def from_result(result: Process_Result): Status = {
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   159
      if (result.ok) Status.ok
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   160
      else if (result.interrupted) Status.cancelled
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   161
      else Status.failed
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   162
    }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   163
  }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   164
80502
db89ef6a8a42 tuned whitespace;
Fabian Huch <huch@in.tum.de>
parents: 80501
diff changeset
   165
  enum Status { case ok, cancelled, aborted, failed }
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   166
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   167
  sealed case class Result(
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   168
    kind: String,
80337
02f8a35ed8e2 clarified names: more canonical;
Fabian Huch <huch@in.tum.de>
parents: 80336
diff changeset
   169
    id: Long,
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   170
    status: Status,
80342
35bee9c44e1a use build log in build manager to store meta-data persistently;
Fabian Huch <huch@in.tum.de>
parents: 80340
diff changeset
   171
    uuid: Option[UUID.T],
35bee9c44e1a use build log in build manager to store meta-data persistently;
Fabian Huch <huch@in.tum.de>
parents: 80340
diff changeset
   172
    build_host: String,
35bee9c44e1a use build log in build manager to store meta-data persistently;
Fabian Huch <huch@in.tum.de>
parents: 80340
diff changeset
   173
    start_date: Date,
35bee9c44e1a use build log in build manager to store meta-data persistently;
Fabian Huch <huch@in.tum.de>
parents: 80340
diff changeset
   174
    end_date: Option[Date],
35bee9c44e1a use build log in build manager to store meta-data persistently;
Fabian Huch <huch@in.tum.de>
parents: 80340
diff changeset
   175
    isabelle_version: Option[String],
35bee9c44e1a use build log in build manager to store meta-data persistently;
Fabian Huch <huch@in.tum.de>
parents: 80340
diff changeset
   176
    afp_version: Option[String],
80646
b4e116523cb6 build_manager: store submitting user;
Fabian Huch <huch@in.tum.de>
parents: 80645
diff changeset
   177
    user: Option[String],
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   178
    serial: Long = 0,
80499
433475f17d73 clarified: components vs. extra components;
Fabian Huch <huch@in.tum.de>
parents: 80498
diff changeset
   179
  ) extends Build {
433475f17d73 clarified: components vs. extra components;
Fabian Huch <huch@in.tum.de>
parents: 80498
diff changeset
   180
    def name: String = Build.name(kind, id)
433475f17d73 clarified: components vs. extra components;
Fabian Huch <huch@in.tum.de>
parents: 80498
diff changeset
   181
    def components: List[Component] =
433475f17d73 clarified: components vs. extra components;
Fabian Huch <huch@in.tum.de>
parents: 80498
diff changeset
   182
      isabelle_version.map(Component.isabelle).toList ::: afp_version.map(Component.afp).toList
433475f17d73 clarified: components vs. extra components;
Fabian Huch <huch@in.tum.de>
parents: 80498
diff changeset
   183
  }
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   184
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   185
  object State {
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   186
    def max_serial(serials: Iterable[Long]): Long = serials.maxOption.getOrElse(0L)
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   187
    def inc_serial(serial: Long): Long = {
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   188
      require(serial < Long.MaxValue, "number overflow")
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   189
      serial + 1
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   190
    }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   191
80272
9f89b3c41460 clarified signature;
wenzelm
parents: 80271
diff changeset
   192
    type Pending = Name.Data[Task]
9f89b3c41460 clarified signature;
wenzelm
parents: 80271
diff changeset
   193
    type Running = Name.Data[Job]
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   194
    type Finished = Map[String, Result]
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   195
  }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   196
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   197
  sealed case class State(
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   198
    serial: Long = 0,
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   199
    pending: State.Pending = Map.empty,
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   200
    running: State.Running = Map.empty,
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   201
    finished: State.Finished = Map.empty
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   202
  ) {
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   203
    def next_serial: Long = State.inc_serial(serial)
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   204
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   205
    def add_pending(task: Task): State = copy(pending = pending + (task.name -> task))
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   206
    def remove_pending(name: String): State = copy(pending = pending - name)
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   207
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   208
    def num_builds = running.size + finished.size
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   209
80281
17d2f775907a add cluster/hosts configurations to build manager: allows running jobs in parallel on distinct hardware;
Fabian Huch <huch@in.tum.de>
parents: 80280
diff changeset
   210
    def next(build_hosts: List[Build_Cluster.Host]): Option[Task] = {
17d2f775907a add cluster/hosts configurations to build manager: allows running jobs in parallel on distinct hardware;
Fabian Huch <huch@in.tum.de>
parents: 80280
diff changeset
   211
      val cluster_running = running.values.exists(_.build_cluster)
80346
b5b2f651a263 proper available hosts;
Fabian Huch <huch@in.tum.de>
parents: 80344
diff changeset
   212
      val available = build_hosts.map(_.hostname).toSet -- running.values.flatMap(_.hostnames).toSet
80281
17d2f775907a add cluster/hosts configurations to build manager: allows running jobs in parallel on distinct hardware;
Fabian Huch <huch@in.tum.de>
parents: 80280
diff changeset
   213
      val ready =
17d2f775907a add cluster/hosts configurations to build manager: allows running jobs in parallel on distinct hardware;
Fabian Huch <huch@in.tum.de>
parents: 80280
diff changeset
   214
        for {
17d2f775907a add cluster/hosts configurations to build manager: allows running jobs in parallel on distinct hardware;
Fabian Huch <huch@in.tum.de>
parents: 80280
diff changeset
   215
          (_, task) <- pending
17d2f775907a add cluster/hosts configurations to build manager: allows running jobs in parallel on distinct hardware;
Fabian Huch <huch@in.tum.de>
parents: 80280
diff changeset
   216
          if !task.build_cluster || !cluster_running
17d2f775907a add cluster/hosts configurations to build manager: allows running jobs in parallel on distinct hardware;
Fabian Huch <huch@in.tum.de>
parents: 80280
diff changeset
   217
          if task.build_hosts.map(_.hostname).forall(available.contains)
17d2f775907a add cluster/hosts configurations to build manager: allows running jobs in parallel on distinct hardware;
Fabian Huch <huch@in.tum.de>
parents: 80280
diff changeset
   218
        } yield task
17d2f775907a add cluster/hosts configurations to build manager: allows running jobs in parallel on distinct hardware;
Fabian Huch <huch@in.tum.de>
parents: 80280
diff changeset
   219
17d2f775907a add cluster/hosts configurations to build manager: allows running jobs in parallel on distinct hardware;
Fabian Huch <huch@in.tum.de>
parents: 80280
diff changeset
   220
      if (ready.isEmpty) None
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   221
      else {
80281
17d2f775907a add cluster/hosts configurations to build manager: allows running jobs in parallel on distinct hardware;
Fabian Huch <huch@in.tum.de>
parents: 80280
diff changeset
   222
        val priority = ready.map(_.priority).maxBy(_.ordinal)
17d2f775907a add cluster/hosts configurations to build manager: allows running jobs in parallel on distinct hardware;
Fabian Huch <huch@in.tum.de>
parents: 80280
diff changeset
   223
        ready.filter(_.priority == priority).toList.sortBy(_.submit_date)(Date.Ordering).headOption
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   224
      }
80281
17d2f775907a add cluster/hosts configurations to build manager: allows running jobs in parallel on distinct hardware;
Fabian Huch <huch@in.tum.de>
parents: 80280
diff changeset
   225
    }
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   226
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   227
    def add_running(job: Job): State = copy(running = running + (job.name -> job))
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   228
    def remove_running(name: String): State = copy(running = running - name)
80468
8ae5312032cc clarified: more operations;
Fabian Huch <huch@in.tum.de>
parents: 80467
diff changeset
   229
    def cancel_running(name: String): State =
8ae5312032cc clarified: more operations;
Fabian Huch <huch@in.tum.de>
parents: 80467
diff changeset
   230
      running.get(name) match {
8ae5312032cc clarified: more operations;
Fabian Huch <huch@in.tum.de>
parents: 80467
diff changeset
   231
        case Some(job) => copy(running = (running - name) + (name -> job.copy(cancelled = true)))
8ae5312032cc clarified: more operations;
Fabian Huch <huch@in.tum.de>
parents: 80467
diff changeset
   232
        case None => this
8ae5312032cc clarified: more operations;
Fabian Huch <huch@in.tum.de>
parents: 80467
diff changeset
   233
      }
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   234
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   235
    def add_finished(result: Result): State = copy(finished = finished + (result.name -> result))
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   236
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   237
    lazy val kinds = (
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   238
      pending.values.map(_.kind) ++
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   239
      running.values.map(_.kind) ++
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   240
      finished.values.map(_.kind)).toList.distinct
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   241
80337
02f8a35ed8e2 clarified names: more canonical;
Fabian Huch <huch@in.tum.de>
parents: 80336
diff changeset
   242
    def next_id(kind: String): Long = {
02f8a35ed8e2 clarified names: more canonical;
Fabian Huch <huch@in.tum.de>
parents: 80336
diff changeset
   243
      val serials = get_finished(kind).map(_.id) ::: get_running(kind).map(_.id)
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   244
      State.inc_serial(State.max_serial(serials))
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   245
    }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   247
    def get_running(kind: String): List[Job] =
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   248
      (for ((_, job) <- running if job.kind == kind) yield job).toList
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   249
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   250
    def get_finished(kind: String): List[Result] =
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   251
      (for ((_, result) <- finished if result.kind == kind) yield result).toList
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   252
80339
7b948ca986ec clarified;
Fabian Huch <huch@in.tum.de>
parents: 80338
diff changeset
   253
    def get(name: String): Option[Build] =
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   254
      pending.get(name).orElse(running.get(name)).orElse(finished.get(name))
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   255
80339
7b948ca986ec clarified;
Fabian Huch <huch@in.tum.de>
parents: 80338
diff changeset
   256
    def get(uuid: UUID.T): Option[Build] =
80337
02f8a35ed8e2 clarified names: more canonical;
Fabian Huch <huch@in.tum.de>
parents: 80336
diff changeset
   257
      pending.values.find(_.uuid == uuid).orElse(
02f8a35ed8e2 clarified names: more canonical;
Fabian Huch <huch@in.tum.de>
parents: 80336
diff changeset
   258
        running.values.find(_.uuid == uuid)).orElse(
02f8a35ed8e2 clarified names: more canonical;
Fabian Huch <huch@in.tum.de>
parents: 80336
diff changeset
   259
        finished.values.find(_.uuid.contains(uuid)))
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   260
  }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   261
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   262
80344
f05a71fa1a3f tuned comments;
Fabian Huch <huch@in.tum.de>
parents: 80343
diff changeset
   263
  /** SQL data model **/
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   264
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   265
  object private_data extends SQL.Data("isabelle_build_manager") {
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   266
    /* tables */
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   267
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   268
    override lazy val tables: SQL.Tables =
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   269
      SQL.Tables(State.table, Pending.table, Running.table, Finished.table)
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   270
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   271
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   272
    /* state */
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   273
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   274
    object State {
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   275
      val serial = SQL.Column.long("serial").make_primary_key
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   276
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   277
      val table = make_table(List(serial), name = "state")
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   278
    }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   279
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   280
    def read_serial(db: SQL.Database): Long =
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   281
      db.execute_query_statementO[Long](
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   282
        State.table.select(List(State.serial.max)),
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   283
        _.long(State.serial)).getOrElse(0L)
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   284
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   285
    def pull_state(db: SQL.Database, state: State): State = {
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   286
      val serial_db = read_serial(db)
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   287
      if (serial_db == state.serial) state
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   288
      else {
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   289
        val serial = serial_db max state.serial
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   290
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   291
        val pending = pull_pending(db)
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   292
        val running = pull_running(db)
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   293
        val finished = pull_finished(db, state.finished)
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   294
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   295
        state.copy(serial = serial, pending = pending, running = running, finished = finished)
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   296
      }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   297
    }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   298
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   299
    def push_state(db: SQL.Database, old_state: State, state: State): State = {
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   300
      val finished = push_finished(db, state.finished)
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   301
      val updates =
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   302
        List(
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   303
          update_pending(db, old_state.pending, state.pending),
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   304
          update_running(db, old_state.running, state.running),
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   305
        ).filter(_.defined)
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   306
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   307
      if (updates.isEmpty && finished == old_state.finished) state
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   308
      else {
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   309
        val serial = state.next_serial
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   310
        db.execute_statement(State.table.delete(State.serial.where_equal(old_state.serial)))
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   311
        db.execute_statement(State.table.insert(), body =
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   312
          { (stmt: SQL.Statement) =>
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   313
            stmt.long(1) = serial
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   314
          })
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   315
        state.copy(serial = serial, finished = finished)
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   316
      }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   317
    }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   318
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   319
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   320
    /* pending */
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   321
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   322
    object Pending {
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   323
      val kind = SQL.Column.string("kind")
80281
17d2f775907a add cluster/hosts configurations to build manager: allows running jobs in parallel on distinct hardware;
Fabian Huch <huch@in.tum.de>
parents: 80280
diff changeset
   324
      val build_cluster = SQL.Column.bool("build_cluster")
17d2f775907a add cluster/hosts configurations to build manager: allows running jobs in parallel on distinct hardware;
Fabian Huch <huch@in.tum.de>
parents: 80280
diff changeset
   325
      val hosts_spec = SQL.Column.string("hosts_spec")
80469
a3bae6dd7344 add timeout to build manager tasks/jobs (e.g. for cluster builds that don't terminate after error on host);
Fabian Huch <huch@in.tum.de>
parents: 80468
diff changeset
   326
      val timeout = SQL.Column.long("timeout")
80414
4b10ae56ed01 add Isabelle settings to managed tasks and ci jobs;
Fabian Huch <huch@in.tum.de>
parents: 80412
diff changeset
   327
      val other_settings = SQL.Column.string("other_settings")
80337
02f8a35ed8e2 clarified names: more canonical;
Fabian Huch <huch@in.tum.de>
parents: 80336
diff changeset
   328
      val uuid = SQL.Column.string("uuid").make_primary_key
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   329
      val submit_date = SQL.Column.date("submit_date")
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   330
      val priority = SQL.Column.string("priority")
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   331
      val isabelle_rev = SQL.Column.string("isabelle_rev")
80499
433475f17d73 clarified: components vs. extra components;
Fabian Huch <huch@in.tum.de>
parents: 80498
diff changeset
   332
      val extra_components = SQL.Column.string("extra_components")
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   333
80646
b4e116523cb6 build_manager: store submitting user;
Fabian Huch <huch@in.tum.de>
parents: 80645
diff changeset
   334
      val user = SQL.Column.string("user")
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   335
      val prefs = SQL.Column.string("prefs")
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   336
      val requirements = SQL.Column.bool("requirements")
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   337
      val all_sessions = SQL.Column.bool("all_sessions")
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   338
      val base_sessions = SQL.Column.string("base_sessions")
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   339
      val exclude_session_groups = SQL.Column.string("exclude_session_groups")
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   340
      val exclude_sessions = SQL.Column.string("exclude_sessions")
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   341
      val session_groups = SQL.Column.string("session_groups")
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   342
      val sessions = SQL.Column.string("sessions")
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   343
      val build_heap = SQL.Column.bool("build_heap")
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   344
      val clean_build = SQL.Column.bool("clean_build")
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   345
      val export_files = SQL.Column.bool("export_files")
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   346
      val fresh_build = SQL.Column.bool("fresh_build")
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   347
      val presentation = SQL.Column.bool("presentation")
80254
6b3374d208b8 add verbose option to build_task;
Fabian Huch <huch@in.tum.de>
parents: 80252
diff changeset
   348
      val verbose = SQL.Column.bool("verbose")
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   349
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   350
      val table =
80469
a3bae6dd7344 add timeout to build manager tasks/jobs (e.g. for cluster builds that don't terminate after error on host);
Fabian Huch <huch@in.tum.de>
parents: 80468
diff changeset
   351
        make_table(List(kind, build_cluster, hosts_spec, timeout, other_settings, uuid, submit_date,
80646
b4e116523cb6 build_manager: store submitting user;
Fabian Huch <huch@in.tum.de>
parents: 80645
diff changeset
   352
          priority, isabelle_rev, extra_components, user, prefs, requirements, all_sessions,
80499
433475f17d73 clarified: components vs. extra components;
Fabian Huch <huch@in.tum.de>
parents: 80498
diff changeset
   353
          base_sessions, exclude_session_groups, exclude_sessions, session_groups, sessions,
433475f17d73 clarified: components vs. extra components;
Fabian Huch <huch@in.tum.de>
parents: 80498
diff changeset
   354
          build_heap, clean_build, export_files, fresh_build, presentation, verbose),
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   355
        name = "pending")
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   356
    }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   357
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   358
    def pull_pending(db: SQL.Database): Build_Manager.State.Pending =
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   359
      db.execute_query_statement(Pending.table.select(), Map.from[String, Task], get =
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   360
        { res =>
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   361
          val kind = res.string(Pending.kind)
80281
17d2f775907a add cluster/hosts configurations to build manager: allows running jobs in parallel on distinct hardware;
Fabian Huch <huch@in.tum.de>
parents: 80280
diff changeset
   362
          val build_cluster = res.bool(Pending.build_cluster)
17d2f775907a add cluster/hosts configurations to build manager: allows running jobs in parallel on distinct hardware;
Fabian Huch <huch@in.tum.de>
parents: 80280
diff changeset
   363
          val hosts_spec = res.string(Pending.hosts_spec)
80469
a3bae6dd7344 add timeout to build manager tasks/jobs (e.g. for cluster builds that don't terminate after error on host);
Fabian Huch <huch@in.tum.de>
parents: 80468
diff changeset
   364
          val timeout = Time.ms(res.long(Pending.timeout))
80414
4b10ae56ed01 add Isabelle settings to managed tasks and ci jobs;
Fabian Huch <huch@in.tum.de>
parents: 80412
diff changeset
   365
          val other_settings = split_lines(res.string(Pending.other_settings))
80337
02f8a35ed8e2 clarified names: more canonical;
Fabian Huch <huch@in.tum.de>
parents: 80336
diff changeset
   366
          val uuid = res.string(Pending.uuid)
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   367
          val submit_date = res.date(Pending.submit_date)
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   368
          val priority = Priority.valueOf(res.string(Pending.priority))
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   369
          val isabelle_rev = res.string(Pending.isabelle_rev)
80499
433475f17d73 clarified: components vs. extra components;
Fabian Huch <huch@in.tum.de>
parents: 80498
diff changeset
   370
          val extra_components =
433475f17d73 clarified: components vs. extra components;
Fabian Huch <huch@in.tum.de>
parents: 80498
diff changeset
   371
            space_explode(',', res.string(Pending.extra_components)).map(Component.parse)
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   372
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   373
          val build_config =
80499
433475f17d73 clarified: components vs. extra components;
Fabian Huch <huch@in.tum.de>
parents: 80498
diff changeset
   374
            if (kind != User_Build.name) CI_Build(kind, build_cluster, extra_components)
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   375
            else {
80646
b4e116523cb6 build_manager: store submitting user;
Fabian Huch <huch@in.tum.de>
parents: 80645
diff changeset
   376
              val user = res.string(Pending.user)
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   377
              val prefs = Options.Spec.parse(res.string(Pending.prefs))
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   378
              val requirements = res.bool(Pending.requirements)
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   379
              val all_sessions = res.bool(Pending.all_sessions)
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   380
              val base_sessions = space_explode(',', res.string(Pending.base_sessions))
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   381
              val exclude_session_groups =
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   382
                space_explode(',', res.string(Pending.exclude_session_groups))
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   383
              val exclude_sessions = space_explode(',', res.string(Pending.exclude_sessions))
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   384
              val session_groups = space_explode(',', res.string(Pending.session_groups))
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   385
              val sessions = space_explode(',', res.string(Pending.sessions))
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   386
              val build_heap = res.bool(Pending.build_heap)
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   387
              val clean_build = res.bool(Pending.clean_build)
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   388
              val export_files = res.bool(Pending.export_files)
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   389
              val fresh_build = res.bool(Pending.fresh_build)
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   390
              val presentation = res.bool(Pending.presentation)
80254
6b3374d208b8 add verbose option to build_task;
Fabian Huch <huch@in.tum.de>
parents: 80252
diff changeset
   391
              val verbose = res.bool(Pending.verbose)
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   392
80499
433475f17d73 clarified: components vs. extra components;
Fabian Huch <huch@in.tum.de>
parents: 80498
diff changeset
   393
              val afp_rev = extra_components.find(_.name == Component.AFP).map(_.rev)
80646
b4e116523cb6 build_manager: store submitting user;
Fabian Huch <huch@in.tum.de>
parents: 80645
diff changeset
   394
              User_Build(user, afp_rev, prefs, requirements, all_sessions, base_sessions,
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   395
                exclude_session_groups, exclude_sessions, session_groups, sessions, build_heap,
80254
6b3374d208b8 add verbose option to build_task;
Fabian Huch <huch@in.tum.de>
parents: 80252
diff changeset
   396
                clean_build, export_files, fresh_build, presentation, verbose)
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   397
            }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   398
80469
a3bae6dd7344 add timeout to build manager tasks/jobs (e.g. for cluster builds that don't terminate after error on host);
Fabian Huch <huch@in.tum.de>
parents: 80468
diff changeset
   399
          val task = Task(build_config, hosts_spec, timeout, other_settings, UUID.make(uuid),
a3bae6dd7344 add timeout to build manager tasks/jobs (e.g. for cluster builds that don't terminate after error on host);
Fabian Huch <huch@in.tum.de>
parents: 80468
diff changeset
   400
            submit_date, priority, isabelle_rev)
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   401
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   402
          task.name -> task
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   403
        })
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   404
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   405
    def update_pending(
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   406
      db: SQL.Database,
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   407
      old_pending: Build_Manager.State.Pending,
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   408
      pending: Build_Manager.State.Pending
80274
cff00b3dddf5 clarified names;
wenzelm
parents: 80272
diff changeset
   409
    ): Update = {
cff00b3dddf5 clarified names;
wenzelm
parents: 80272
diff changeset
   410
      val update = Update.make(old_pending, pending)
80337
02f8a35ed8e2 clarified names: more canonical;
Fabian Huch <huch@in.tum.de>
parents: 80336
diff changeset
   411
      val delete = update.delete.map(old_pending(_).uuid.toString)
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   412
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   413
      if (update.deletes)
80337
02f8a35ed8e2 clarified names: more canonical;
Fabian Huch <huch@in.tum.de>
parents: 80336
diff changeset
   414
        db.execute_statement(Pending.table.delete(Pending.uuid.where_member(delete)))
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   415
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   416
      if (update.inserts) {
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   417
        db.execute_batch_statement(Pending.table.insert(), batch =
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   418
          for (name <- update.insert) yield { (stmt: SQL.Statement) =>
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   419
            val task = pending(name)
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   420
            stmt.string(1) = task.kind
80281
17d2f775907a add cluster/hosts configurations to build manager: allows running jobs in parallel on distinct hardware;
Fabian Huch <huch@in.tum.de>
parents: 80280
diff changeset
   421
            stmt.bool(2) = task.build_cluster
17d2f775907a add cluster/hosts configurations to build manager: allows running jobs in parallel on distinct hardware;
Fabian Huch <huch@in.tum.de>
parents: 80280
diff changeset
   422
            stmt.string(3) = task.hosts_spec
80469
a3bae6dd7344 add timeout to build manager tasks/jobs (e.g. for cluster builds that don't terminate after error on host);
Fabian Huch <huch@in.tum.de>
parents: 80468
diff changeset
   423
            stmt.long(4) = task.timeout.ms
a3bae6dd7344 add timeout to build manager tasks/jobs (e.g. for cluster builds that don't terminate after error on host);
Fabian Huch <huch@in.tum.de>
parents: 80468
diff changeset
   424
            stmt.string(5) = cat_lines(task.other_settings)
a3bae6dd7344 add timeout to build manager tasks/jobs (e.g. for cluster builds that don't terminate after error on host);
Fabian Huch <huch@in.tum.de>
parents: 80468
diff changeset
   425
            stmt.string(6) = task.uuid.toString
a3bae6dd7344 add timeout to build manager tasks/jobs (e.g. for cluster builds that don't terminate after error on host);
Fabian Huch <huch@in.tum.de>
parents: 80468
diff changeset
   426
            stmt.date(7) = task.submit_date
a3bae6dd7344 add timeout to build manager tasks/jobs (e.g. for cluster builds that don't terminate after error on host);
Fabian Huch <huch@in.tum.de>
parents: 80468
diff changeset
   427
            stmt.string(8) = task.priority.toString
a3bae6dd7344 add timeout to build manager tasks/jobs (e.g. for cluster builds that don't terminate after error on host);
Fabian Huch <huch@in.tum.de>
parents: 80468
diff changeset
   428
            stmt.string(9) = task.isabelle_rev
80499
433475f17d73 clarified: components vs. extra components;
Fabian Huch <huch@in.tum.de>
parents: 80498
diff changeset
   429
            stmt.string(10) = task.extra_components.mkString(",")
80646
b4e116523cb6 build_manager: store submitting user;
Fabian Huch <huch@in.tum.de>
parents: 80645
diff changeset
   430
            stmt.string(11) = task.user
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   431
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   432
            def get[A](f: User_Build => A): Option[A] =
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   433
              task.build_config match {
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   434
                case user_build: User_Build => Some(f(user_build))
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   435
                case _ => None
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   436
              }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   437
80646
b4e116523cb6 build_manager: store submitting user;
Fabian Huch <huch@in.tum.de>
parents: 80645
diff changeset
   438
            stmt.string(12) = get(user_build => user_build.prefs.map(_.print).mkString(","))
b4e116523cb6 build_manager: store submitting user;
Fabian Huch <huch@in.tum.de>
parents: 80645
diff changeset
   439
            stmt.bool(13) = get(_.requirements)
b4e116523cb6 build_manager: store submitting user;
Fabian Huch <huch@in.tum.de>
parents: 80645
diff changeset
   440
            stmt.bool(14) = get(_.all_sessions)
b4e116523cb6 build_manager: store submitting user;
Fabian Huch <huch@in.tum.de>
parents: 80645
diff changeset
   441
            stmt.string(15) = get(_.base_sessions.mkString(","))
b4e116523cb6 build_manager: store submitting user;
Fabian Huch <huch@in.tum.de>
parents: 80645
diff changeset
   442
            stmt.string(16) = get(_.exclude_session_groups.mkString(","))
b4e116523cb6 build_manager: store submitting user;
Fabian Huch <huch@in.tum.de>
parents: 80645
diff changeset
   443
            stmt.string(17) = get(_.exclude_sessions.mkString(","))
b4e116523cb6 build_manager: store submitting user;
Fabian Huch <huch@in.tum.de>
parents: 80645
diff changeset
   444
            stmt.string(18) = get(_.session_groups.mkString(","))
b4e116523cb6 build_manager: store submitting user;
Fabian Huch <huch@in.tum.de>
parents: 80645
diff changeset
   445
            stmt.string(19) = get(_.sessions.mkString(","))
b4e116523cb6 build_manager: store submitting user;
Fabian Huch <huch@in.tum.de>
parents: 80645
diff changeset
   446
            stmt.bool(20) = get(_.build_heap)
b4e116523cb6 build_manager: store submitting user;
Fabian Huch <huch@in.tum.de>
parents: 80645
diff changeset
   447
            stmt.bool(21) = get(_.clean_build)
b4e116523cb6 build_manager: store submitting user;
Fabian Huch <huch@in.tum.de>
parents: 80645
diff changeset
   448
            stmt.bool(22) = get(_.export_files)
b4e116523cb6 build_manager: store submitting user;
Fabian Huch <huch@in.tum.de>
parents: 80645
diff changeset
   449
            stmt.bool(23) = get(_.fresh_build)
b4e116523cb6 build_manager: store submitting user;
Fabian Huch <huch@in.tum.de>
parents: 80645
diff changeset
   450
            stmt.bool(24) = get(_.presentation)
b4e116523cb6 build_manager: store submitting user;
Fabian Huch <huch@in.tum.de>
parents: 80645
diff changeset
   451
            stmt.bool(25) = get(_.verbose)
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   452
          })
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   453
      }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   454
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   455
      update
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   456
    }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   457
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   458
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   459
    /* running */
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   460
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   461
    object Running {
80337
02f8a35ed8e2 clarified names: more canonical;
Fabian Huch <huch@in.tum.de>
parents: 80336
diff changeset
   462
      val uuid = SQL.Column.string("uuid").make_primary_key
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   463
      val kind = SQL.Column.string("kind")
80337
02f8a35ed8e2 clarified names: more canonical;
Fabian Huch <huch@in.tum.de>
parents: 80336
diff changeset
   464
      val id = SQL.Column.long("id")
80281
17d2f775907a add cluster/hosts configurations to build manager: allows running jobs in parallel on distinct hardware;
Fabian Huch <huch@in.tum.de>
parents: 80280
diff changeset
   465
      val build_cluster = SQL.Column.bool("build_cluster")
17d2f775907a add cluster/hosts configurations to build manager: allows running jobs in parallel on distinct hardware;
Fabian Huch <huch@in.tum.de>
parents: 80280
diff changeset
   466
      val hostnames = SQL.Column.string("hostnames")
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   467
      val components = SQL.Column.string("components")
80469
a3bae6dd7344 add timeout to build manager tasks/jobs (e.g. for cluster builds that don't terminate after error on host);
Fabian Huch <huch@in.tum.de>
parents: 80468
diff changeset
   468
      val timeout = SQL.Column.long("timeout")
80646
b4e116523cb6 build_manager: store submitting user;
Fabian Huch <huch@in.tum.de>
parents: 80645
diff changeset
   469
      val user = SQL.Column.string("user")
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   470
      val start_date = SQL.Column.date("start_date")
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   471
      val cancelled = SQL.Column.bool("cancelled")
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   472
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   473
      val table =
80646
b4e116523cb6 build_manager: store submitting user;
Fabian Huch <huch@in.tum.de>
parents: 80645
diff changeset
   474
        make_table(List(uuid, kind, id, build_cluster, hostnames, components, timeout, user,
b4e116523cb6 build_manager: store submitting user;
Fabian Huch <huch@in.tum.de>
parents: 80645
diff changeset
   475
          start_date, cancelled),
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   476
        name = "running")
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   477
    }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   478
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   479
    def pull_running(db: SQL.Database): Build_Manager.State.Running =
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   480
      db.execute_query_statement(Running.table.select(), Map.from[String, Job], get =
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   481
        { res =>
80337
02f8a35ed8e2 clarified names: more canonical;
Fabian Huch <huch@in.tum.de>
parents: 80336
diff changeset
   482
          val uuid = res.string(Running.uuid)
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   483
          val kind = res.string(Running.kind)
80337
02f8a35ed8e2 clarified names: more canonical;
Fabian Huch <huch@in.tum.de>
parents: 80336
diff changeset
   484
          val id = res.long(Running.id)
80281
17d2f775907a add cluster/hosts configurations to build manager: allows running jobs in parallel on distinct hardware;
Fabian Huch <huch@in.tum.de>
parents: 80280
diff changeset
   485
          val build_cluster = res.bool(Running.build_cluster)
17d2f775907a add cluster/hosts configurations to build manager: allows running jobs in parallel on distinct hardware;
Fabian Huch <huch@in.tum.de>
parents: 80280
diff changeset
   486
          val hostnames = space_explode(',', res.string(Running.hostnames))
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   487
          val components = space_explode(',', res.string(Running.components)).map(Component.parse)
80469
a3bae6dd7344 add timeout to build manager tasks/jobs (e.g. for cluster builds that don't terminate after error on host);
Fabian Huch <huch@in.tum.de>
parents: 80468
diff changeset
   488
          val timeout = Time.ms(res.long(Running.timeout))
80646
b4e116523cb6 build_manager: store submitting user;
Fabian Huch <huch@in.tum.de>
parents: 80645
diff changeset
   489
          val user = res.get_string(Running.user)
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   490
          val start_date = res.date(Running.start_date)
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   491
          val cancelled = res.bool(Running.cancelled)
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   492
80499
433475f17d73 clarified: components vs. extra components;
Fabian Huch <huch@in.tum.de>
parents: 80498
diff changeset
   493
          val job = Job(UUID.make(uuid), kind, id, build_cluster, hostnames, components, timeout,
80646
b4e116523cb6 build_manager: store submitting user;
Fabian Huch <huch@in.tum.de>
parents: 80645
diff changeset
   494
            user, start_date, cancelled)
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   495
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   496
          job.name -> job
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   497
        })
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   498
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   499
    def update_running(
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   500
      db: SQL.Database,
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   501
      old_running: Build_Manager.State.Running,
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   502
      running: Build_Manager.State.Running
80274
cff00b3dddf5 clarified names;
wenzelm
parents: 80272
diff changeset
   503
    ): Update = {
cff00b3dddf5 clarified names;
wenzelm
parents: 80272
diff changeset
   504
      val update = Update.make(old_running, running)
80337
02f8a35ed8e2 clarified names: more canonical;
Fabian Huch <huch@in.tum.de>
parents: 80336
diff changeset
   505
      val delete = update.delete.map(old_running(_).uuid.toString)
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   506
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   507
      if (update.deletes)
80337
02f8a35ed8e2 clarified names: more canonical;
Fabian Huch <huch@in.tum.de>
parents: 80336
diff changeset
   508
        db.execute_statement(Running.table.delete(Running.uuid.where_member(delete)))
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   509
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   510
      if (update.inserts) {
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   511
        db.execute_batch_statement(Running.table.insert(), batch =
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   512
          for (name <- update.insert) yield { (stmt: SQL.Statement) =>
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   513
            val job = running(name)
80337
02f8a35ed8e2 clarified names: more canonical;
Fabian Huch <huch@in.tum.de>
parents: 80336
diff changeset
   514
            stmt.string(1) = job.uuid.toString
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   515
            stmt.string(2) = job.kind
80337
02f8a35ed8e2 clarified names: more canonical;
Fabian Huch <huch@in.tum.de>
parents: 80336
diff changeset
   516
            stmt.long(3) = job.id
80499
433475f17d73 clarified: components vs. extra components;
Fabian Huch <huch@in.tum.de>
parents: 80498
diff changeset
   517
            stmt.bool(4) = job.build_cluster
433475f17d73 clarified: components vs. extra components;
Fabian Huch <huch@in.tum.de>
parents: 80498
diff changeset
   518
            stmt.string(5) = job.hostnames.mkString(",")
433475f17d73 clarified: components vs. extra components;
Fabian Huch <huch@in.tum.de>
parents: 80498
diff changeset
   519
            stmt.string(6) = job.components.mkString(",")
433475f17d73 clarified: components vs. extra components;
Fabian Huch <huch@in.tum.de>
parents: 80498
diff changeset
   520
            stmt.long(7) = job.timeout.ms
80646
b4e116523cb6 build_manager: store submitting user;
Fabian Huch <huch@in.tum.de>
parents: 80645
diff changeset
   521
            stmt.string(8) = job.user
b4e116523cb6 build_manager: store submitting user;
Fabian Huch <huch@in.tum.de>
parents: 80645
diff changeset
   522
            stmt.date(9) = job.start_date
b4e116523cb6 build_manager: store submitting user;
Fabian Huch <huch@in.tum.de>
parents: 80645
diff changeset
   523
            stmt.bool(10) = job.cancelled
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   524
          })
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   525
      }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   526
      update
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   527
    }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   528
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   529
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   530
    /* finished */
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   531
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   532
    object Finished {
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   533
      val kind = SQL.Column.string("kind")
80337
02f8a35ed8e2 clarified names: more canonical;
Fabian Huch <huch@in.tum.de>
parents: 80336
diff changeset
   534
      val id = SQL.Column.long("id")
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   535
      val status = SQL.Column.string("status")
80337
02f8a35ed8e2 clarified names: more canonical;
Fabian Huch <huch@in.tum.de>
parents: 80336
diff changeset
   536
      val uuid = SQL.Column.string("uuid")
80342
35bee9c44e1a use build log in build manager to store meta-data persistently;
Fabian Huch <huch@in.tum.de>
parents: 80340
diff changeset
   537
      val build_host = SQL.Column.string("build_host")
35bee9c44e1a use build log in build manager to store meta-data persistently;
Fabian Huch <huch@in.tum.de>
parents: 80340
diff changeset
   538
      val start_date = SQL.Column.date("start_date")
35bee9c44e1a use build log in build manager to store meta-data persistently;
Fabian Huch <huch@in.tum.de>
parents: 80340
diff changeset
   539
      val end_date = SQL.Column.date("end_date")
35bee9c44e1a use build log in build manager to store meta-data persistently;
Fabian Huch <huch@in.tum.de>
parents: 80340
diff changeset
   540
      val isabelle_version = SQL.Column.string("isabelle_version")
35bee9c44e1a use build log in build manager to store meta-data persistently;
Fabian Huch <huch@in.tum.de>
parents: 80340
diff changeset
   541
      val afp_version = SQL.Column.string("afp_version")
80646
b4e116523cb6 build_manager: store submitting user;
Fabian Huch <huch@in.tum.de>
parents: 80645
diff changeset
   542
      val user = SQL.Column.string("user")
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   543
      val serial = SQL.Column.long("serial").make_primary_key
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   544
80342
35bee9c44e1a use build log in build manager to store meta-data persistently;
Fabian Huch <huch@in.tum.de>
parents: 80340
diff changeset
   545
      val table =
35bee9c44e1a use build log in build manager to store meta-data persistently;
Fabian Huch <huch@in.tum.de>
parents: 80340
diff changeset
   546
        make_table(
35bee9c44e1a use build log in build manager to store meta-data persistently;
Fabian Huch <huch@in.tum.de>
parents: 80340
diff changeset
   547
          List(kind, id, status, uuid, build_host, start_date, end_date, isabelle_version,
80646
b4e116523cb6 build_manager: store submitting user;
Fabian Huch <huch@in.tum.de>
parents: 80645
diff changeset
   548
            afp_version, user, serial),
80342
35bee9c44e1a use build log in build manager to store meta-data persistently;
Fabian Huch <huch@in.tum.de>
parents: 80340
diff changeset
   549
          name = "finished")
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   550
    }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   551
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   552
    def read_finished_serial(db: SQL.Database): Long =
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   553
      db.execute_query_statementO[Long](
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   554
        Finished.table.select(List(Finished.serial.max)),
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   555
        _.long(Finished.serial)).getOrElse(0L)
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   556
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   557
    def pull_finished(
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   558
      db: SQL.Database,
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   559
      finished: Build_Manager.State.Finished
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   560
    ): Build_Manager.State.Finished = {
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   561
      val max_serial0 = Build_Manager.State.max_serial(finished.values.map(_.serial))
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   562
      val max_serial1 = read_finished_serial(db)
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   563
      val missing = (max_serial0 + 1) to max_serial1
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   564
      finished ++ db.execute_query_statement(
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   565
        Finished.table.select(sql = Finished.serial.where_member_long(missing)),
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   566
        Map.from[String, Result], get =
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   567
        { res =>
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   568
          val kind = res.string(Finished.kind)
80337
02f8a35ed8e2 clarified names: more canonical;
Fabian Huch <huch@in.tum.de>
parents: 80336
diff changeset
   569
          val id = res.long(Finished.id)
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   570
          val status = Status.valueOf(res.string(Finished.status))
80337
02f8a35ed8e2 clarified names: more canonical;
Fabian Huch <huch@in.tum.de>
parents: 80336
diff changeset
   571
          val uuid = res.get_string(Finished.uuid).map(UUID.make)
80342
35bee9c44e1a use build log in build manager to store meta-data persistently;
Fabian Huch <huch@in.tum.de>
parents: 80340
diff changeset
   572
          val build_host = res.string(Finished.build_host)
35bee9c44e1a use build log in build manager to store meta-data persistently;
Fabian Huch <huch@in.tum.de>
parents: 80340
diff changeset
   573
          val start_date = res.date(Finished.start_date)
35bee9c44e1a use build log in build manager to store meta-data persistently;
Fabian Huch <huch@in.tum.de>
parents: 80340
diff changeset
   574
          val end_date = res.get_date(Finished.end_date)
35bee9c44e1a use build log in build manager to store meta-data persistently;
Fabian Huch <huch@in.tum.de>
parents: 80340
diff changeset
   575
          val isabelle_version = res.get_string(Finished.isabelle_version)
35bee9c44e1a use build log in build manager to store meta-data persistently;
Fabian Huch <huch@in.tum.de>
parents: 80340
diff changeset
   576
          val afp_version = res.get_string(Finished.afp_version)
80646
b4e116523cb6 build_manager: store submitting user;
Fabian Huch <huch@in.tum.de>
parents: 80645
diff changeset
   577
          val user = res.get_string(Finished.user)
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   578
          val serial = res.long(Finished.serial)
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   579
80342
35bee9c44e1a use build log in build manager to store meta-data persistently;
Fabian Huch <huch@in.tum.de>
parents: 80340
diff changeset
   580
          val result = Result(kind, id, status, uuid, build_host, start_date, end_date,
80646
b4e116523cb6 build_manager: store submitting user;
Fabian Huch <huch@in.tum.de>
parents: 80645
diff changeset
   581
            isabelle_version, afp_version, user, serial)
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   582
          result.name -> result
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   583
        }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   584
      )
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   585
    }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   586
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   587
    def push_finished(
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   588
      db: SQL.Database,
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   589
      finished: Build_Manager.State.Finished
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   590
    ): Build_Manager.State.Finished = {
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   591
      val (insert0, old) = finished.partition(_._2.serial == 0L)
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   592
      val max_serial = Build_Manager.State.max_serial(finished.map(_._2.serial))
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   593
      val insert =
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   594
        for (((_, result), n) <- insert0.zipWithIndex)
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   595
        yield result.copy(serial = max_serial + 1 + n)
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   596
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   597
      if (insert.nonEmpty)
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   598
        db.execute_batch_statement(Finished.table.insert(), batch =
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   599
          for (result <- insert) yield { (stmt: SQL.Statement) =>
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   600
            stmt.string(1) = result.kind
80337
02f8a35ed8e2 clarified names: more canonical;
Fabian Huch <huch@in.tum.de>
parents: 80336
diff changeset
   601
            stmt.long(2) = result.id
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   602
            stmt.string(3) = result.status.toString
80337
02f8a35ed8e2 clarified names: more canonical;
Fabian Huch <huch@in.tum.de>
parents: 80336
diff changeset
   603
            stmt.string(4) = result.uuid.map(_.toString)
80342
35bee9c44e1a use build log in build manager to store meta-data persistently;
Fabian Huch <huch@in.tum.de>
parents: 80340
diff changeset
   604
            stmt.string(5) = result.build_host
35bee9c44e1a use build log in build manager to store meta-data persistently;
Fabian Huch <huch@in.tum.de>
parents: 80340
diff changeset
   605
            stmt.date(6) = result.start_date
35bee9c44e1a use build log in build manager to store meta-data persistently;
Fabian Huch <huch@in.tum.de>
parents: 80340
diff changeset
   606
            stmt.date(7) = result.end_date
35bee9c44e1a use build log in build manager to store meta-data persistently;
Fabian Huch <huch@in.tum.de>
parents: 80340
diff changeset
   607
            stmt.string(8) = result.isabelle_version
35bee9c44e1a use build log in build manager to store meta-data persistently;
Fabian Huch <huch@in.tum.de>
parents: 80340
diff changeset
   608
            stmt.string(9) = result.afp_version
80646
b4e116523cb6 build_manager: store submitting user;
Fabian Huch <huch@in.tum.de>
parents: 80645
diff changeset
   609
            stmt.string(10) = result.user
b4e116523cb6 build_manager: store submitting user;
Fabian Huch <huch@in.tum.de>
parents: 80645
diff changeset
   610
            stmt.long(11) = result.serial
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   611
          })
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   612
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   613
      old ++ insert.map(result => result.serial.toString -> result)
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   614
    }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   615
  }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   616
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   617
80497
bd00bdf39c86 clarified build report;
Fabian Huch <huch@in.tum.de>
parents: 80470
diff changeset
   618
  /** build reports **/
bd00bdf39c86 clarified build report;
Fabian Huch <huch@in.tum.de>
parents: 80470
diff changeset
   619
bd00bdf39c86 clarified build report;
Fabian Huch <huch@in.tum.de>
parents: 80470
diff changeset
   620
  object Report {
80533
464266fc956e store hg log in addition to diff;
Fabian Huch <huch@in.tum.de>
parents: 80532
diff changeset
   621
    case class Data(
464266fc956e store hg log in addition to diff;
Fabian Huch <huch@in.tum.de>
parents: 80532
diff changeset
   622
      build_log: String,
464266fc956e store hg log in addition to diff;
Fabian Huch <huch@in.tum.de>
parents: 80532
diff changeset
   623
      component_logs: List[(String, String)],
464266fc956e store hg log in addition to diff;
Fabian Huch <huch@in.tum.de>
parents: 80532
diff changeset
   624
      component_diffs: List[(String, String)])
80497
bd00bdf39c86 clarified build report;
Fabian Huch <huch@in.tum.de>
parents: 80470
diff changeset
   625
  }
bd00bdf39c86 clarified build report;
Fabian Huch <huch@in.tum.de>
parents: 80470
diff changeset
   626
bd00bdf39c86 clarified build report;
Fabian Huch <huch@in.tum.de>
parents: 80470
diff changeset
   627
  case class Report(kind: String, id: Long, dir: Path) {
bd00bdf39c86 clarified build report;
Fabian Huch <huch@in.tum.de>
parents: 80470
diff changeset
   628
    private val log_name = "build-manager"
80531
Fabian Huch <huch@in.tum.de>
parents: 80518
diff changeset
   629
    private val diff_ext = "diff"
80533
464266fc956e store hg log in addition to diff;
Fabian Huch <huch@in.tum.de>
parents: 80532
diff changeset
   630
    private val log_ext = "log"
80497
bd00bdf39c86 clarified build report;
Fabian Huch <huch@in.tum.de>
parents: 80470
diff changeset
   631
bd00bdf39c86 clarified build report;
Fabian Huch <huch@in.tum.de>
parents: 80470
diff changeset
   632
    private def log_file = dir + Path.basic(log_name).log
80498
748f9bee8278 compress reports;
Fabian Huch <huch@in.tum.de>
parents: 80497
diff changeset
   633
    private def log_file_gz = dir + Path.basic(log_name).log.gz
80497
bd00bdf39c86 clarified build report;
Fabian Huch <huch@in.tum.de>
parents: 80470
diff changeset
   634
bd00bdf39c86 clarified build report;
Fabian Huch <huch@in.tum.de>
parents: 80470
diff changeset
   635
    def init(): Unit = Isabelle_System.make_directory(dir)
bd00bdf39c86 clarified build report;
Fabian Huch <huch@in.tum.de>
parents: 80470
diff changeset
   636
80498
748f9bee8278 compress reports;
Fabian Huch <huch@in.tum.de>
parents: 80497
diff changeset
   637
    def ok: Boolean = log_file.is_file != log_file_gz.is_file
80497
bd00bdf39c86 clarified build report;
Fabian Huch <huch@in.tum.de>
parents: 80470
diff changeset
   638
bd00bdf39c86 clarified build report;
Fabian Huch <huch@in.tum.de>
parents: 80470
diff changeset
   639
    def progress: Progress = new File_Progress(log_file)
bd00bdf39c86 clarified build report;
Fabian Huch <huch@in.tum.de>
parents: 80470
diff changeset
   640
80531
Fabian Huch <huch@in.tum.de>
parents: 80518
diff changeset
   641
    private def read_gz(file: Path, ext: String): Option[(String, String)] =
Fabian Huch <huch@in.tum.de>
parents: 80518
diff changeset
   642
      if (!File.is_gz(file.file_name) || file.drop_ext.get_ext != ext) None
Fabian Huch <huch@in.tum.de>
parents: 80518
diff changeset
   643
      else Some(file.drop_ext.drop_ext.file_name -> File.read_gzip(file))
Fabian Huch <huch@in.tum.de>
parents: 80518
diff changeset
   644
80498
748f9bee8278 compress reports;
Fabian Huch <huch@in.tum.de>
parents: 80497
diff changeset
   645
    def read: Report.Data = {
80532
d5ff748321b7 clarified names;
Fabian Huch <huch@in.tum.de>
parents: 80531
diff changeset
   646
      val build_log =
80498
748f9bee8278 compress reports;
Fabian Huch <huch@in.tum.de>
parents: 80497
diff changeset
   647
        if_proper(ok, if (log_file.is_file) File.read(log_file) else File.read_gzip(log_file_gz))
80531
Fabian Huch <huch@in.tum.de>
parents: 80518
diff changeset
   648
80532
d5ff748321b7 clarified names;
Fabian Huch <huch@in.tum.de>
parents: 80531
diff changeset
   649
      val component_diffs =
d5ff748321b7 clarified names;
Fabian Huch <huch@in.tum.de>
parents: 80531
diff changeset
   650
        File.read_dir(dir).flatMap(name => read_gz(dir + Path.basic(name), diff_ext))
80533
464266fc956e store hg log in addition to diff;
Fabian Huch <huch@in.tum.de>
parents: 80532
diff changeset
   651
      val component_logs =
464266fc956e store hg log in addition to diff;
Fabian Huch <huch@in.tum.de>
parents: 80532
diff changeset
   652
        File.read_dir(dir).flatMap(name => read_gz(dir + Path.basic(name), log_ext))
80531
Fabian Huch <huch@in.tum.de>
parents: 80518
diff changeset
   653
80533
464266fc956e store hg log in addition to diff;
Fabian Huch <huch@in.tum.de>
parents: 80532
diff changeset
   654
      Report.Data(build_log, component_logs, component_diffs)
80498
748f9bee8278 compress reports;
Fabian Huch <huch@in.tum.de>
parents: 80497
diff changeset
   655
    }
80497
bd00bdf39c86 clarified build report;
Fabian Huch <huch@in.tum.de>
parents: 80470
diff changeset
   656
80544
77c78910544c clarified;
Fabian Huch <huch@in.tum.de>
parents: 80543
diff changeset
   657
    def write_log(
77c78910544c clarified;
Fabian Huch <huch@in.tum.de>
parents: 80543
diff changeset
   658
      component: String,
77c78910544c clarified;
Fabian Huch <huch@in.tum.de>
parents: 80543
diff changeset
   659
      repository: Mercurial.Repository,
77c78910544c clarified;
Fabian Huch <huch@in.tum.de>
parents: 80543
diff changeset
   660
      rev0: String,
77c78910544c clarified;
Fabian Huch <huch@in.tum.de>
parents: 80543
diff changeset
   661
      rev: String
77c78910544c clarified;
Fabian Huch <huch@in.tum.de>
parents: 80543
diff changeset
   662
    ): Unit =
77c78910544c clarified;
Fabian Huch <huch@in.tum.de>
parents: 80543
diff changeset
   663
      if (rev0.nonEmpty && rev.nonEmpty && rev0 != rev) {
77c78910544c clarified;
Fabian Huch <huch@in.tum.de>
parents: 80543
diff changeset
   664
        val log_opts = "--graph --color always"
77c78910544c clarified;
Fabian Huch <huch@in.tum.de>
parents: 80543
diff changeset
   665
        val rev1 = "children(" + rev0 + ")"
77c78910544c clarified;
Fabian Huch <huch@in.tum.de>
parents: 80543
diff changeset
   666
        val cmd = repository.command_line("log", Mercurial.opt_rev(rev1 + ":" + rev), log_opts)
77c78910544c clarified;
Fabian Huch <huch@in.tum.de>
parents: 80543
diff changeset
   667
        val log = Isabelle_System.bash("export HGPLAINEXCEPT=color\n" + cmd).check.out
77c78910544c clarified;
Fabian Huch <huch@in.tum.de>
parents: 80543
diff changeset
   668
        if (log.nonEmpty) File.write_gzip(dir + Path.basic(component).ext(log_ext).gz, log)
77c78910544c clarified;
Fabian Huch <huch@in.tum.de>
parents: 80543
diff changeset
   669
      }
80500
12dc23fc3135 add diffs to build manager;
Fabian Huch <huch@in.tum.de>
parents: 80499
diff changeset
   670
80544
77c78910544c clarified;
Fabian Huch <huch@in.tum.de>
parents: 80543
diff changeset
   671
    def write_diff(
77c78910544c clarified;
Fabian Huch <huch@in.tum.de>
parents: 80543
diff changeset
   672
      component: String,
77c78910544c clarified;
Fabian Huch <huch@in.tum.de>
parents: 80543
diff changeset
   673
      repository: Mercurial.Repository,
77c78910544c clarified;
Fabian Huch <huch@in.tum.de>
parents: 80543
diff changeset
   674
      rev0: String,
77c78910544c clarified;
Fabian Huch <huch@in.tum.de>
parents: 80543
diff changeset
   675
      rev: String
77c78910544c clarified;
Fabian Huch <huch@in.tum.de>
parents: 80543
diff changeset
   676
    ): Unit =
77c78910544c clarified;
Fabian Huch <huch@in.tum.de>
parents: 80543
diff changeset
   677
      if (rev0.nonEmpty && rev.nonEmpty) {
77c78910544c clarified;
Fabian Huch <huch@in.tum.de>
parents: 80543
diff changeset
   678
        val diff_opts = "--noprefix --nodates --ignore-all-space --color always"
77c78910544c clarified;
Fabian Huch <huch@in.tum.de>
parents: 80543
diff changeset
   679
        val cmd = repository.command_line("diff", Mercurial.opt_rev(rev0 + ":" + rev), diff_opts)
77c78910544c clarified;
Fabian Huch <huch@in.tum.de>
parents: 80543
diff changeset
   680
        val diff = Isabelle_System.bash("export HGPLAINEXCEPT=color\n" + cmd).check.out
77c78910544c clarified;
Fabian Huch <huch@in.tum.de>
parents: 80543
diff changeset
   681
        if (diff.nonEmpty) File.write_gzip(dir + Path.basic(component).ext(diff_ext).gz, diff)
77c78910544c clarified;
Fabian Huch <huch@in.tum.de>
parents: 80543
diff changeset
   682
      }
80533
464266fc956e store hg log in addition to diff;
Fabian Huch <huch@in.tum.de>
parents: 80532
diff changeset
   683
80646
b4e116523cb6 build_manager: store submitting user;
Fabian Huch <huch@in.tum.de>
parents: 80645
diff changeset
   684
    def result(uuid: Option[UUID.T] = None, user: Option[String] = None): Result = {
80497
bd00bdf39c86 clarified build report;
Fabian Huch <huch@in.tum.de>
parents: 80470
diff changeset
   685
      val End = """^Job ended at [^,]+, with status (\w+)$""".r
bd00bdf39c86 clarified build report;
Fabian Huch <huch@in.tum.de>
parents: 80470
diff changeset
   686
80532
d5ff748321b7 clarified names;
Fabian Huch <huch@in.tum.de>
parents: 80531
diff changeset
   687
      val build_log_file = Build_Log.Log_File(log_name, Library.trim_split_lines(read.build_log))
80497
bd00bdf39c86 clarified build report;
Fabian Huch <huch@in.tum.de>
parents: 80470
diff changeset
   688
bd00bdf39c86 clarified build report;
Fabian Huch <huch@in.tum.de>
parents: 80470
diff changeset
   689
      val meta_info = build_log_file.parse_meta_info()
bd00bdf39c86 clarified build report;
Fabian Huch <huch@in.tum.de>
parents: 80470
diff changeset
   690
      val status =
bd00bdf39c86 clarified build report;
Fabian Huch <huch@in.tum.de>
parents: 80470
diff changeset
   691
        build_log_file.lines.last match {
bd00bdf39c86 clarified build report;
Fabian Huch <huch@in.tum.de>
parents: 80470
diff changeset
   692
          case End(status) => Status.valueOf(status)
bd00bdf39c86 clarified build report;
Fabian Huch <huch@in.tum.de>
parents: 80470
diff changeset
   693
          case _ => Status.aborted
bd00bdf39c86 clarified build report;
Fabian Huch <huch@in.tum.de>
parents: 80470
diff changeset
   694
        }
bd00bdf39c86 clarified build report;
Fabian Huch <huch@in.tum.de>
parents: 80470
diff changeset
   695
      val build_host = meta_info.get_build_host.getOrElse(error("No build host"))
bd00bdf39c86 clarified build report;
Fabian Huch <huch@in.tum.de>
parents: 80470
diff changeset
   696
      val start_date = meta_info.get_build_start.getOrElse(error("No start date"))
bd00bdf39c86 clarified build report;
Fabian Huch <huch@in.tum.de>
parents: 80470
diff changeset
   697
      val end_date = meta_info.get_build_end
bd00bdf39c86 clarified build report;
Fabian Huch <huch@in.tum.de>
parents: 80470
diff changeset
   698
      val isabelle_version = meta_info.get(Build_Log.Prop.isabelle_version)
bd00bdf39c86 clarified build report;
Fabian Huch <huch@in.tum.de>
parents: 80470
diff changeset
   699
      val afp_version = meta_info.get(Build_Log.Prop.afp_version)
bd00bdf39c86 clarified build report;
Fabian Huch <huch@in.tum.de>
parents: 80470
diff changeset
   700
80498
748f9bee8278 compress reports;
Fabian Huch <huch@in.tum.de>
parents: 80497
diff changeset
   701
      if (log_file.is_file) {
748f9bee8278 compress reports;
Fabian Huch <huch@in.tum.de>
parents: 80497
diff changeset
   702
        File.write_gzip(log_file_gz, build_log_file.text)
748f9bee8278 compress reports;
Fabian Huch <huch@in.tum.de>
parents: 80497
diff changeset
   703
        Isabelle_System.rm_tree(log_file)
748f9bee8278 compress reports;
Fabian Huch <huch@in.tum.de>
parents: 80497
diff changeset
   704
      }
748f9bee8278 compress reports;
Fabian Huch <huch@in.tum.de>
parents: 80497
diff changeset
   705
80497
bd00bdf39c86 clarified build report;
Fabian Huch <huch@in.tum.de>
parents: 80470
diff changeset
   706
      Result(kind, id, status, uuid, build_host, start_date, end_date, isabelle_version,
80646
b4e116523cb6 build_manager: store submitting user;
Fabian Huch <huch@in.tum.de>
parents: 80645
diff changeset
   707
        afp_version, user)
80497
bd00bdf39c86 clarified build report;
Fabian Huch <huch@in.tum.de>
parents: 80470
diff changeset
   708
    }
bd00bdf39c86 clarified build report;
Fabian Huch <huch@in.tum.de>
parents: 80470
diff changeset
   709
  }
bd00bdf39c86 clarified build report;
Fabian Huch <huch@in.tum.de>
parents: 80470
diff changeset
   710
bd00bdf39c86 clarified build report;
Fabian Huch <huch@in.tum.de>
parents: 80470
diff changeset
   711
80344
f05a71fa1a3f tuned comments;
Fabian Huch <huch@in.tum.de>
parents: 80343
diff changeset
   712
  /** running build manager processes **/
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   713
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   714
  abstract class Loop_Process[A](name: String, store: Store, progress: Progress)
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   715
    extends Runnable {
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   716
    val options = store.options
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   717
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   718
    private val _database =
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   719
      try { store.open_database() }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   720
      catch { case exn: Throwable => close(); throw exn }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   721
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   722
    def close(): Unit = Option(_database).foreach(_.close())
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   723
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   724
    protected var _state = State()
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   725
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   726
    protected def synchronized_database[A](label: String)(body: => A): A = synchronized {
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   727
      Build_Manager.private_data.transaction_lock(_database, label = name + "." + label) {
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   728
        val old_state = Build_Manager.private_data.pull_state(_database, _state)
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   729
        _state = old_state
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   730
        val res = body
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   731
        _state = Build_Manager.private_data.push_state(_database, old_state, _state)
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   732
        res
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   733
      }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   734
    }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   735
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   736
    protected def delay = options.seconds("build_manager_delay")
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   737
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   738
    def init: A
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   739
    def loop_body(a: A): A
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   740
    def stopped(a: A): Boolean = progress.stopped
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   741
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   742
    private val interrupted = Synchronized(false)
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   743
    private def sleep(time_limit: Time): Unit =
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   744
      interrupted.timed_access(_ => Some(time_limit), b => if (b) Some((), false) else None)
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   745
    def interrupt(): Unit = interrupted.change(_ => true)
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   746
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   747
    @tailrec private def loop(a: A): Unit =
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   748
      if (!stopped(a)) {
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   749
        val start = Time.now()
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   750
        val a1 = loop_body(a)
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   751
        if (!stopped(a)) {
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   752
          sleep(start + delay)
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   753
          loop(a1)
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   754
        }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   755
      }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   756
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   757
    override def run(): Unit = {
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   758
      progress.echo("Started " + name)
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   759
      loop(init)
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   760
      close()
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   761
      progress.echo("Stopped " + name)
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   762
    }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   763
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   764
    def echo(msg: String) = progress.echo(name + ": " + msg)
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   765
    def echo_error_message(msg: String) = progress.echo_error_message(name + ": " + msg)
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   766
  }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   767
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   768
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   769
  /* build runner */
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   770
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   771
  object Runner {
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   772
    object State {
80645
a1dce0cc6c26 build_manager: terminate processes if cancelling does not work;
Fabian Huch <huch@in.tum.de>
parents: 80644
diff changeset
   773
      def init(options: Options): State =
a1dce0cc6c26 build_manager: terminate processes if cancelling does not work;
Fabian Huch <huch@in.tum.de>
parents: 80644
diff changeset
   774
        new State(Map.empty, Map.empty, Map.empty, options.seconds("build_manager_cancel_timeout"))
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   775
    }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   776
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   777
    class State private(
80279
02424b81472a clarified: add explicit build process;
Fabian Huch <huch@in.tum.de>
parents: 80278
diff changeset
   778
      process_futures: Map[String, Future[Build_Process]],
80645
a1dce0cc6c26 build_manager: terminate processes if cancelling does not work;
Fabian Huch <huch@in.tum.de>
parents: 80644
diff changeset
   779
      result_futures: Map[String, Future[Process_Result]],
a1dce0cc6c26 build_manager: terminate processes if cancelling does not work;
Fabian Huch <huch@in.tum.de>
parents: 80644
diff changeset
   780
      cancelling_until: Map[String, Time],
a1dce0cc6c26 build_manager: terminate processes if cancelling does not work;
Fabian Huch <huch@in.tum.de>
parents: 80644
diff changeset
   781
      cancel_timeout: Time
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   782
    ) {
80645
a1dce0cc6c26 build_manager: terminate processes if cancelling does not work;
Fabian Huch <huch@in.tum.de>
parents: 80644
diff changeset
   783
      private def copy(
a1dce0cc6c26 build_manager: terminate processes if cancelling does not work;
Fabian Huch <huch@in.tum.de>
parents: 80644
diff changeset
   784
        process_futures: Map[String, Future[Build_Process]] = process_futures,
a1dce0cc6c26 build_manager: terminate processes if cancelling does not work;
Fabian Huch <huch@in.tum.de>
parents: 80644
diff changeset
   785
        result_futures: Map[String, Future[Process_Result]] = result_futures,
a1dce0cc6c26 build_manager: terminate processes if cancelling does not work;
Fabian Huch <huch@in.tum.de>
parents: 80644
diff changeset
   786
        cancelling_until: Map[String, Time] = cancelling_until,
a1dce0cc6c26 build_manager: terminate processes if cancelling does not work;
Fabian Huch <huch@in.tum.de>
parents: 80644
diff changeset
   787
      ): State = new State(process_futures, result_futures, cancelling_until, cancel_timeout)
a1dce0cc6c26 build_manager: terminate processes if cancelling does not work;
Fabian Huch <huch@in.tum.de>
parents: 80644
diff changeset
   788
80277
Fabian Huch <huch@in.tum.de>
parents: 80274
diff changeset
   789
      def is_empty = process_futures.isEmpty && result_futures.isEmpty
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   790
80280
7987b33fb6c5 clarified context: operations now in build process;
Fabian Huch <huch@in.tum.de>
parents: 80279
diff changeset
   791
      def init(context: Context): State = {
7987b33fb6c5 clarified context: operations now in build process;
Fabian Huch <huch@in.tum.de>
parents: 80279
diff changeset
   792
        val process_future = Future.fork(Build_Process.open(context))
80277
Fabian Huch <huch@in.tum.de>
parents: 80274
diff changeset
   793
        val result_future =
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   794
          Future.fork(
80277
Fabian Huch <huch@in.tum.de>
parents: 80274
diff changeset
   795
            process_future.join_result match {
80279
02424b81472a clarified: add explicit build process;
Fabian Huch <huch@in.tum.de>
parents: 80278
diff changeset
   796
              case Exn.Res(process) => process.run()
80284
7a5bbc2e4bad build manager: echo error messages to server output;
Fabian Huch <huch@in.tum.de>
parents: 80283
diff changeset
   797
              case Exn.Exn(exn) => Process_Result(Process_Result.RC.interrupt).error(exn.getMessage)
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   798
            })
80645
a1dce0cc6c26 build_manager: terminate processes if cancelling does not work;
Fabian Huch <huch@in.tum.de>
parents: 80644
diff changeset
   799
a1dce0cc6c26 build_manager: terminate processes if cancelling does not work;
Fabian Huch <huch@in.tum.de>
parents: 80644
diff changeset
   800
        copy(
80280
7987b33fb6c5 clarified context: operations now in build process;
Fabian Huch <huch@in.tum.de>
parents: 80279
diff changeset
   801
          process_futures + (context.name -> process_future),
7987b33fb6c5 clarified context: operations now in build process;
Fabian Huch <huch@in.tum.de>
parents: 80279
diff changeset
   802
          result_futures + (context.name -> result_future))
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   803
      }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   804
80779
a1b3abc629af manage runner state properly (amending be4c1fbccfe8);
Fabian Huch <huch@in.tum.de>
parents: 80731
diff changeset
   805
      def running: List[String] = process_futures.keys.toList.filterNot(cancelling_until.contains)
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   806
80781
11e33f3d5ef1 better results for terminated jobs;
Fabian Huch <huch@in.tum.de>
parents: 80780
diff changeset
   807
      private def maybe_result(name: String): Option[Process_Result] =
11e33f3d5ef1 better results for terminated jobs;
Fabian Huch <huch@in.tum.de>
parents: 80780
diff changeset
   808
        for (future <- result_futures.get(name) if future.is_finished) yield
11e33f3d5ef1 better results for terminated jobs;
Fabian Huch <huch@in.tum.de>
parents: 80780
diff changeset
   809
          future.join_result match {
11e33f3d5ef1 better results for terminated jobs;
Fabian Huch <huch@in.tum.de>
parents: 80780
diff changeset
   810
            case Exn.Res(result) => result
11e33f3d5ef1 better results for terminated jobs;
Fabian Huch <huch@in.tum.de>
parents: 80780
diff changeset
   811
            case Exn.Exn(exn) => Process_Result(Process_Result.RC.interrupt).error(exn.getMessage)
11e33f3d5ef1 better results for terminated jobs;
Fabian Huch <huch@in.tum.de>
parents: 80780
diff changeset
   812
          }
11e33f3d5ef1 better results for terminated jobs;
Fabian Huch <huch@in.tum.de>
parents: 80780
diff changeset
   813
80730
be4c1fbccfe8 terminate jobs properly;
Fabian Huch <huch@in.tum.de>
parents: 80650
diff changeset
   814
      private def do_terminate(name: String): Boolean = {
80779
a1b3abc629af manage runner state properly (amending be4c1fbccfe8);
Fabian Huch <huch@in.tum.de>
parents: 80731
diff changeset
   815
        val is_late = Time.now() > cancelling_until(name)
80730
be4c1fbccfe8 terminate jobs properly;
Fabian Huch <huch@in.tum.de>
parents: 80650
diff changeset
   816
        if (is_late) process_futures(name).join.terminate()
be4c1fbccfe8 terminate jobs properly;
Fabian Huch <huch@in.tum.de>
parents: 80650
diff changeset
   817
        is_late
be4c1fbccfe8 terminate jobs properly;
Fabian Huch <huch@in.tum.de>
parents: 80650
diff changeset
   818
      }
80645
a1dce0cc6c26 build_manager: terminate processes if cancelling does not work;
Fabian Huch <huch@in.tum.de>
parents: 80644
diff changeset
   819
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   820
      def update: (State, Map[String, Process_Result]) = {
80731
834849b55910 remove terminated jobs, even if futures do not complete;
Fabian Huch <huch@in.tum.de>
parents: 80730
diff changeset
   821
        val finished0 =
80781
11e33f3d5ef1 better results for terminated jobs;
Fabian Huch <huch@in.tum.de>
parents: 80780
diff changeset
   822
          for {
11e33f3d5ef1 better results for terminated jobs;
Fabian Huch <huch@in.tum.de>
parents: 80780
diff changeset
   823
            (name, _) <- result_futures
11e33f3d5ef1 better results for terminated jobs;
Fabian Huch <huch@in.tum.de>
parents: 80780
diff changeset
   824
            result <- maybe_result(name)
11e33f3d5ef1 better results for terminated jobs;
Fabian Huch <huch@in.tum.de>
parents: 80780
diff changeset
   825
          } yield name -> result
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   826
80731
834849b55910 remove terminated jobs, even if futures do not complete;
Fabian Huch <huch@in.tum.de>
parents: 80730
diff changeset
   827
        val (terminated, cancelling_until1) =
834849b55910 remove terminated jobs, even if futures do not complete;
Fabian Huch <huch@in.tum.de>
parents: 80730
diff changeset
   828
          cancelling_until
834849b55910 remove terminated jobs, even if futures do not complete;
Fabian Huch <huch@in.tum.de>
parents: 80730
diff changeset
   829
            .filterNot((name, _) => finished0.contains(name))
834849b55910 remove terminated jobs, even if futures do not complete;
Fabian Huch <huch@in.tum.de>
parents: 80730
diff changeset
   830
            .partition((name, _) => do_terminate(name))
834849b55910 remove terminated jobs, even if futures do not complete;
Fabian Huch <huch@in.tum.de>
parents: 80730
diff changeset
   831
834849b55910 remove terminated jobs, even if futures do not complete;
Fabian Huch <huch@in.tum.de>
parents: 80730
diff changeset
   832
        val finished =
834849b55910 remove terminated jobs, even if futures do not complete;
Fabian Huch <huch@in.tum.de>
parents: 80730
diff changeset
   833
          finished0 ++
80781
11e33f3d5ef1 better results for terminated jobs;
Fabian Huch <huch@in.tum.de>
parents: 80780
diff changeset
   834
            terminated.map((name, _) =>
11e33f3d5ef1 better results for terminated jobs;
Fabian Huch <huch@in.tum.de>
parents: 80780
diff changeset
   835
              name -> maybe_result(name).getOrElse(Process_Result(Process_Result.RC.timeout)))
80731
834849b55910 remove terminated jobs, even if futures do not complete;
Fabian Huch <huch@in.tum.de>
parents: 80730
diff changeset
   836
80645
a1dce0cc6c26 build_manager: terminate processes if cancelling does not work;
Fabian Huch <huch@in.tum.de>
parents: 80644
diff changeset
   837
        val state1 =
a1dce0cc6c26 build_manager: terminate processes if cancelling does not work;
Fabian Huch <huch@in.tum.de>
parents: 80644
diff changeset
   838
          copy(
a1dce0cc6c26 build_manager: terminate processes if cancelling does not work;
Fabian Huch <huch@in.tum.de>
parents: 80644
diff changeset
   839
            process_futures.filterNot((name, _) => finished.contains(name)),
a1dce0cc6c26 build_manager: terminate processes if cancelling does not work;
Fabian Huch <huch@in.tum.de>
parents: 80644
diff changeset
   840
            result_futures.filterNot((name, _) => finished.contains(name)),
80731
834849b55910 remove terminated jobs, even if futures do not complete;
Fabian Huch <huch@in.tum.de>
parents: 80730
diff changeset
   841
            cancelling_until1)
80645
a1dce0cc6c26 build_manager: terminate processes if cancelling does not work;
Fabian Huch <huch@in.tum.de>
parents: 80644
diff changeset
   842
        (state1, finished)
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   843
      }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   844
80730
be4c1fbccfe8 terminate jobs properly;
Fabian Huch <huch@in.tum.de>
parents: 80650
diff changeset
   845
      private def do_cancel(process_future: Future[Build_Process]): Boolean = {
be4c1fbccfe8 terminate jobs properly;
Fabian Huch <huch@in.tum.de>
parents: 80650
diff changeset
   846
        val is_finished = process_future.is_finished
be4c1fbccfe8 terminate jobs properly;
Fabian Huch <huch@in.tum.de>
parents: 80650
diff changeset
   847
        if (is_finished) process_future.join.cancel() else process_future.cancel()
be4c1fbccfe8 terminate jobs properly;
Fabian Huch <huch@in.tum.de>
parents: 80650
diff changeset
   848
        is_finished
be4c1fbccfe8 terminate jobs properly;
Fabian Huch <huch@in.tum.de>
parents: 80650
diff changeset
   849
      }
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   850
80730
be4c1fbccfe8 terminate jobs properly;
Fabian Huch <huch@in.tum.de>
parents: 80650
diff changeset
   851
      def cancel(cancelled: List[String]): State = {
be4c1fbccfe8 terminate jobs properly;
Fabian Huch <huch@in.tum.de>
parents: 80650
diff changeset
   852
        val cancelling_until1 =
be4c1fbccfe8 terminate jobs properly;
Fabian Huch <huch@in.tum.de>
parents: 80650
diff changeset
   853
          for {
be4c1fbccfe8 terminate jobs properly;
Fabian Huch <huch@in.tum.de>
parents: 80650
diff changeset
   854
            name <- cancelled
be4c1fbccfe8 terminate jobs properly;
Fabian Huch <huch@in.tum.de>
parents: 80650
diff changeset
   855
            process_future <- process_futures.get(name)
be4c1fbccfe8 terminate jobs properly;
Fabian Huch <huch@in.tum.de>
parents: 80650
diff changeset
   856
            if do_cancel(process_future)
be4c1fbccfe8 terminate jobs properly;
Fabian Huch <huch@in.tum.de>
parents: 80650
diff changeset
   857
          } yield name -> (Time.now() + cancel_timeout)
be4c1fbccfe8 terminate jobs properly;
Fabian Huch <huch@in.tum.de>
parents: 80650
diff changeset
   858
80779
a1b3abc629af manage runner state properly (amending be4c1fbccfe8);
Fabian Huch <huch@in.tum.de>
parents: 80731
diff changeset
   859
        copy(cancelling_until = cancelling_until ++ cancelling_until1)
80730
be4c1fbccfe8 terminate jobs properly;
Fabian Huch <huch@in.tum.de>
parents: 80650
diff changeset
   860
      }
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   861
    }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   862
  }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   863
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   864
  class Runner(
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   865
    store: Store,
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   866
    build_hosts: List[Build_Cluster.Host],
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   867
    isabelle_repository: Mercurial.Repository,
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   868
    sync_dirs: List[Sync.Dir],
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   869
    progress: Progress
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   870
  ) extends Loop_Process[Runner.State]("Runner", store, progress) {
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   871
    val rsync_context = Rsync.Context()
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   872
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   873
    private def sync(repository: Mercurial.Repository, rev: String, target: Path): String = {
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   874
      repository.pull()
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   875
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   876
      if (rev.nonEmpty) repository.sync(rsync_context, target, rev = rev)
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   877
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   878
      Exn.capture(repository.id(File.read(target + Mercurial.Hg_Sync.PATH_ID))) match {
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   879
        case Exn.Res(res) => res
80647
3519f026e7d6 tuned and clarified;
Fabian Huch <huch@in.tum.de>
parents: 80646
diff changeset
   880
        case Exn.Exn(_) => ""
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   881
      }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   882
    }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   883
80280
7987b33fb6c5 clarified context: operations now in build process;
Fabian Huch <huch@in.tum.de>
parents: 80279
diff changeset
   884
    private def start_next(): Option[Context] =
7987b33fb6c5 clarified context: operations now in build process;
Fabian Huch <huch@in.tum.de>
parents: 80279
diff changeset
   885
      synchronized_database("start_next") {
80424
6ed82923d51d abort tasks with invalid host specs;
Fabian Huch <huch@in.tum.de>
parents: 80423
diff changeset
   886
        for ((name, task) <- _state.pending if Exn.is_exn(Exn.capture(task.build_hosts))) {
6ed82923d51d abort tasks with invalid host specs;
Fabian Huch <huch@in.tum.de>
parents: 80423
diff changeset
   887
          progress.echo("Invalid host spec for task " + name + ": " + quote(task.hosts_spec))
6ed82923d51d abort tasks with invalid host specs;
Fabian Huch <huch@in.tum.de>
parents: 80423
diff changeset
   888
          _state = _state.remove_pending(name)
6ed82923d51d abort tasks with invalid host specs;
Fabian Huch <huch@in.tum.de>
parents: 80423
diff changeset
   889
        }
6ed82923d51d abort tasks with invalid host specs;
Fabian Huch <huch@in.tum.de>
parents: 80423
diff changeset
   890
80281
17d2f775907a add cluster/hosts configurations to build manager: allows running jobs in parallel on distinct hardware;
Fabian Huch <huch@in.tum.de>
parents: 80280
diff changeset
   891
        _state.next(build_hosts).flatMap { task =>
80340
992bd899a027 improve build manager log (for build_log);
Fabian Huch <huch@in.tum.de>
parents: 80339
diff changeset
   892
          echo("Initializing " + task.name)
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   893
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   894
          _state = _state.remove_pending(task.name)
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   895
80337
02f8a35ed8e2 clarified names: more canonical;
Fabian Huch <huch@in.tum.de>
parents: 80336
diff changeset
   896
          val id = _state.next_id(task.kind)
02f8a35ed8e2 clarified names: more canonical;
Fabian Huch <huch@in.tum.de>
parents: 80336
diff changeset
   897
          val context = Context(store, task, id)
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   898
80340
992bd899a027 improve build manager log (for build_log);
Fabian Huch <huch@in.tum.de>
parents: 80339
diff changeset
   899
          val start_date = Date.now()
992bd899a027 improve build manager log (for build_log);
Fabian Huch <huch@in.tum.de>
parents: 80339
diff changeset
   900
992bd899a027 improve build manager log (for build_log);
Fabian Huch <huch@in.tum.de>
parents: 80339
diff changeset
   901
          val start_msg =
992bd899a027 improve build manager log (for build_log);
Fabian Huch <huch@in.tum.de>
parents: 80339
diff changeset
   902
            "Starting job " + Build.name(task.kind, id) +
992bd899a027 improve build manager log (for build_log);
Fabian Huch <huch@in.tum.de>
parents: 80339
diff changeset
   903
            " at " + Build_Log.print_date(start_date) + "," +
992bd899a027 improve build manager log (for build_log);
Fabian Huch <huch@in.tum.de>
parents: 80339
diff changeset
   904
            " on " + (
992bd899a027 improve build manager log (for build_log);
Fabian Huch <huch@in.tum.de>
parents: 80339
diff changeset
   905
              if (task.build_cluster) "cluster"
992bd899a027 improve build manager log (for build_log);
Fabian Huch <huch@in.tum.de>
parents: 80339
diff changeset
   906
              else Library.the_single(task.build_hosts).hostname)
992bd899a027 improve build manager log (for build_log);
Fabian Huch <huch@in.tum.de>
parents: 80339
diff changeset
   907
992bd899a027 improve build manager log (for build_log);
Fabian Huch <huch@in.tum.de>
parents: 80339
diff changeset
   908
          echo(start_msg + " (id " + task.uuid + ")")
992bd899a027 improve build manager log (for build_log);
Fabian Huch <huch@in.tum.de>
parents: 80339
diff changeset
   909
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   910
          Exn.capture {
80497
bd00bdf39c86 clarified build report;
Fabian Huch <huch@in.tum.de>
parents: 80470
diff changeset
   911
            context.report.init()
bd00bdf39c86 clarified build report;
Fabian Huch <huch@in.tum.de>
parents: 80470
diff changeset
   912
            context.report.progress.echo(start_msg)
80340
992bd899a027 improve build manager log (for build_log);
Fabian Huch <huch@in.tum.de>
parents: 80339
diff changeset
   913
80280
7987b33fb6c5 clarified context: operations now in build process;
Fabian Huch <huch@in.tum.de>
parents: 80279
diff changeset
   914
            store.sync_permissions(context.task_dir)
80255
1844c169e360 ensure permissions when starting build task (e.g., due to misconfigured client);
Fabian Huch <huch@in.tum.de>
parents: 80254
diff changeset
   915
80409
Fabian Huch <huch@in.tum.de>
parents: 80408
diff changeset
   916
            val isabelle_rev = sync(isabelle_repository, task.isabelle_rev, context.task_dir)
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   917
80281
17d2f775907a add cluster/hosts configurations to build manager: allows running jobs in parallel on distinct hardware;
Fabian Huch <huch@in.tum.de>
parents: 80280
diff changeset
   918
            val hostnames = task.build_hosts.map(_.hostname).distinct
17d2f775907a add cluster/hosts configurations to build manager: allows running jobs in parallel on distinct hardware;
Fabian Huch <huch@in.tum.de>
parents: 80280
diff changeset
   919
80499
433475f17d73 clarified: components vs. extra components;
Fabian Huch <huch@in.tum.de>
parents: 80498
diff changeset
   920
            val extra_components =
433475f17d73 clarified: components vs. extra components;
Fabian Huch <huch@in.tum.de>
parents: 80498
diff changeset
   921
              for (extra_component <- task.extra_components)
433475f17d73 clarified: components vs. extra components;
Fabian Huch <huch@in.tum.de>
parents: 80498
diff changeset
   922
              yield sync_dirs.find(_.name == extra_component.name) match {
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   923
                case Some(sync_dir) =>
80280
7987b33fb6c5 clarified context: operations now in build process;
Fabian Huch <huch@in.tum.de>
parents: 80279
diff changeset
   924
                  val target = context.task_dir + sync_dir.target
80499
433475f17d73 clarified: components vs. extra components;
Fabian Huch <huch@in.tum.de>
parents: 80498
diff changeset
   925
                  val rev = sync(sync_dir.hg, extra_component.rev, target)
80408
e6d3d1db6136 add root entry for non-local components;
Fabian Huch <huch@in.tum.de>
parents: 80407
diff changeset
   926
80499
433475f17d73 clarified: components vs. extra components;
Fabian Huch <huch@in.tum.de>
parents: 80498
diff changeset
   927
                  if (!extra_component.is_local)
80408
e6d3d1db6136 add root entry for non-local components;
Fabian Huch <huch@in.tum.de>
parents: 80407
diff changeset
   928
                    File.append(context.task_dir + Sync.DIRS_ROOTS, sync_dir.roots_entry + "\n")
80499
433475f17d73 clarified: components vs. extra components;
Fabian Huch <huch@in.tum.de>
parents: 80498
diff changeset
   929
                  extra_component.copy(rev = rev)
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   930
                case None =>
80499
433475f17d73 clarified: components vs. extra components;
Fabian Huch <huch@in.tum.de>
parents: 80498
diff changeset
   931
                  if (extra_component.is_local) extra_component
433475f17d73 clarified: components vs. extra components;
Fabian Huch <huch@in.tum.de>
parents: 80498
diff changeset
   932
                  else error("Unknown component " + extra_component)
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   933
              }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   934
80500
12dc23fc3135 add diffs to build manager;
Fabian Huch <huch@in.tum.de>
parents: 80499
diff changeset
   935
            if (task.kind != User_Build.name && _state.get_finished(task.kind).nonEmpty) {
12dc23fc3135 add diffs to build manager;
Fabian Huch <huch@in.tum.de>
parents: 80499
diff changeset
   936
              val previous = _state.get_finished(task.kind).maxBy(_.id)
12dc23fc3135 add diffs to build manager;
Fabian Huch <huch@in.tum.de>
parents: 80499
diff changeset
   937
12dc23fc3135 add diffs to build manager;
Fabian Huch <huch@in.tum.de>
parents: 80499
diff changeset
   938
              for (isabelle_rev0 <- previous.isabelle_version) {
80544
77c78910544c clarified;
Fabian Huch <huch@in.tum.de>
parents: 80543
diff changeset
   939
                context.report.write_log(Component.Isabelle,
77c78910544c clarified;
Fabian Huch <huch@in.tum.de>
parents: 80543
diff changeset
   940
                  isabelle_repository, isabelle_rev0, isabelle_rev)
77c78910544c clarified;
Fabian Huch <huch@in.tum.de>
parents: 80543
diff changeset
   941
                context.report.write_diff(Component.Isabelle,
77c78910544c clarified;
Fabian Huch <huch@in.tum.de>
parents: 80543
diff changeset
   942
                  isabelle_repository, isabelle_rev0, isabelle_rev)
80500
12dc23fc3135 add diffs to build manager;
Fabian Huch <huch@in.tum.de>
parents: 80499
diff changeset
   943
              }
12dc23fc3135 add diffs to build manager;
Fabian Huch <huch@in.tum.de>
parents: 80499
diff changeset
   944
12dc23fc3135 add diffs to build manager;
Fabian Huch <huch@in.tum.de>
parents: 80499
diff changeset
   945
              for {
12dc23fc3135 add diffs to build manager;
Fabian Huch <huch@in.tum.de>
parents: 80499
diff changeset
   946
                afp_rev0 <- previous.afp_version
12dc23fc3135 add diffs to build manager;
Fabian Huch <huch@in.tum.de>
parents: 80499
diff changeset
   947
                afp <- extra_components.find(_.name == Component.AFP)
12dc23fc3135 add diffs to build manager;
Fabian Huch <huch@in.tum.de>
parents: 80499
diff changeset
   948
                sync_dir <- sync_dirs.find(_.name == afp.name)
80533
464266fc956e store hg log in addition to diff;
Fabian Huch <huch@in.tum.de>
parents: 80532
diff changeset
   949
              } {
80544
77c78910544c clarified;
Fabian Huch <huch@in.tum.de>
parents: 80543
diff changeset
   950
                context.report.write_log(afp.name, sync_dir.hg, afp_rev0, afp.rev)
77c78910544c clarified;
Fabian Huch <huch@in.tum.de>
parents: 80543
diff changeset
   951
                context.report.write_diff(afp.name, sync_dir.hg, afp_rev0, afp.rev)
80533
464266fc956e store hg log in addition to diff;
Fabian Huch <huch@in.tum.de>
parents: 80532
diff changeset
   952
              }
80500
12dc23fc3135 add diffs to build manager;
Fabian Huch <huch@in.tum.de>
parents: 80499
diff changeset
   953
            }
12dc23fc3135 add diffs to build manager;
Fabian Huch <huch@in.tum.de>
parents: 80499
diff changeset
   954
80646
b4e116523cb6 build_manager: store submitting user;
Fabian Huch <huch@in.tum.de>
parents: 80645
diff changeset
   955
            val components = Component.isabelle(isabelle_rev) :: extra_components
b4e116523cb6 build_manager: store submitting user;
Fabian Huch <huch@in.tum.de>
parents: 80645
diff changeset
   956
b4e116523cb6 build_manager: store submitting user;
Fabian Huch <huch@in.tum.de>
parents: 80645
diff changeset
   957
            Job(task.uuid, task.kind, id, task.build_cluster, hostnames, components, task.timeout,
b4e116523cb6 build_manager: store submitting user;
Fabian Huch <huch@in.tum.de>
parents: 80645
diff changeset
   958
              task.user, start_date)
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   959
          } match {
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   960
            case Exn.Res(job) =>
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   961
              _state = _state.add_running(job)
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   962
80542
dd86d35375a7 log and display components with empty (unknown) revisions to indicate that they are present;
Fabian Huch <huch@in.tum.de>
parents: 80541
diff changeset
   963
              for (component <- job.components)
80499
433475f17d73 clarified: components vs. extra components;
Fabian Huch <huch@in.tum.de>
parents: 80498
diff changeset
   964
                context.report.progress.echo("Using " + component.toString)
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   965
80280
7987b33fb6c5 clarified context: operations now in build process;
Fabian Huch <huch@in.tum.de>
parents: 80279
diff changeset
   966
              Some(context)
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   967
            case Exn.Exn(exn) =>
80497
bd00bdf39c86 clarified build report;
Fabian Huch <huch@in.tum.de>
parents: 80470
diff changeset
   968
              context.report.progress.echo_error_message("Failed to start job: " + exn.getMessage)
80340
992bd899a027 improve build manager log (for build_log);
Fabian Huch <huch@in.tum.de>
parents: 80339
diff changeset
   969
              echo_error_message("Failed to start " + task.uuid + ": " + exn.getMessage)
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   970
80280
7987b33fb6c5 clarified context: operations now in build process;
Fabian Huch <huch@in.tum.de>
parents: 80279
diff changeset
   971
              Isabelle_System.rm_tree(context.task_dir)
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   972
80646
b4e116523cb6 build_manager: store submitting user;
Fabian Huch <huch@in.tum.de>
parents: 80645
diff changeset
   973
              _state = _state.add_finished(context.report.result(Some(task.uuid), task.user))
80340
992bd899a027 improve build manager log (for build_log);
Fabian Huch <huch@in.tum.de>
parents: 80339
diff changeset
   974
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   975
              None
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   976
          }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   977
        }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   978
      }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   979
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   980
    private def stop_cancelled(state: Runner.State): Runner.State =
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
   981
      synchronized_database("stop_cancelled") {
80469
a3bae6dd7344 add timeout to build manager tasks/jobs (e.g. for cluster builds that don't terminate after error on host);
Fabian Huch <huch@in.tum.de>
parents: 80468
diff changeset
   982
        val now = Date.now()
a3bae6dd7344 add timeout to build manager tasks/jobs (e.g. for cluster builds that don't terminate after error on host);
Fabian Huch <huch@in.tum.de>
parents: 80468
diff changeset
   983
        for {
a3bae6dd7344 add timeout to build manager tasks/jobs (e.g. for cluster builds that don't terminate after error on host);
Fabian Huch <huch@in.tum.de>
parents: 80468
diff changeset
   984
          name <- state.running
a3bae6dd7344 add timeout to build manager tasks/jobs (e.g. for cluster builds that don't terminate after error on host);
Fabian Huch <huch@in.tum.de>
parents: 80468
diff changeset
   985
          job = _state.running(name)
a3bae6dd7344 add timeout to build manager tasks/jobs (e.g. for cluster builds that don't terminate after error on host);
Fabian Huch <huch@in.tum.de>
parents: 80468
diff changeset
   986
          if now - job.start_date > job.timeout
a3bae6dd7344 add timeout to build manager tasks/jobs (e.g. for cluster builds that don't terminate after error on host);
Fabian Huch <huch@in.tum.de>
parents: 80468
diff changeset
   987
        } {
a3bae6dd7344 add timeout to build manager tasks/jobs (e.g. for cluster builds that don't terminate after error on host);
Fabian Huch <huch@in.tum.de>
parents: 80468
diff changeset
   988
          _state = _state.cancel_running(name)
a3bae6dd7344 add timeout to build manager tasks/jobs (e.g. for cluster builds that don't terminate after error on host);
Fabian Huch <huch@in.tum.de>
parents: 80468
diff changeset
   989
a3bae6dd7344 add timeout to build manager tasks/jobs (e.g. for cluster builds that don't terminate after error on host);
Fabian Huch <huch@in.tum.de>
parents: 80468
diff changeset
   990
          val timeout_msg = "Timeout after " + job.timeout.message_hms
80497
bd00bdf39c86 clarified build report;
Fabian Huch <huch@in.tum.de>
parents: 80470
diff changeset
   991
          store.report(job.kind, job.id).progress.echo_error_message(timeout_msg)
80469
a3bae6dd7344 add timeout to build manager tasks/jobs (e.g. for cluster builds that don't terminate after error on host);
Fabian Huch <huch@in.tum.de>
parents: 80468
diff changeset
   992
          echo(job.name + ": " + timeout_msg)
a3bae6dd7344 add timeout to build manager tasks/jobs (e.g. for cluster builds that don't terminate after error on host);
Fabian Huch <huch@in.tum.de>
parents: 80468
diff changeset
   993
        }
a3bae6dd7344 add timeout to build manager tasks/jobs (e.g. for cluster builds that don't terminate after error on host);
Fabian Huch <huch@in.tum.de>
parents: 80468
diff changeset
   994
80644
6a996ad11af2 build_manager: log message when job is cancelled;
Fabian Huch <huch@in.tum.de>
parents: 80575
diff changeset
   995
        val cancelled =
6a996ad11af2 build_manager: log message when job is cancelled;
Fabian Huch <huch@in.tum.de>
parents: 80575
diff changeset
   996
          for {
6a996ad11af2 build_manager: log message when job is cancelled;
Fabian Huch <huch@in.tum.de>
parents: 80575
diff changeset
   997
            name <- state.running
6a996ad11af2 build_manager: log message when job is cancelled;
Fabian Huch <huch@in.tum.de>
parents: 80575
diff changeset
   998
            job = _state.running(name)
6a996ad11af2 build_manager: log message when job is cancelled;
Fabian Huch <huch@in.tum.de>
parents: 80575
diff changeset
   999
            if job.cancelled
6a996ad11af2 build_manager: log message when job is cancelled;
Fabian Huch <huch@in.tum.de>
parents: 80575
diff changeset
  1000
          } yield job
6a996ad11af2 build_manager: log message when job is cancelled;
Fabian Huch <huch@in.tum.de>
parents: 80575
diff changeset
  1001
6a996ad11af2 build_manager: log message when job is cancelled;
Fabian Huch <huch@in.tum.de>
parents: 80575
diff changeset
  1002
        cancelled.foreach(job => store.report(job.kind, job.id).progress.echo("Cancelling ..."))
6a996ad11af2 build_manager: log message when job is cancelled;
Fabian Huch <huch@in.tum.de>
parents: 80575
diff changeset
  1003
        state.cancel(cancelled.map(_.name))
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1004
      }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1005
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1006
    private def finish_job(name: String, process_result: Process_Result): Unit =
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1007
      synchronized_database("finish_job") {
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1008
        val job = _state.running(name)
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1009
80342
35bee9c44e1a use build log in build manager to store meta-data persistently;
Fabian Huch <huch@in.tum.de>
parents: 80340
diff changeset
  1010
        val end_date = Date.now()
35bee9c44e1a use build log in build manager to store meta-data persistently;
Fabian Huch <huch@in.tum.de>
parents: 80340
diff changeset
  1011
        val status = Status.from_result(process_result)
35bee9c44e1a use build log in build manager to store meta-data persistently;
Fabian Huch <huch@in.tum.de>
parents: 80340
diff changeset
  1012
        val end_msg = "Job ended at " + Build_Log.print_date(end_date) + ", with status " + status
35bee9c44e1a use build log in build manager to store meta-data persistently;
Fabian Huch <huch@in.tum.de>
parents: 80340
diff changeset
  1013
80497
bd00bdf39c86 clarified build report;
Fabian Huch <huch@in.tum.de>
parents: 80470
diff changeset
  1014
        val report = store.report(job.kind, job.id)
bd00bdf39c86 clarified build report;
Fabian Huch <huch@in.tum.de>
parents: 80470
diff changeset
  1015
        report.progress.echo(end_msg)
80340
992bd899a027 improve build manager log (for build_log);
Fabian Huch <huch@in.tum.de>
parents: 80339
diff changeset
  1016
80284
7a5bbc2e4bad build manager: echo error messages to server output;
Fabian Huch <huch@in.tum.de>
parents: 80283
diff changeset
  1017
        val interrupted_error = process_result.interrupted && process_result.err.nonEmpty
7a5bbc2e4bad build manager: echo error messages to server output;
Fabian Huch <huch@in.tum.de>
parents: 80283
diff changeset
  1018
        val err_msg = if_proper(interrupted_error, ": " + process_result.err)
80340
992bd899a027 improve build manager log (for build_log);
Fabian Huch <huch@in.tum.de>
parents: 80339
diff changeset
  1019
        echo(end_msg + " (code " + process_result.rc + ")" + err_msg)
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1020
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1021
        _state = _state
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1022
          .remove_running(job.name)
80646
b4e116523cb6 build_manager: store submitting user;
Fabian Huch <huch@in.tum.de>
parents: 80645
diff changeset
  1023
          .add_finished(report.result(Some(job.uuid), job.user))
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1024
      }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1025
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1026
    override def stopped(state: Runner.State): Boolean = progress.stopped && state.is_empty
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1027
80780
d6417e967a7c more robust: clean up unfinished jobs on init, e.g. if build_manager process was forcefully terminated;
Fabian Huch <huch@in.tum.de>
parents: 80779
diff changeset
  1028
    def init: Runner.State = synchronized_database("init") {
d6417e967a7c more robust: clean up unfinished jobs on init, e.g. if build_manager process was forcefully terminated;
Fabian Huch <huch@in.tum.de>
parents: 80779
diff changeset
  1029
      for ((name, job) <- _state.running) {
d6417e967a7c more robust: clean up unfinished jobs on init, e.g. if build_manager process was forcefully terminated;
Fabian Huch <huch@in.tum.de>
parents: 80779
diff changeset
  1030
        echo("Cleaned up job " + job.uuid)
d6417e967a7c more robust: clean up unfinished jobs on init, e.g. if build_manager process was forcefully terminated;
Fabian Huch <huch@in.tum.de>
parents: 80779
diff changeset
  1031
d6417e967a7c more robust: clean up unfinished jobs on init, e.g. if build_manager process was forcefully terminated;
Fabian Huch <huch@in.tum.de>
parents: 80779
diff changeset
  1032
        val report = store.report(job.kind, job.id)
d6417e967a7c more robust: clean up unfinished jobs on init, e.g. if build_manager process was forcefully terminated;
Fabian Huch <huch@in.tum.de>
parents: 80779
diff changeset
  1033
d6417e967a7c more robust: clean up unfinished jobs on init, e.g. if build_manager process was forcefully terminated;
Fabian Huch <huch@in.tum.de>
parents: 80779
diff changeset
  1034
        _state = _state
d6417e967a7c more robust: clean up unfinished jobs on init, e.g. if build_manager process was forcefully terminated;
Fabian Huch <huch@in.tum.de>
parents: 80779
diff changeset
  1035
          .remove_running(job.name)
d6417e967a7c more robust: clean up unfinished jobs on init, e.g. if build_manager process was forcefully terminated;
Fabian Huch <huch@in.tum.de>
parents: 80779
diff changeset
  1036
          .add_finished(report.result(Some(job.uuid), job.user))
d6417e967a7c more robust: clean up unfinished jobs on init, e.g. if build_manager process was forcefully terminated;
Fabian Huch <huch@in.tum.de>
parents: 80779
diff changeset
  1037
      }
d6417e967a7c more robust: clean up unfinished jobs on init, e.g. if build_manager process was forcefully terminated;
Fabian Huch <huch@in.tum.de>
parents: 80779
diff changeset
  1038
d6417e967a7c more robust: clean up unfinished jobs on init, e.g. if build_manager process was forcefully terminated;
Fabian Huch <huch@in.tum.de>
parents: 80779
diff changeset
  1039
      Runner.State.init(store.options)
d6417e967a7c more robust: clean up unfinished jobs on init, e.g. if build_manager process was forcefully terminated;
Fabian Huch <huch@in.tum.de>
parents: 80779
diff changeset
  1040
    }
d6417e967a7c more robust: clean up unfinished jobs on init, e.g. if build_manager process was forcefully terminated;
Fabian Huch <huch@in.tum.de>
parents: 80779
diff changeset
  1041
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1042
    def loop_body(state: Runner.State): Runner.State = {
80281
17d2f775907a add cluster/hosts configurations to build manager: allows running jobs in parallel on distinct hardware;
Fabian Huch <huch@in.tum.de>
parents: 80280
diff changeset
  1043
      val state1 =
17d2f775907a add cluster/hosts configurations to build manager: allows running jobs in parallel on distinct hardware;
Fabian Huch <huch@in.tum.de>
parents: 80280
diff changeset
  1044
        if (progress.stopped) state
17d2f775907a add cluster/hosts configurations to build manager: allows running jobs in parallel on distinct hardware;
Fabian Huch <huch@in.tum.de>
parents: 80280
diff changeset
  1045
        else {
17d2f775907a add cluster/hosts configurations to build manager: allows running jobs in parallel on distinct hardware;
Fabian Huch <huch@in.tum.de>
parents: 80280
diff changeset
  1046
          start_next() match {
17d2f775907a add cluster/hosts configurations to build manager: allows running jobs in parallel on distinct hardware;
Fabian Huch <huch@in.tum.de>
parents: 80280
diff changeset
  1047
            case None => state
17d2f775907a add cluster/hosts configurations to build manager: allows running jobs in parallel on distinct hardware;
Fabian Huch <huch@in.tum.de>
parents: 80280
diff changeset
  1048
            case Some(context) => state.init(context)
17d2f775907a add cluster/hosts configurations to build manager: allows running jobs in parallel on distinct hardware;
Fabian Huch <huch@in.tum.de>
parents: 80280
diff changeset
  1049
          }
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1050
        }
80281
17d2f775907a add cluster/hosts configurations to build manager: allows running jobs in parallel on distinct hardware;
Fabian Huch <huch@in.tum.de>
parents: 80280
diff changeset
  1051
      val state2 = stop_cancelled(state1)
17d2f775907a add cluster/hosts configurations to build manager: allows running jobs in parallel on distinct hardware;
Fabian Huch <huch@in.tum.de>
parents: 80280
diff changeset
  1052
      val (state3, results) = state2.update
17d2f775907a add cluster/hosts configurations to build manager: allows running jobs in parallel on distinct hardware;
Fabian Huch <huch@in.tum.de>
parents: 80280
diff changeset
  1053
      results.foreach(finish_job)
17d2f775907a add cluster/hosts configurations to build manager: allows running jobs in parallel on distinct hardware;
Fabian Huch <huch@in.tum.de>
parents: 80280
diff changeset
  1054
      state3
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1055
    }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1056
  }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1057
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1058
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1059
  /* repository poller */
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1060
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1061
  object Poller {
80574
90493e889dff clarified: more uniform;
Fabian Huch <huch@in.tum.de>
parents: 80547
diff changeset
  1062
    case class State(current: List[Component], next: Future[List[Component]])
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1063
  }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1064
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1065
  class Poller(
80412
a7f8249533e9 moved ci_build module to build_ci;
Fabian Huch <huch@in.tum.de>
parents: 80411
diff changeset
  1066
    ci_jobs: List[Build_CI.Job],
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1067
    store: Store,
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1068
    isabelle_repository: Mercurial.Repository,
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1069
    sync_dirs: List[Sync.Dir],
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1070
    progress: Progress
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1071
  ) extends Loop_Process[Poller.State]("Poller", store, progress) {
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1072
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1073
    override def delay = options.seconds("build_manager_poll_delay")
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1074
80574
90493e889dff clarified: more uniform;
Fabian Huch <huch@in.tum.de>
parents: 80547
diff changeset
  1075
    private def current: List[Component] =
90493e889dff clarified: more uniform;
Fabian Huch <huch@in.tum.de>
parents: 80547
diff changeset
  1076
      Component.isabelle(isabelle_repository.id("default")) ::
90493e889dff clarified: more uniform;
Fabian Huch <huch@in.tum.de>
parents: 80547
diff changeset
  1077
        sync_dirs.map(dir => Component(dir.name, dir.hg.id("default")))
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1078
80574
90493e889dff clarified: more uniform;
Fabian Huch <huch@in.tum.de>
parents: 80547
diff changeset
  1079
    private def poll: Future[List[Component]] = Future.fork {
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1080
      Par_List.map((repo: Mercurial.Repository) => repo.pull(),
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1081
        isabelle_repository :: sync_dirs.map(_.hg))
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1082
80260
ed9b1598d293 manage components of ci builds;
Fabian Huch <huch@in.tum.de>
parents: 80259
diff changeset
  1083
      current
ed9b1598d293 manage components of ci builds;
Fabian Huch <huch@in.tum.de>
parents: 80259
diff changeset
  1084
    }
ed9b1598d293 manage components of ci builds;
Fabian Huch <huch@in.tum.de>
parents: 80259
diff changeset
  1085
ed9b1598d293 manage components of ci builds;
Fabian Huch <huch@in.tum.de>
parents: 80259
diff changeset
  1086
    val init: Poller.State = Poller.State(current, poll)
ed9b1598d293 manage components of ci builds;
Fabian Huch <huch@in.tum.de>
parents: 80259
diff changeset
  1087
80574
90493e889dff clarified: more uniform;
Fabian Huch <huch@in.tum.de>
parents: 80547
diff changeset
  1088
    private def add_tasks(current: List[Component], next: List[Component]): Unit = {
80575
01edf83f6dee better poller: don't start job when same version is already running;
Fabian Huch <huch@in.tum.de>
parents: 80574
diff changeset
  1089
      val next_rev = next.map(component => component.name -> component.rev).toMap
01edf83f6dee better poller: don't start job when same version is already running;
Fabian Huch <huch@in.tum.de>
parents: 80574
diff changeset
  1090
01edf83f6dee better poller: don't start job when same version is already running;
Fabian Huch <huch@in.tum.de>
parents: 80574
diff changeset
  1091
      def is_unchanged(components: List[Component]): Boolean =
01edf83f6dee better poller: don't start job when same version is already running;
Fabian Huch <huch@in.tum.de>
parents: 80574
diff changeset
  1092
        components.forall(component => next_rev.get(component.name).contains(component.rev))
01edf83f6dee better poller: don't start job when same version is already running;
Fabian Huch <huch@in.tum.de>
parents: 80574
diff changeset
  1093
01edf83f6dee better poller: don't start job when same version is already running;
Fabian Huch <huch@in.tum.de>
parents: 80574
diff changeset
  1094
      def is_changed(component_names: List[String]): Boolean =
01edf83f6dee better poller: don't start job when same version is already running;
Fabian Huch <huch@in.tum.de>
parents: 80574
diff changeset
  1095
        !is_unchanged(current.filter(component => component_names.contains(component.name)))
01edf83f6dee better poller: don't start job when same version is already running;
Fabian Huch <huch@in.tum.de>
parents: 80574
diff changeset
  1096
01edf83f6dee better poller: don't start job when same version is already running;
Fabian Huch <huch@in.tum.de>
parents: 80574
diff changeset
  1097
      def is_current(job: Job): Boolean = is_unchanged(job.components)
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1098
80260
ed9b1598d293 manage components of ci builds;
Fabian Huch <huch@in.tum.de>
parents: 80259
diff changeset
  1099
      synchronized_database("add_tasks") {
ed9b1598d293 manage components of ci builds;
Fabian Huch <huch@in.tum.de>
parents: 80259
diff changeset
  1100
        for {
ed9b1598d293 manage components of ci builds;
Fabian Huch <huch@in.tum.de>
parents: 80259
diff changeset
  1101
          ci_job <- ci_jobs
80412
a7f8249533e9 moved ci_build module to build_ci;
Fabian Huch <huch@in.tum.de>
parents: 80411
diff changeset
  1102
          if ci_job.trigger == Build_CI.On_Commit
80575
01edf83f6dee better poller: don't start job when same version is already running;
Fabian Huch <huch@in.tum.de>
parents: 80574
diff changeset
  1103
          if is_changed(Component.Isabelle :: ci_job.components)
80260
ed9b1598d293 manage components of ci builds;
Fabian Huch <huch@in.tum.de>
parents: 80259
diff changeset
  1104
          if !_state.pending.values.exists(_.kind == ci_job.name)
80575
01edf83f6dee better poller: don't start job when same version is already running;
Fabian Huch <huch@in.tum.de>
parents: 80574
diff changeset
  1105
          if !_state.running.values.filter(_.kind == ci_job.name).exists(is_current)
80416
c369b0419172 clarified: more operations;
Fabian Huch <huch@in.tum.de>
parents: 80414
diff changeset
  1106
        } _state = _state.add_pending(CI_Build.task(ci_job))
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1107
      }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1108
    }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1109
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1110
    def loop_body(state: Poller.State): Poller.State =
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1111
      if (!state.next.is_finished) state
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1112
      else {
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1113
        state.next.join_result match {
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1114
          case Exn.Exn(exn) =>
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1115
            echo_error_message("Could not reach repository: " + exn.getMessage)
80260
ed9b1598d293 manage components of ci builds;
Fabian Huch <huch@in.tum.de>
parents: 80259
diff changeset
  1116
            Poller.State(state.current, poll)
ed9b1598d293 manage components of ci builds;
Fabian Huch <huch@in.tum.de>
parents: 80259
diff changeset
  1117
          case Exn.Res(next) =>
ed9b1598d293 manage components of ci builds;
Fabian Huch <huch@in.tum.de>
parents: 80259
diff changeset
  1118
            if (state.current != next) {
ed9b1598d293 manage components of ci builds;
Fabian Huch <huch@in.tum.de>
parents: 80259
diff changeset
  1119
              echo("Found new revisions: " + next)
ed9b1598d293 manage components of ci builds;
Fabian Huch <huch@in.tum.de>
parents: 80259
diff changeset
  1120
              add_tasks(state.current, next)
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1121
            }
80260
ed9b1598d293 manage components of ci builds;
Fabian Huch <huch@in.tum.de>
parents: 80259
diff changeset
  1122
            Poller.State(next, poll)
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1123
        }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1124
      }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1125
  }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1126
80261
e3f472221f8f add triggers to ci jobs: on commit vs timed;
Fabian Huch <huch@in.tum.de>
parents: 80260
diff changeset
  1127
  class Timer(
80412
a7f8249533e9 moved ci_build module to build_ci;
Fabian Huch <huch@in.tum.de>
parents: 80411
diff changeset
  1128
    ci_jobs: List[Build_CI.Job],
80261
e3f472221f8f add triggers to ci jobs: on commit vs timed;
Fabian Huch <huch@in.tum.de>
parents: 80260
diff changeset
  1129
    store: Store,
e3f472221f8f add triggers to ci jobs: on commit vs timed;
Fabian Huch <huch@in.tum.de>
parents: 80260
diff changeset
  1130
    progress: Progress
e3f472221f8f add triggers to ci jobs: on commit vs timed;
Fabian Huch <huch@in.tum.de>
parents: 80260
diff changeset
  1131
  ) extends Loop_Process[Date]("Timer", store, progress) {
e3f472221f8f add triggers to ci jobs: on commit vs timed;
Fabian Huch <huch@in.tum.de>
parents: 80260
diff changeset
  1132
80406
d85ad13d8cf3 extra timer delay, to limit db transactions;
Fabian Huch <huch@in.tum.de>
parents: 80405
diff changeset
  1133
    override def delay = options.seconds("build_manager_timer_delay")
80410
Fabian Huch <huch@in.tum.de>
parents: 80409
diff changeset
  1134
80405
661a226bb49a proper synchronized;
Fabian Huch <huch@in.tum.de>
parents: 80396
diff changeset
  1135
    private def add_tasks(previous: Date, next: Date): Unit = synchronized_database("add_tasks") {
661a226bb49a proper synchronized;
Fabian Huch <huch@in.tum.de>
parents: 80396
diff changeset
  1136
      for (ci_job <- ci_jobs)
80261
e3f472221f8f add triggers to ci jobs: on commit vs timed;
Fabian Huch <huch@in.tum.de>
parents: 80260
diff changeset
  1137
        ci_job.trigger match {
81882
2adff49492f0 clarified;
Fabian Huch <huch@in.tum.de>
parents: 81881
diff changeset
  1138
          case timer: Build_CI.Timed if timer.next(previous, next) =>
80416
c369b0419172 clarified: more operations;
Fabian Huch <huch@in.tum.de>
parents: 80414
diff changeset
  1139
            val task = CI_Build.task(ci_job)
80349
2503ff5d29ce tuned messages;
Fabian Huch <huch@in.tum.de>
parents: 80348
diff changeset
  1140
            echo("Triggered task " + task.kind)
80261
e3f472221f8f add triggers to ci jobs: on commit vs timed;
Fabian Huch <huch@in.tum.de>
parents: 80260
diff changeset
  1141
            _state = _state.add_pending(task)
e3f472221f8f add triggers to ci jobs: on commit vs timed;
Fabian Huch <huch@in.tum.de>
parents: 80260
diff changeset
  1142
          case _ =>
e3f472221f8f add triggers to ci jobs: on commit vs timed;
Fabian Huch <huch@in.tum.de>
parents: 80260
diff changeset
  1143
        }
80405
661a226bb49a proper synchronized;
Fabian Huch <huch@in.tum.de>
parents: 80396
diff changeset
  1144
    }
80261
e3f472221f8f add triggers to ci jobs: on commit vs timed;
Fabian Huch <huch@in.tum.de>
parents: 80260
diff changeset
  1145
e3f472221f8f add triggers to ci jobs: on commit vs timed;
Fabian Huch <huch@in.tum.de>
parents: 80260
diff changeset
  1146
    def init: Date = Date.now()
e3f472221f8f add triggers to ci jobs: on commit vs timed;
Fabian Huch <huch@in.tum.de>
parents: 80260
diff changeset
  1147
    def loop_body(previous: Date): Date = {
e3f472221f8f add triggers to ci jobs: on commit vs timed;
Fabian Huch <huch@in.tum.de>
parents: 80260
diff changeset
  1148
      val now = Date.now()
e3f472221f8f add triggers to ci jobs: on commit vs timed;
Fabian Huch <huch@in.tum.de>
parents: 80260
diff changeset
  1149
      add_tasks(previous, now)
e3f472221f8f add triggers to ci jobs: on commit vs timed;
Fabian Huch <huch@in.tum.de>
parents: 80260
diff changeset
  1150
      now
e3f472221f8f add triggers to ci jobs: on commit vs timed;
Fabian Huch <huch@in.tum.de>
parents: 80260
diff changeset
  1151
    }
e3f472221f8f add triggers to ci jobs: on commit vs timed;
Fabian Huch <huch@in.tum.de>
parents: 80260
diff changeset
  1152
  }
e3f472221f8f add triggers to ci jobs: on commit vs timed;
Fabian Huch <huch@in.tum.de>
parents: 80260
diff changeset
  1153
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1154
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1155
  /* web server */
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1156
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1157
  object Web_Server {
80338
5a6cc89c8f98 proper web server address;
Fabian Huch <huch@in.tum.de>
parents: 80337
diff changeset
  1158
    val Id = new Properties.String(Markup.ID)
5a6cc89c8f98 proper web server address;
Fabian Huch <huch@in.tum.de>
parents: 80337
diff changeset
  1159
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1160
    object Page {
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1161
      val HOME = Path.basic("home")
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1162
      val OVERVIEW = Path.basic("overview")
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1163
      val BUILD = Path.basic("build")
80535
417fcf9f5e71 render hg diff and log (on separate page);
Fabian Huch <huch@in.tum.de>
parents: 80534
diff changeset
  1164
      val DIFF = Path.basic("diff")
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1165
    }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1166
80348
3b4f9e8b46cb clarified web server paths;
Fabian Huch <huch@in.tum.de>
parents: 80346
diff changeset
  1167
    def paths(store: Store): Web_App.Paths =
3b4f9e8b46cb clarified web server paths;
Fabian Huch <huch@in.tum.de>
parents: 80346
diff changeset
  1168
      Web_App.Paths(store.address, Path.current, serve_frontend = true, landing = Page.HOME)
3b4f9e8b46cb clarified web server paths;
Fabian Huch <huch@in.tum.de>
parents: 80346
diff changeset
  1169
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1170
    object API {
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1171
      val BUILD_CANCEL = Path.explode("api/build/cancel")
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1172
    }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1173
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1174
    object Cache {
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1175
      def empty: Cache = new Cache()
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1176
    }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1177
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1178
    class Cache private(keep: Time = Time.minutes(1)) {
80497
bd00bdf39c86 clarified build report;
Fabian Huch <huch@in.tum.de>
parents: 80470
diff changeset
  1179
      private var cached: Map[Report, (Time, Report.Data)] = Map.empty
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1180
80497
bd00bdf39c86 clarified build report;
Fabian Huch <huch@in.tum.de>
parents: 80470
diff changeset
  1181
      def update(): Unit = synchronized {
bd00bdf39c86 clarified build report;
Fabian Huch <huch@in.tum.de>
parents: 80470
diff changeset
  1182
        cached =
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1183
          for {
80497
bd00bdf39c86 clarified build report;
Fabian Huch <huch@in.tum.de>
parents: 80470
diff changeset
  1184
            (report, (time, _)) <- cached
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1185
            if time + keep > Time.now()
80497
bd00bdf39c86 clarified build report;
Fabian Huch <huch@in.tum.de>
parents: 80470
diff changeset
  1186
          } yield report -> (time, report.read)
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1187
      }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1188
80497
bd00bdf39c86 clarified build report;
Fabian Huch <huch@in.tum.de>
parents: 80470
diff changeset
  1189
      def lookup(report: Report): Report.Data = synchronized {
bd00bdf39c86 clarified build report;
Fabian Huch <huch@in.tum.de>
parents: 80470
diff changeset
  1190
        cached.get(report) match {
bd00bdf39c86 clarified build report;
Fabian Huch <huch@in.tum.de>
parents: 80470
diff changeset
  1191
          case Some((_, data)) =>
bd00bdf39c86 clarified build report;
Fabian Huch <huch@in.tum.de>
parents: 80470
diff changeset
  1192
            cached += report -> (Time.now(), data)
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1193
          case None =>
80497
bd00bdf39c86 clarified build report;
Fabian Huch <huch@in.tum.de>
parents: 80470
diff changeset
  1194
            cached += report -> (Time.now(), report.read)
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1195
        }
80497
bd00bdf39c86 clarified build report;
Fabian Huch <huch@in.tum.de>
parents: 80470
diff changeset
  1196
        cached(report)._2
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1197
      }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1198
    }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1199
  }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1200
80649
f5ae78dd49d1 build_manager: display more info;
Fabian Huch <huch@in.tum.de>
parents: 80647
diff changeset
  1201
  class Web_Server(
f5ae78dd49d1 build_manager: display more info;
Fabian Huch <huch@in.tum.de>
parents: 80647
diff changeset
  1202
    port: Int,
f5ae78dd49d1 build_manager: display more info;
Fabian Huch <huch@in.tum.de>
parents: 80647
diff changeset
  1203
    store: Store,
f5ae78dd49d1 build_manager: display more info;
Fabian Huch <huch@in.tum.de>
parents: 80647
diff changeset
  1204
    build_hosts: List[Build_Cluster.Host],
f5ae78dd49d1 build_manager: display more info;
Fabian Huch <huch@in.tum.de>
parents: 80647
diff changeset
  1205
    progress: Progress
f5ae78dd49d1 build_manager: display more info;
Fabian Huch <huch@in.tum.de>
parents: 80647
diff changeset
  1206
  ) extends Loop_Process[Unit]("Web_Server", store, progress) {
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1207
    import Web_App.*
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1208
    import Web_Server.*
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1209
80348
3b4f9e8b46cb clarified web server paths;
Fabian Huch <huch@in.tum.de>
parents: 80346
diff changeset
  1210
    val paths = Web_Server.paths(store)
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1211
    val cache = Cache.empty
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1212
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1213
    enum Model {
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1214
      case Error extends Model
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1215
      case Cancelled extends Model
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1216
      case Home(state: State) extends Model
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1217
      case Overview(kind: String, state: State) extends Model
80339
7b948ca986ec clarified;
Fabian Huch <huch@in.tum.de>
parents: 80338
diff changeset
  1218
      case Details(build: Build, state: State, public: Boolean = true) extends Model
80647
3519f026e7d6 tuned and clarified;
Fabian Huch <huch@in.tum.de>
parents: 80646
diff changeset
  1219
      case Diff(build: Build) extends Model
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1220
    }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1221
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1222
    object View {
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1223
      import HTML.*
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1224
      import More_HTML.*
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1225
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1226
      def render_if(cond: Boolean, body: XML.Body): XML.Body = if (cond) body else Nil
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1227
80534
f5da84211ac0 clarified;
Fabian Huch <huch@in.tum.de>
parents: 80533
diff changeset
  1228
      def page_link(path: Path, s: String, props: Properties.T = Nil): XML.Elem =
f5da84211ac0 clarified;
Fabian Huch <huch@in.tum.de>
parents: 80533
diff changeset
  1229
        link(paths.frontend_url(path, props).toString, text(s)) + ("target" -> "_parent")
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1230
80337
02f8a35ed8e2 clarified names: more canonical;
Fabian Huch <huch@in.tum.de>
parents: 80336
diff changeset
  1231
      def link_build(name: String, id: Long): XML.Elem =
80534
f5da84211ac0 clarified;
Fabian Huch <huch@in.tum.de>
parents: 80533
diff changeset
  1232
        page_link(Page.BUILD, "#" + id, Markup.Name(name))
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1233
80647
3519f026e7d6 tuned and clarified;
Fabian Huch <huch@in.tum.de>
parents: 80646
diff changeset
  1234
      private def render_page(name: String)(body: => XML.Body): XML.Body =
3519f026e7d6 tuned and clarified;
Fabian Huch <huch@in.tum.de>
parents: 80646
diff changeset
  1235
        More_HTML.header(List(nav(List(page_link(Page.HOME, "home"))))) ::
80258
60013c49cedc more build manager page;
Fabian Huch <huch@in.tum.de>
parents: 80255
diff changeset
  1236
        main(chapter(name) :: body ::: Nil) :: Nil
60013c49cedc more build manager page;
Fabian Huch <huch@in.tum.de>
parents: 80255
diff changeset
  1237
80419
788b6af566ff better build summaries;
Fabian Huch <huch@in.tum.de>
parents: 80416
diff changeset
  1238
      private def summary(start: Date): XML.Body =
788b6af566ff better build summaries;
Fabian Huch <huch@in.tum.de>
parents: 80416
diff changeset
  1239
        text(" running since " + Build_Log.print_date(start))
788b6af566ff better build summaries;
Fabian Huch <huch@in.tum.de>
parents: 80416
diff changeset
  1240
788b6af566ff better build summaries;
Fabian Huch <huch@in.tum.de>
parents: 80416
diff changeset
  1241
      private def summary(status: Status, start: Date, end: Option[Date]): XML.Body =
788b6af566ff better build summaries;
Fabian Huch <huch@in.tum.de>
parents: 80416
diff changeset
  1242
        text(" (" + status.toString + if_proper(end, " in " + (end.get - start).message_hms) +
788b6af566ff better build summaries;
Fabian Huch <huch@in.tum.de>
parents: 80416
diff changeset
  1243
          ") on " + Build_Log.print_date(start))
788b6af566ff better build summaries;
Fabian Huch <huch@in.tum.de>
parents: 80416
diff changeset
  1244
80258
60013c49cedc more build manager page;
Fabian Huch <huch@in.tum.de>
parents: 80255
diff changeset
  1245
      def render_home(state: State): XML.Body = render_page("Dashboard") {
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1246
        def render_kind(kind: String): XML.Elem = {
80337
02f8a35ed8e2 clarified names: more canonical;
Fabian Huch <huch@in.tum.de>
parents: 80336
diff changeset
  1247
          val running = state.get_running(kind).sortBy(_.id).reverse
02f8a35ed8e2 clarified names: more canonical;
Fabian Huch <huch@in.tum.de>
parents: 80336
diff changeset
  1248
          val finished = state.get_finished(kind).sortBy(_.id).reverse
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1249
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1250
          def render_previous(finished: List[Result]): XML.Body = {
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1251
            val (failed, rest) = finished.span(_.status != Status.ok)
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1252
            val first_failed = failed.lastOption.map(result =>
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1253
              par(
80419
788b6af566ff better build summaries;
Fabian Huch <huch@in.tum.de>
parents: 80416
diff changeset
  1254
                text("first failure: ") ::: link_build(result.name, result.id) ::
788b6af566ff better build summaries;
Fabian Huch <huch@in.tum.de>
parents: 80416
diff changeset
  1255
                summary(result.status, result.start_date, result.end_date)))
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1256
            val last_success = rest.headOption.map(result =>
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1257
              par(
80337
02f8a35ed8e2 clarified names: more canonical;
Fabian Huch <huch@in.tum.de>
parents: 80336
diff changeset
  1258
                text("last success: ") ::: link_build(result.name, result.id) ::
80419
788b6af566ff better build summaries;
Fabian Huch <huch@in.tum.de>
parents: 80416
diff changeset
  1259
                summary(result.status, result.start_date, result.end_date)))
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1260
            first_failed.toList ::: last_success.toList
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1261
          }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1262
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1263
          def render_job(job: Job): XML.Body =
80419
788b6af566ff better build summaries;
Fabian Huch <huch@in.tum.de>
parents: 80416
diff changeset
  1264
            par(link_build(job.name, job.id) :: summary(job.start_date)) ::
80283
c19f44f6525a omit showing previous failures for user builds;
Fabian Huch <huch@in.tum.de>
parents: 80282
diff changeset
  1265
            render_if(
c19f44f6525a omit showing previous failures for user builds;
Fabian Huch <huch@in.tum.de>
parents: 80282
diff changeset
  1266
              finished.headOption.exists(_.status != Status.ok) && job.kind != User_Build.name,
c19f44f6525a omit showing previous failures for user builds;
Fabian Huch <huch@in.tum.de>
parents: 80282
diff changeset
  1267
              render_previous(finished))
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1268
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1269
          def render_result(result: Result): XML.Body =
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1270
            par(
80337
02f8a35ed8e2 clarified names: more canonical;
Fabian Huch <huch@in.tum.de>
parents: 80336
diff changeset
  1271
              link_build(result.name, result.id) ::
80419
788b6af566ff better build summaries;
Fabian Huch <huch@in.tum.de>
parents: 80416
diff changeset
  1272
              summary(result.status, result.start_date, result.end_date)) ::
80258
60013c49cedc more build manager page;
Fabian Huch <huch@in.tum.de>
parents: 80255
diff changeset
  1273
            render_if(result.status != Status.ok && result.kind != User_Build.name,
60013c49cedc more build manager page;
Fabian Huch <huch@in.tum.de>
parents: 80255
diff changeset
  1274
              render_previous(finished.tail))
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1275
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1276
          fieldset(
80534
f5da84211ac0 clarified;
Fabian Huch <huch@in.tum.de>
parents: 80533
diff changeset
  1277
            XML.elem("legend", List(page_link(Page.OVERVIEW, kind, Markup.Kind(kind)))) ::
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1278
            (if (running.nonEmpty) render_job(running.head)
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1279
            else if (finished.nonEmpty) render_result(finished.head)
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1280
            else Nil))
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1281
        }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1282
80649
f5ae78dd49d1 build_manager: display more info;
Fabian Huch <huch@in.tum.de>
parents: 80647
diff changeset
  1283
        val running = state.running.values.toList
f5ae78dd49d1 build_manager: display more info;
Fabian Huch <huch@in.tum.de>
parents: 80647
diff changeset
  1284
        val idle = (build_hosts.map(_.hostname).toSet -- running.flatMap(_.hostnames).toSet).toList
f5ae78dd49d1 build_manager: display more info;
Fabian Huch <huch@in.tum.de>
parents: 80647
diff changeset
  1285
f5ae78dd49d1 build_manager: display more info;
Fabian Huch <huch@in.tum.de>
parents: 80647
diff changeset
  1286
        def render_rows(hostnames: List[String], body: XML.Body): XML.Body =
f5ae78dd49d1 build_manager: display more info;
Fabian Huch <huch@in.tum.de>
parents: 80647
diff changeset
  1287
          hostnames match {
f5ae78dd49d1 build_manager: display more info;
Fabian Huch <huch@in.tum.de>
parents: 80647
diff changeset
  1288
            case Nil => Nil
f5ae78dd49d1 build_manager: display more info;
Fabian Huch <huch@in.tum.de>
parents: 80647
diff changeset
  1289
            case hostname :: Nil => List(tr(List(td(text(hostname)), td(body))))
f5ae78dd49d1 build_manager: display more info;
Fabian Huch <huch@in.tum.de>
parents: 80647
diff changeset
  1290
            case hostname :: hostnames1 =>
f5ae78dd49d1 build_manager: display more info;
Fabian Huch <huch@in.tum.de>
parents: 80647
diff changeset
  1291
              tr(List(td(text(hostname)), td.apply(rowspan(hostnames.length), body))) ::
f5ae78dd49d1 build_manager: display more info;
Fabian Huch <huch@in.tum.de>
parents: 80647
diff changeset
  1292
              hostnames1.map(hostname => tr(List(td(text(hostname)))))
f5ae78dd49d1 build_manager: display more info;
Fabian Huch <huch@in.tum.de>
parents: 80647
diff changeset
  1293
          }
f5ae78dd49d1 build_manager: display more info;
Fabian Huch <huch@in.tum.de>
parents: 80647
diff changeset
  1294
f5ae78dd49d1 build_manager: display more info;
Fabian Huch <huch@in.tum.de>
parents: 80647
diff changeset
  1295
        def render_job(job: Job): XML.Body =
f5ae78dd49d1 build_manager: display more info;
Fabian Huch <huch@in.tum.de>
parents: 80647
diff changeset
  1296
          render_rows(job.hostnames,
f5ae78dd49d1 build_manager: display more info;
Fabian Huch <huch@in.tum.de>
parents: 80647
diff changeset
  1297
            page_link(Page.BUILD, job.name, Markup.Name(job.name)) :: summary(job.start_date))
f5ae78dd49d1 build_manager: display more info;
Fabian Huch <huch@in.tum.de>
parents: 80647
diff changeset
  1298
f5ae78dd49d1 build_manager: display more info;
Fabian Huch <huch@in.tum.de>
parents: 80647
diff changeset
  1299
        par(text("Queue: " + state.pending.size + " tasks waiting")) ::
f5ae78dd49d1 build_manager: display more info;
Fabian Huch <huch@in.tum.de>
parents: 80647
diff changeset
  1300
        table(tr(List(th(text("Host")), th(text("Activity")))) ::
f5ae78dd49d1 build_manager: display more info;
Fabian Huch <huch@in.tum.de>
parents: 80647
diff changeset
  1301
          running.sortBy(_.name).flatMap(render_job) :::
f5ae78dd49d1 build_manager: display more info;
Fabian Huch <huch@in.tum.de>
parents: 80647
diff changeset
  1302
          idle.sorted.map(List(_)).flatMap(render_rows(_, text("idle")))) ::
f5ae78dd49d1 build_manager: display more info;
Fabian Huch <huch@in.tum.de>
parents: 80647
diff changeset
  1303
        section("Builds") ::
f5ae78dd49d1 build_manager: display more info;
Fabian Huch <huch@in.tum.de>
parents: 80647
diff changeset
  1304
        par(text("Total: " + state.num_builds + " builds")) ::
80421
96e1b4f38a17 tuned website;
Fabian Huch <huch@in.tum.de>
parents: 80420
diff changeset
  1305
        state.kinds.sorted.map(render_kind)
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1306
      }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1307
80258
60013c49cedc more build manager page;
Fabian Huch <huch@in.tum.de>
parents: 80255
diff changeset
  1308
      def render_overview(kind: String, state: State): XML.Body =
60013c49cedc more build manager page;
Fabian Huch <huch@in.tum.de>
parents: 80255
diff changeset
  1309
        render_page("Overview: " + kind + " job ") {
60013c49cedc more build manager page;
Fabian Huch <huch@in.tum.de>
parents: 80255
diff changeset
  1310
          def render_job(job: Job): XML.Body =
80419
788b6af566ff better build summaries;
Fabian Huch <huch@in.tum.de>
parents: 80416
diff changeset
  1311
            List(par(link_build(job.name, job.id) :: summary(job.start_date)))
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1312
80258
60013c49cedc more build manager page;
Fabian Huch <huch@in.tum.de>
parents: 80255
diff changeset
  1313
          def render_result(result: Result): XML.Body =
60013c49cedc more build manager page;
Fabian Huch <huch@in.tum.de>
parents: 80255
diff changeset
  1314
            List(par(
80337
02f8a35ed8e2 clarified names: more canonical;
Fabian Huch <huch@in.tum.de>
parents: 80336
diff changeset
  1315
              link_build(result.name, result.id) ::
80419
788b6af566ff better build summaries;
Fabian Huch <huch@in.tum.de>
parents: 80416
diff changeset
  1316
              summary(result.status, result.start_date, result.end_date)))
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1317
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1318
          itemize(
80337
02f8a35ed8e2 clarified names: more canonical;
Fabian Huch <huch@in.tum.de>
parents: 80336
diff changeset
  1319
            state.get_running(kind).sortBy(_.id).reverse.map(render_job) :::
02f8a35ed8e2 clarified names: more canonical;
Fabian Huch <huch@in.tum.de>
parents: 80336
diff changeset
  1320
            state.get_finished(kind).sortBy(_.id).reverse.map(render_result)) :: Nil
80258
60013c49cedc more build manager page;
Fabian Huch <huch@in.tum.de>
parents: 80255
diff changeset
  1321
        }
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1322
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1323
      private val ID = Params.key(Markup.ID)
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1324
80339
7b948ca986ec clarified;
Fabian Huch <huch@in.tum.de>
parents: 80338
diff changeset
  1325
      def render_details(build: Build, state: State, public: Boolean): XML.Body =
7b948ca986ec clarified;
Fabian Huch <huch@in.tum.de>
parents: 80338
diff changeset
  1326
        render_page("Build: " + build.name) {
80337
02f8a35ed8e2 clarified names: more canonical;
Fabian Huch <huch@in.tum.de>
parents: 80336
diff changeset
  1327
          def render_cancel(uuid: UUID.T): XML.Body =
80258
60013c49cedc more build manager page;
Fabian Huch <huch@in.tum.de>
parents: 80255
diff changeset
  1328
            render_if(!public, List(
80337
02f8a35ed8e2 clarified names: more canonical;
Fabian Huch <huch@in.tum.de>
parents: 80336
diff changeset
  1329
              submit_form("", List(hidden(ID, uuid.toString),
80258
60013c49cedc more build manager page;
Fabian Huch <huch@in.tum.de>
parents: 80255
diff changeset
  1330
                api_button(paths.api_route(API.BUILD_CANCEL), "cancel build")))))
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1331
80542
dd86d35375a7 log and display components with empty (unknown) revisions to indicate that they are present;
Fabian Huch <huch@in.tum.de>
parents: 80541
diff changeset
  1332
          def render_rev(components: List[Component], data: Report.Data): XML.Body = {
dd86d35375a7 log and display components with empty (unknown) revisions to indicate that they are present;
Fabian Huch <huch@in.tum.de>
parents: 80541
diff changeset
  1333
            val hg_info = data.component_logs.map(_._1) ++ data.component_diffs.map(_._1)
dd86d35375a7 log and display components with empty (unknown) revisions to indicate that they are present;
Fabian Huch <huch@in.tum.de>
parents: 80541
diff changeset
  1334
            val s = components.mkString(", ")
80501
83c212f7cf97 use ansi colored diffs;
Fabian Huch <huch@in.tum.de>
parents: 80500
diff changeset
  1335
80547
819402eeac34 tuned website;
Fabian Huch <huch@in.tum.de>
parents: 80546
diff changeset
  1336
            if (!components.map(_.name).exists(hg_info.toSet)) text("Components: " + s)
819402eeac34 tuned website;
Fabian Huch <huch@in.tum.de>
parents: 80546
diff changeset
  1337
            else text("Components: ") :+ page_link(Page.DIFF, s, Markup.Name(build.name))
80501
83c212f7cf97 use ansi colored diffs;
Fabian Huch <huch@in.tum.de>
parents: 80500
diff changeset
  1338
          }
80500
12dc23fc3135 add diffs to build manager;
Fabian Huch <huch@in.tum.de>
parents: 80499
diff changeset
  1339
80649
f5ae78dd49d1 build_manager: display more info;
Fabian Huch <huch@in.tum.de>
parents: 80647
diff changeset
  1340
          def waiting_for(host: Build_Cluster.Host): XML.Body =
f5ae78dd49d1 build_manager: display more info;
Fabian Huch <huch@in.tum.de>
parents: 80647
diff changeset
  1341
            build_hosts.find(_.hostname == host.hostname) match {
f5ae78dd49d1 build_manager: display more info;
Fabian Huch <huch@in.tum.de>
parents: 80647
diff changeset
  1342
              case None => break ::: text(quote(host.hostname) + " is not a build host")
f5ae78dd49d1 build_manager: display more info;
Fabian Huch <huch@in.tum.de>
parents: 80647
diff changeset
  1343
              case Some(host) =>
f5ae78dd49d1 build_manager: display more info;
Fabian Huch <huch@in.tum.de>
parents: 80647
diff changeset
  1344
                val active = state.running.values.filter(_.hostnames.contains(host.hostname))
f5ae78dd49d1 build_manager: display more info;
Fabian Huch <huch@in.tum.de>
parents: 80647
diff changeset
  1345
                if (active.isEmpty) Nil
f5ae78dd49d1 build_manager: display more info;
Fabian Huch <huch@in.tum.de>
parents: 80647
diff changeset
  1346
                else break :::
f5ae78dd49d1 build_manager: display more info;
Fabian Huch <huch@in.tum.de>
parents: 80647
diff changeset
  1347
                  text(host.hostname + " is busy with " + active.map(_.name).mkString(" and "))
f5ae78dd49d1 build_manager: display more info;
Fabian Huch <huch@in.tum.de>
parents: 80647
diff changeset
  1348
            }
f5ae78dd49d1 build_manager: display more info;
Fabian Huch <huch@in.tum.de>
parents: 80647
diff changeset
  1349
f5ae78dd49d1 build_manager: display more info;
Fabian Huch <huch@in.tum.de>
parents: 80647
diff changeset
  1350
          def waiting(task: Task): XML.Body = {
f5ae78dd49d1 build_manager: display more info;
Fabian Huch <huch@in.tum.de>
parents: 80647
diff changeset
  1351
            val num_before = state.pending.values.count(_ > task)
f5ae78dd49d1 build_manager: display more info;
Fabian Huch <huch@in.tum.de>
parents: 80647
diff changeset
  1352
f5ae78dd49d1 build_manager: display more info;
Fabian Huch <huch@in.tum.de>
parents: 80647
diff changeset
  1353
            if (num_before > 0) text("Waiting for " + num_before + " tasks to complete")
f5ae78dd49d1 build_manager: display more info;
Fabian Huch <huch@in.tum.de>
parents: 80647
diff changeset
  1354
            else Exn.capture(task.build_hosts) match {
f5ae78dd49d1 build_manager: display more info;
Fabian Huch <huch@in.tum.de>
parents: 80647
diff changeset
  1355
              case Exn.Res(hosts) => text("Hosts not ready:") ::: hosts.flatMap(waiting_for)
f5ae78dd49d1 build_manager: display more info;
Fabian Huch <huch@in.tum.de>
parents: 80647
diff changeset
  1356
              case _ => text("Unkown host spec")
f5ae78dd49d1 build_manager: display more info;
Fabian Huch <huch@in.tum.de>
parents: 80647
diff changeset
  1357
            }
f5ae78dd49d1 build_manager: display more info;
Fabian Huch <huch@in.tum.de>
parents: 80647
diff changeset
  1358
          }
f5ae78dd49d1 build_manager: display more info;
Fabian Huch <huch@in.tum.de>
parents: 80647
diff changeset
  1359
f5ae78dd49d1 build_manager: display more info;
Fabian Huch <huch@in.tum.de>
parents: 80647
diff changeset
  1360
          def started(user: Option[String], date: Date): String =
f5ae78dd49d1 build_manager: display more info;
Fabian Huch <huch@in.tum.de>
parents: 80647
diff changeset
  1361
            "Started" + if_proper(user, " by " + user.get) + " on " + Build_Log.print_date(date)
f5ae78dd49d1 build_manager: display more info;
Fabian Huch <huch@in.tum.de>
parents: 80647
diff changeset
  1362
80339
7b948ca986ec clarified;
Fabian Huch <huch@in.tum.de>
parents: 80338
diff changeset
  1363
          build match {
80258
60013c49cedc more build manager page;
Fabian Huch <huch@in.tum.de>
parents: 80255
diff changeset
  1364
            case task: Task =>
80420
80e10a1aa431 better results view;
Fabian Huch <huch@in.tum.de>
parents: 80419
diff changeset
  1365
              par(text("Task from " + Build_Log.print_date(task.submit_date) + ". ")) ::
80649
f5ae78dd49d1 build_manager: display more info;
Fabian Huch <huch@in.tum.de>
parents: 80647
diff changeset
  1366
              par(text("Components: " + task.components.mkString(", "))) ::
f5ae78dd49d1 build_manager: display more info;
Fabian Huch <huch@in.tum.de>
parents: 80647
diff changeset
  1367
              par(List(bold(waiting(task)))) ::
80337
02f8a35ed8e2 clarified names: more canonical;
Fabian Huch <huch@in.tum.de>
parents: 80336
diff changeset
  1368
              render_cancel(task.uuid)
80502
db89ef6a8a42 tuned whitespace;
Fabian Huch <huch@in.tum.de>
parents: 80501
diff changeset
  1369
80258
60013c49cedc more build manager page;
Fabian Huch <huch@in.tum.de>
parents: 80255
diff changeset
  1370
            case job: Job =>
80497
bd00bdf39c86 clarified build report;
Fabian Huch <huch@in.tum.de>
parents: 80470
diff changeset
  1371
              val report_data = cache.lookup(store.report(job.kind, job.id))
bd00bdf39c86 clarified build report;
Fabian Huch <huch@in.tum.de>
parents: 80470
diff changeset
  1372
80649
f5ae78dd49d1 build_manager: display more info;
Fabian Huch <huch@in.tum.de>
parents: 80647
diff changeset
  1373
              par(text(started(job.user, job.start_date))) ::
80258
60013c49cedc more build manager page;
Fabian Huch <huch@in.tum.de>
parents: 80255
diff changeset
  1374
              par(
80518
d3b96e19ccc7 tuned messages: whitespace following usual Isabelle conventions;
wenzelm
parents: 80502
diff changeset
  1375
                if (job.cancelled) text("Cancelling ...")
d3b96e19ccc7 tuned messages: whitespace following usual Isabelle conventions;
wenzelm
parents: 80502
diff changeset
  1376
                else text("Running ...") ::: render_cancel(job.uuid)) ::
80535
417fcf9f5e71 render hg diff and log (on separate page);
Fabian Huch <huch@in.tum.de>
parents: 80534
diff changeset
  1377
              par(render_rev(job.components, report_data)) ::
417fcf9f5e71 render hg diff and log (on separate page);
Fabian Huch <huch@in.tum.de>
parents: 80534
diff changeset
  1378
              par(List(source(report_data.build_log))) :: Nil
80502
db89ef6a8a42 tuned whitespace;
Fabian Huch <huch@in.tum.de>
parents: 80501
diff changeset
  1379
80258
60013c49cedc more build manager page;
Fabian Huch <huch@in.tum.de>
parents: 80255
diff changeset
  1380
            case result: Result =>
80497
bd00bdf39c86 clarified build report;
Fabian Huch <huch@in.tum.de>
parents: 80470
diff changeset
  1381
              val report_data = cache.lookup(store.report(result.kind, result.id))
bd00bdf39c86 clarified build report;
Fabian Huch <huch@in.tum.de>
parents: 80470
diff changeset
  1382
80649
f5ae78dd49d1 build_manager: display more info;
Fabian Huch <huch@in.tum.de>
parents: 80647
diff changeset
  1383
              par(text(started(result.user, result.start_date) +
80420
80e10a1aa431 better results view;
Fabian Huch <huch@in.tum.de>
parents: 80419
diff changeset
  1384
                if_proper(result.end_date,
80e10a1aa431 better results view;
Fabian Huch <huch@in.tum.de>
parents: 80419
diff changeset
  1385
                  ", took " + (result.end_date.get - result.start_date).message_hms))) ::
80258
60013c49cedc more build manager page;
Fabian Huch <huch@in.tum.de>
parents: 80255
diff changeset
  1386
              par(text("Status: " + result.status)) ::
80535
417fcf9f5e71 render hg diff and log (on separate page);
Fabian Huch <huch@in.tum.de>
parents: 80534
diff changeset
  1387
              par(render_rev(result.components, report_data)) ::
417fcf9f5e71 render hg diff and log (on separate page);
Fabian Huch <huch@in.tum.de>
parents: 80534
diff changeset
  1388
              par(List(source(report_data.build_log))) :: Nil
80258
60013c49cedc more build manager page;
Fabian Huch <huch@in.tum.de>
parents: 80255
diff changeset
  1389
          }
60013c49cedc more build manager page;
Fabian Huch <huch@in.tum.de>
parents: 80255
diff changeset
  1390
        }
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1391
80647
3519f026e7d6 tuned and clarified;
Fabian Huch <huch@in.tum.de>
parents: 80646
diff changeset
  1392
      def render_diff(build: Build): XML.Body = render_page("Diff: " + build.name) {
80535
417fcf9f5e71 render hg diff and log (on separate page);
Fabian Huch <huch@in.tum.de>
parents: 80534
diff changeset
  1393
        def colored(s: String): XML.Body = {
417fcf9f5e71 render hg diff and log (on separate page);
Fabian Huch <huch@in.tum.de>
parents: 80534
diff changeset
  1394
          val Colored = "([^\u001b]*)\u001b\\[([0-9;]+)m(.*)\u001b\\[0m([^\u001b]*)".r
80536
63afde05a820 tuned HTML display of ANSI colors for better readability;
Fabian Huch <huch@in.tum.de>
parents: 80535
diff changeset
  1395
          val colors = List("black", "maroon", "green", "olive", "navy", "purple", "teal", "silver")
80535
417fcf9f5e71 render hg diff and log (on separate page);
Fabian Huch <huch@in.tum.de>
parents: 80534
diff changeset
  1396
417fcf9f5e71 render hg diff and log (on separate page);
Fabian Huch <huch@in.tum.de>
parents: 80534
diff changeset
  1397
          val lines = split_lines(s).map {
417fcf9f5e71 render hg diff and log (on separate page);
Fabian Huch <huch@in.tum.de>
parents: 80534
diff changeset
  1398
            case Colored(pre, code, s, post) =>
417fcf9f5e71 render hg diff and log (on separate page);
Fabian Huch <huch@in.tum.de>
parents: 80534
diff changeset
  1399
              val codes = space_explode(';', code.stripSuffix(";1")).map(Value.Int.parse)
417fcf9f5e71 render hg diff and log (on separate page);
Fabian Huch <huch@in.tum.de>
parents: 80534
diff changeset
  1400
              val fg = codes match { case 0 :: i :: Nil => colors.unapply(i - 30) case _ => None }
417fcf9f5e71 render hg diff and log (on separate page);
Fabian Huch <huch@in.tum.de>
parents: 80534
diff changeset
  1401
417fcf9f5e71 render hg diff and log (on separate page);
Fabian Huch <huch@in.tum.de>
parents: 80534
diff changeset
  1402
              val sp = span(if (code.endsWith(";1")) List(bold(text(s))) else text(s))
417fcf9f5e71 render hg diff and log (on separate page);
Fabian Huch <huch@in.tum.de>
parents: 80534
diff changeset
  1403
              val sp1 = fg.map(color => sp + ("style" -> ("color:" + color))).getOrElse(sp)
417fcf9f5e71 render hg diff and log (on separate page);
Fabian Huch <huch@in.tum.de>
parents: 80534
diff changeset
  1404
              List(span(text(pre)), sp1, span(text(post)))
417fcf9f5e71 render hg diff and log (on separate page);
Fabian Huch <huch@in.tum.de>
parents: 80534
diff changeset
  1405
            case line => text(Library.strip_ansi_color(line))
417fcf9f5e71 render hg diff and log (on separate page);
Fabian Huch <huch@in.tum.de>
parents: 80534
diff changeset
  1406
          }
417fcf9f5e71 render hg diff and log (on separate page);
Fabian Huch <huch@in.tum.de>
parents: 80534
diff changeset
  1407
417fcf9f5e71 render hg diff and log (on separate page);
Fabian Huch <huch@in.tum.de>
parents: 80534
diff changeset
  1408
          List(source(Library.separate(nl, lines).flatten))
417fcf9f5e71 render hg diff and log (on separate page);
Fabian Huch <huch@in.tum.de>
parents: 80534
diff changeset
  1409
        }
417fcf9f5e71 render hg diff and log (on separate page);
Fabian Huch <huch@in.tum.de>
parents: 80534
diff changeset
  1410
417fcf9f5e71 render hg diff and log (on separate page);
Fabian Huch <huch@in.tum.de>
parents: 80534
diff changeset
  1411
        def render_diff(data: Report.Data, components: List[Component]): XML.Body =
417fcf9f5e71 render hg diff and log (on separate page);
Fabian Huch <huch@in.tum.de>
parents: 80534
diff changeset
  1412
          par(List(page_link(Page.BUILD, "back to build", Markup.Name(build.name)))) ::
417fcf9f5e71 render hg diff and log (on separate page);
Fabian Huch <huch@in.tum.de>
parents: 80534
diff changeset
  1413
          (for (component <- components if !component.is_local) yield {
81881
f23fc3d21873 tuned whitespace;
Fabian Huch <huch@in.tum.de>
parents: 80782
diff changeset
  1414
            val infos =
80535
417fcf9f5e71 render hg diff and log (on separate page);
Fabian Huch <huch@in.tum.de>
parents: 80534
diff changeset
  1415
              data.component_logs.toMap.get(component.name).toList.flatMap(colored) :::
80538
1dd989a9ad88 tuned display;
Fabian Huch <huch@in.tum.de>
parents: 80536
diff changeset
  1416
              data.component_diffs.toMap.get(component.name).toList.flatMap(colored)
1dd989a9ad88 tuned display;
Fabian Huch <huch@in.tum.de>
parents: 80536
diff changeset
  1417
80547
819402eeac34 tuned website;
Fabian Huch <huch@in.tum.de>
parents: 80546
diff changeset
  1418
            val header = if (infos.isEmpty) component.toString else component.name + ":"
819402eeac34 tuned website;
Fabian Huch <huch@in.tum.de>
parents: 80546
diff changeset
  1419
            par(subsubsection(header) :: infos)
80535
417fcf9f5e71 render hg diff and log (on separate page);
Fabian Huch <huch@in.tum.de>
parents: 80534
diff changeset
  1420
          })
417fcf9f5e71 render hg diff and log (on separate page);
Fabian Huch <huch@in.tum.de>
parents: 80534
diff changeset
  1421
417fcf9f5e71 render hg diff and log (on separate page);
Fabian Huch <huch@in.tum.de>
parents: 80534
diff changeset
  1422
        build match {
417fcf9f5e71 render hg diff and log (on separate page);
Fabian Huch <huch@in.tum.de>
parents: 80534
diff changeset
  1423
          case job: Job =>
417fcf9f5e71 render hg diff and log (on separate page);
Fabian Huch <huch@in.tum.de>
parents: 80534
diff changeset
  1424
            render_diff(cache.lookup(store.report(job.kind, job.id)), job.components)
417fcf9f5e71 render hg diff and log (on separate page);
Fabian Huch <huch@in.tum.de>
parents: 80534
diff changeset
  1425
          case result: Result =>
417fcf9f5e71 render hg diff and log (on separate page);
Fabian Huch <huch@in.tum.de>
parents: 80534
diff changeset
  1426
            render_diff(cache.lookup(store.report(result.kind, result.id)), result.components)
417fcf9f5e71 render hg diff and log (on separate page);
Fabian Huch <huch@in.tum.de>
parents: 80534
diff changeset
  1427
          case _ => Nil
417fcf9f5e71 render hg diff and log (on separate page);
Fabian Huch <huch@in.tum.de>
parents: 80534
diff changeset
  1428
        }
417fcf9f5e71 render hg diff and log (on separate page);
Fabian Huch <huch@in.tum.de>
parents: 80534
diff changeset
  1429
      }
417fcf9f5e71 render hg diff and log (on separate page);
Fabian Huch <huch@in.tum.de>
parents: 80534
diff changeset
  1430
80534
f5da84211ac0 clarified;
Fabian Huch <huch@in.tum.de>
parents: 80533
diff changeset
  1431
      def render_cancelled: XML.Body =
f5da84211ac0 clarified;
Fabian Huch <huch@in.tum.de>
parents: 80533
diff changeset
  1432
        render_page("Build cancelled")(List(page_link(Page.HOME, "Home")))
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1433
80337
02f8a35ed8e2 clarified names: more canonical;
Fabian Huch <huch@in.tum.de>
parents: 80336
diff changeset
  1434
      def parse_uuid(params: Params.Data): Option[UUID.T] =
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1435
        for {
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1436
          id <- params.get(ID)
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1437
          uuid <- UUID.unapply(id)
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1438
        } yield uuid
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1439
    }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1440
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1441
    private val server = new Server[Model](paths, port, progress = progress) {
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1442
      /* control */
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1443
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1444
      def overview: Some[Model.Home] = Some(Model.Home(_state))
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1445
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1446
      def get_overview(props: Properties.T): Option[Model.Overview] =
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1447
        props match {
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1448
          case Markup.Kind(kind) => Some(Model.Overview(kind, _state))
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1449
          case _ => None
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1450
        }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1451
80339
7b948ca986ec clarified;
Fabian Huch <huch@in.tum.de>
parents: 80338
diff changeset
  1452
      def get_build(props: Properties.T): Option[Model.Details] =
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1453
        props match {
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1454
          case Markup.Name(name) =>
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1455
            val state = _state
80339
7b948ca986ec clarified;
Fabian Huch <huch@in.tum.de>
parents: 80338
diff changeset
  1456
            state.get(name).map(Model.Details(_, state))
80338
5a6cc89c8f98 proper web server address;
Fabian Huch <huch@in.tum.de>
parents: 80337
diff changeset
  1457
          case Web_Server.Id(UUID(uuid)) =>
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1458
            val state = _state
80339
7b948ca986ec clarified;
Fabian Huch <huch@in.tum.de>
parents: 80338
diff changeset
  1459
            state.get(uuid).map(Model.Details(_, state, public = false))
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1460
          case _ => None
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1461
        }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1462
80535
417fcf9f5e71 render hg diff and log (on separate page);
Fabian Huch <huch@in.tum.de>
parents: 80534
diff changeset
  1463
      def get_diff(props: Properties.T): Option[Model.Diff] =
417fcf9f5e71 render hg diff and log (on separate page);
Fabian Huch <huch@in.tum.de>
parents: 80534
diff changeset
  1464
        props match {
80647
3519f026e7d6 tuned and clarified;
Fabian Huch <huch@in.tum.de>
parents: 80646
diff changeset
  1465
          case Markup.Name(name) => _state.get(name).map(Model.Diff(_))
80535
417fcf9f5e71 render hg diff and log (on separate page);
Fabian Huch <huch@in.tum.de>
parents: 80534
diff changeset
  1466
          case _ => None
417fcf9f5e71 render hg diff and log (on separate page);
Fabian Huch <huch@in.tum.de>
parents: 80534
diff changeset
  1467
        }
417fcf9f5e71 render hg diff and log (on separate page);
Fabian Huch <huch@in.tum.de>
parents: 80534
diff changeset
  1468
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1469
      def cancel_build(params: Params.Data): Option[Model] =
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1470
        for {
80337
02f8a35ed8e2 clarified names: more canonical;
Fabian Huch <huch@in.tum.de>
parents: 80336
diff changeset
  1471
          uuid <- View.parse_uuid(params)
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1472
          model <-
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1473
            synchronized_database("cancel_build") {
80337
02f8a35ed8e2 clarified names: more canonical;
Fabian Huch <huch@in.tum.de>
parents: 80336
diff changeset
  1474
              _state.get(uuid).map {
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1475
                case task: Task =>
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1476
                  _state = _state.remove_pending(task.name)
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1477
                  Model.Cancelled
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1478
                case job: Job =>
80468
8ae5312032cc clarified: more operations;
Fabian Huch <huch@in.tum.de>
parents: 80467
diff changeset
  1479
                  _state = _state.cancel_running(job.name)
80467
010d45681b87 tuned website;
Fabian Huch <huch@in.tum.de>
parents: 80424
diff changeset
  1480
                  Model.Cancelled
80339
7b948ca986ec clarified;
Fabian Huch <huch@in.tum.de>
parents: 80338
diff changeset
  1481
                case result: Result => Model.Details(result, _state, public = false)
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1482
              }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1483
            }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1484
        } yield model
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1485
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1486
      def render(model: Model): XML.Body =
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1487
        HTML.title("Isabelle Build Manager") :: (
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1488
          model match {
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1489
            case Model.Error => HTML.text("invalid request")
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1490
            case Model.Home(state) => View.render_home(state)
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1491
            case Model.Overview(kind, state) => View.render_overview(kind, state)
80339
7b948ca986ec clarified;
Fabian Huch <huch@in.tum.de>
parents: 80338
diff changeset
  1492
            case Model.Details(build, state, public) => View.render_details(build, state, public)
80647
3519f026e7d6 tuned and clarified;
Fabian Huch <huch@in.tum.de>
parents: 80646
diff changeset
  1493
            case Model.Diff(build) => View.render_diff(build)
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1494
            case Model.Cancelled => View.render_cancelled
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1495
          })
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1496
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1497
      val error_model: Model = Model.Error
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1498
      val endpoints = List(
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1499
        Get(Page.HOME, "home", _ => overview),
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1500
        Get(Page.OVERVIEW, "overview", get_overview),
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1501
        Get(Page.BUILD, "build", get_build),
80535
417fcf9f5e71 render hg diff and log (on separate page);
Fabian Huch <huch@in.tum.de>
parents: 80534
diff changeset
  1502
        Get(Page.DIFF, "diff", get_diff),
80259
06a473ad2777 use external CSS for build manager page;
Fabian Huch <huch@in.tum.de>
parents: 80258
diff changeset
  1503
        Post(API.BUILD_CANCEL, "cancel build", cancel_build))
80315
a82db14570cd add favicon to web app;
Fabian Huch <huch@in.tum.de>
parents: 80284
diff changeset
  1504
      val logo = Bytes.read(Path.explode("$ISABELLE_HOME/lib/logo/isabelle_transparent-48.gif"))
80259
06a473ad2777 use external CSS for build manager page;
Fabian Huch <huch@in.tum.de>
parents: 80258
diff changeset
  1505
      val head =
06a473ad2777 use external CSS for build manager page;
Fabian Huch <huch@in.tum.de>
parents: 80258
diff changeset
  1506
        List(
80320
b8ce1269e190 add title;
Fabian Huch <huch@in.tum.de>
parents: 80319
diff changeset
  1507
          HTML.title("Isabelle Build Manager"),
80393
6138c5b803be Base64: proper support for large Bytes, with subtle change of types (Bytes instead of String);
wenzelm
parents: 80346
diff changeset
  1508
          Web_App.More_HTML.icon("data:image/x-icon;base64," + logo.encode_base64.text),
80259
06a473ad2777 use external CSS for build manager page;
Fabian Huch <huch@in.tum.de>
parents: 80258
diff changeset
  1509
          HTML.style_file("https://hawkz.github.io/gdcss/gd.css"),
80650
5555a40b2ed4 build_manager: change colors;
Fabian Huch <huch@in.tum.de>
parents: 80649
diff changeset
  1510
          HTML.style("""
81881
f23fc3d21873 tuned whitespace;
Fabian Huch <huch@in.tum.de>
parents: 80782
diff changeset
  1511
:root {
80650
5555a40b2ed4 build_manager: change colors;
Fabian Huch <huch@in.tum.de>
parents: 80649
diff changeset
  1512
  --color-secondary: var(--color-tertiary);
5555a40b2ed4 build_manager: change colors;
Fabian Huch <huch@in.tum.de>
parents: 80649
diff changeset
  1513
  --color-secondary-hover: var(--color-tertiary-hover);
5555a40b2ed4 build_manager: change colors;
Fabian Huch <huch@in.tum.de>
parents: 80649
diff changeset
  1514
}
5555a40b2ed4 build_manager: change colors;
Fabian Huch <huch@in.tum.de>
parents: 80649
diff changeset
  1515
html { background-color: white; }"""))
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1516
    }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1517
80782
32247ad40647 stop web server on close;
Fabian Huch <huch@in.tum.de>
parents: 80781
diff changeset
  1518
    override def close(): Unit = {
32247ad40647 stop web server on close;
Fabian Huch <huch@in.tum.de>
parents: 80781
diff changeset
  1519
      server.stop()
32247ad40647 stop web server on close;
Fabian Huch <huch@in.tum.de>
parents: 80781
diff changeset
  1520
      super.close()
32247ad40647 stop web server on close;
Fabian Huch <huch@in.tum.de>
parents: 80781
diff changeset
  1521
    }
32247ad40647 stop web server on close;
Fabian Huch <huch@in.tum.de>
parents: 80781
diff changeset
  1522
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1523
    def init: Unit = server.start()
80782
32247ad40647 stop web server on close;
Fabian Huch <huch@in.tum.de>
parents: 80781
diff changeset
  1524
    def loop_body(u: Unit): Unit =
32247ad40647 stop web server on close;
Fabian Huch <huch@in.tum.de>
parents: 80781
diff changeset
  1525
      if (!progress.stopped) synchronized_database("iterate") { cache.update() }
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1526
  }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1527
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1528
80344
f05a71fa1a3f tuned comments;
Fabian Huch <huch@in.tum.de>
parents: 80343
diff changeset
  1529
  /** context **/
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1530
80337
02f8a35ed8e2 clarified names: more canonical;
Fabian Huch <huch@in.tum.de>
parents: 80336
diff changeset
  1531
  case class Context(store: Store, task: Task, id: Long) {
80339
7b948ca986ec clarified;
Fabian Huch <huch@in.tum.de>
parents: 80338
diff changeset
  1532
    def name = Build.name(task.kind, id)
80497
bd00bdf39c86 clarified build report;
Fabian Huch <huch@in.tum.de>
parents: 80470
diff changeset
  1533
    def report: Report = store.report(task.kind, id)
80281
17d2f775907a add cluster/hosts configurations to build manager: allows running jobs in parallel on distinct hardware;
Fabian Huch <huch@in.tum.de>
parents: 80280
diff changeset
  1534
    def task_dir: Path = store.task_dir(task)
17d2f775907a add cluster/hosts configurations to build manager: allows running jobs in parallel on distinct hardware;
Fabian Huch <huch@in.tum.de>
parents: 80280
diff changeset
  1535
17d2f775907a add cluster/hosts configurations to build manager: allows running jobs in parallel on distinct hardware;
Fabian Huch <huch@in.tum.de>
parents: 80280
diff changeset
  1536
    def isabelle_identifier: String =
17d2f775907a add cluster/hosts configurations to build manager: allows running jobs in parallel on distinct hardware;
Fabian Huch <huch@in.tum.de>
parents: 80280
diff changeset
  1537
      if (task.build_cluster) store.options.string("build_cluster_identifier") else store.identifier
17d2f775907a add cluster/hosts configurations to build manager: allows running jobs in parallel on distinct hardware;
Fabian Huch <huch@in.tum.de>
parents: 80280
diff changeset
  1538
17d2f775907a add cluster/hosts configurations to build manager: allows running jobs in parallel on distinct hardware;
Fabian Huch <huch@in.tum.de>
parents: 80280
diff changeset
  1539
    def open_ssh(): SSH.System = {
82040
0dc7b3253aaa clarified options: extra ssh connection to cluster of build_manager;
Fabian Huch <huch@in.tum.de>
parents: 82039
diff changeset
  1540
      if (task.build_cluster) store.open_cluster_ssh()
80281
17d2f775907a add cluster/hosts configurations to build manager: allows running jobs in parallel on distinct hardware;
Fabian Huch <huch@in.tum.de>
parents: 80280
diff changeset
  1541
      else Library.the_single(task.build_hosts).open_ssh(store.options)
17d2f775907a add cluster/hosts configurations to build manager: allows running jobs in parallel on distinct hardware;
Fabian Huch <huch@in.tum.de>
parents: 80280
diff changeset
  1542
    }
80279
02424b81472a clarified: add explicit build process;
Fabian Huch <huch@in.tum.de>
parents: 80278
diff changeset
  1543
  }
02424b81472a clarified: add explicit build process;
Fabian Huch <huch@in.tum.de>
parents: 80278
diff changeset
  1544
02424b81472a clarified: add explicit build process;
Fabian Huch <huch@in.tum.de>
parents: 80278
diff changeset
  1545
80344
f05a71fa1a3f tuned comments;
Fabian Huch <huch@in.tum.de>
parents: 80343
diff changeset
  1546
  /** build process **/
80279
02424b81472a clarified: add explicit build process;
Fabian Huch <huch@in.tum.de>
parents: 80278
diff changeset
  1547
02424b81472a clarified: add explicit build process;
Fabian Huch <huch@in.tum.de>
parents: 80278
diff changeset
  1548
  object Build_Process {
80280
7987b33fb6c5 clarified context: operations now in build process;
Fabian Huch <huch@in.tum.de>
parents: 80279
diff changeset
  1549
    def open(context: Context): Build_Process = new Build_Process(context.open_ssh(), context)
80279
02424b81472a clarified: add explicit build process;
Fabian Huch <huch@in.tum.de>
parents: 80278
diff changeset
  1550
  }
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1551
80281
17d2f775907a add cluster/hosts configurations to build manager: allows running jobs in parallel on distinct hardware;
Fabian Huch <huch@in.tum.de>
parents: 80280
diff changeset
  1552
  class Build_Process(ssh: SSH.System, context: Context) {
17d2f775907a add cluster/hosts configurations to build manager: allows running jobs in parallel on distinct hardware;
Fabian Huch <huch@in.tum.de>
parents: 80280
diff changeset
  1553
    private val task = context.task
80497
bd00bdf39c86 clarified build report;
Fabian Huch <huch@in.tum.de>
parents: 80470
diff changeset
  1554
    private val progress = context.report.progress
80281
17d2f775907a add cluster/hosts configurations to build manager: allows running jobs in parallel on distinct hardware;
Fabian Huch <huch@in.tum.de>
parents: 80280
diff changeset
  1555
17d2f775907a add cluster/hosts configurations to build manager: allows running jobs in parallel on distinct hardware;
Fabian Huch <huch@in.tum.de>
parents: 80280
diff changeset
  1556
17d2f775907a add cluster/hosts configurations to build manager: allows running jobs in parallel on distinct hardware;
Fabian Huch <huch@in.tum.de>
parents: 80280
diff changeset
  1557
    /* resources with cleanup operations */
17d2f775907a add cluster/hosts configurations to build manager: allows running jobs in parallel on distinct hardware;
Fabian Huch <huch@in.tum.de>
parents: 80280
diff changeset
  1558
80279
02424b81472a clarified: add explicit build process;
Fabian Huch <huch@in.tum.de>
parents: 80278
diff changeset
  1559
    private val _dir = ssh.tmp_dir()
02424b81472a clarified: add explicit build process;
Fabian Huch <huch@in.tum.de>
parents: 80278
diff changeset
  1560
    private val _isabelle =
02424b81472a clarified: add explicit build process;
Fabian Huch <huch@in.tum.de>
parents: 80278
diff changeset
  1561
      try {
02424b81472a clarified: add explicit build process;
Fabian Huch <huch@in.tum.de>
parents: 80278
diff changeset
  1562
        val rsync_context = Rsync.Context(ssh = ssh)
80280
7987b33fb6c5 clarified context: operations now in build process;
Fabian Huch <huch@in.tum.de>
parents: 80279
diff changeset
  1563
        val source = File.standard_path(context.task_dir)
80279
02424b81472a clarified: add explicit build process;
Fabian Huch <huch@in.tum.de>
parents: 80278
diff changeset
  1564
        Rsync.exec(rsync_context, clean = true, args = List("--", Url.direct_path(source),
02424b81472a clarified: add explicit build process;
Fabian Huch <huch@in.tum.de>
parents: 80278
diff changeset
  1565
          rsync_context.target(_dir))).check
02424b81472a clarified: add explicit build process;
Fabian Huch <huch@in.tum.de>
parents: 80278
diff changeset
  1566
80280
7987b33fb6c5 clarified context: operations now in build process;
Fabian Huch <huch@in.tum.de>
parents: 80279
diff changeset
  1567
        Isabelle_System.rm_tree(context.task_dir)
80281
17d2f775907a add cluster/hosts configurations to build manager: allows running jobs in parallel on distinct hardware;
Fabian Huch <huch@in.tum.de>
parents: 80280
diff changeset
  1568
        Other_Isabelle(_dir, context.isabelle_identifier, ssh, progress)
80279
02424b81472a clarified: add explicit build process;
Fabian Huch <huch@in.tum.de>
parents: 80278
diff changeset
  1569
      }
02424b81472a clarified: add explicit build process;
Fabian Huch <huch@in.tum.de>
parents: 80278
diff changeset
  1570
      catch { case exn: Throwable => close(); throw exn }
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1571
80279
02424b81472a clarified: add explicit build process;
Fabian Huch <huch@in.tum.de>
parents: 80278
diff changeset
  1572
    private val _process =
02424b81472a clarified: add explicit build process;
Fabian Huch <huch@in.tum.de>
parents: 80278
diff changeset
  1573
      try {
02424b81472a clarified: add explicit build process;
Fabian Huch <huch@in.tum.de>
parents: 80278
diff changeset
  1574
        val init_components =
02424b81472a clarified: add explicit build process;
Fabian Huch <huch@in.tum.de>
parents: 80278
diff changeset
  1575
          for {
80499
433475f17d73 clarified: components vs. extra components;
Fabian Huch <huch@in.tum.de>
parents: 80498
diff changeset
  1576
            extra_component <- task.build_config.extra_components
433475f17d73 clarified: components vs. extra components;
Fabian Huch <huch@in.tum.de>
parents: 80498
diff changeset
  1577
            target = _dir + Sync.DIRS + Path.basic(extra_component.name)
80279
02424b81472a clarified: add explicit build process;
Fabian Huch <huch@in.tum.de>
parents: 80278
diff changeset
  1578
            if Components.is_component_dir(target)
02424b81472a clarified: add explicit build process;
Fabian Huch <huch@in.tum.de>
parents: 80278
diff changeset
  1579
          } yield "init_component " + quote(target.absolute.implode)
02424b81472a clarified: add explicit build process;
Fabian Huch <huch@in.tum.de>
parents: 80278
diff changeset
  1580
02424b81472a clarified: add explicit build process;
Fabian Huch <huch@in.tum.de>
parents: 80278
diff changeset
  1581
        _isabelle.init(
80414
4b10ae56ed01 add Isabelle settings to managed tasks and ci jobs;
Fabian Huch <huch@in.tum.de>
parents: 80412
diff changeset
  1582
          other_settings = _isabelle.init_components() ::: init_components ::: task.other_settings,
80281
17d2f775907a add cluster/hosts configurations to build manager: allows running jobs in parallel on distinct hardware;
Fabian Huch <huch@in.tum.de>
parents: 80280
diff changeset
  1583
          fresh = task.build_config.fresh_build, echo = true)
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1584
80411
a9fce67fb8b2 overhauled ci_build: clarified, removed unused, removed implicit Jenkins assumptions;
Fabian Huch <huch@in.tum.de>
parents: 80410
diff changeset
  1585
        val paths = Web_Server.paths(context.store)
a9fce67fb8b2 overhauled ci_build: clarified, removed unused, removed implicit Jenkins assumptions;
Fabian Huch <huch@in.tum.de>
parents: 80410
diff changeset
  1586
        val job_url = paths.frontend_url(Web_Server.Page.BUILD, Markup.Name(context.name))
a9fce67fb8b2 overhauled ci_build: clarified, removed unused, removed implicit Jenkins assumptions;
Fabian Huch <huch@in.tum.de>
parents: 80410
diff changeset
  1587
        val cmd = task.build_config.command(job_url, task.build_hosts)
80281
17d2f775907a add cluster/hosts configurations to build manager: allows running jobs in parallel on distinct hardware;
Fabian Huch <huch@in.tum.de>
parents: 80280
diff changeset
  1588
        progress.echo("isabelle" + cmd)
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1589
80279
02424b81472a clarified: add explicit build process;
Fabian Huch <huch@in.tum.de>
parents: 80278
diff changeset
  1590
        val script = File.bash_path(Isabelle_Tool.exe(_isabelle.isabelle_home)) + cmd
02424b81472a clarified: add explicit build process;
Fabian Huch <huch@in.tum.de>
parents: 80278
diff changeset
  1591
        ssh.bash_process(_isabelle.bash_context(script), settings = false)
02424b81472a clarified: add explicit build process;
Fabian Huch <huch@in.tum.de>
parents: 80278
diff changeset
  1592
      }
02424b81472a clarified: add explicit build process;
Fabian Huch <huch@in.tum.de>
parents: 80278
diff changeset
  1593
      catch { case exn: Throwable => close(); throw exn }
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1594
80279
02424b81472a clarified: add explicit build process;
Fabian Huch <huch@in.tum.de>
parents: 80278
diff changeset
  1595
    def cancel(): Unit = Option(_process).foreach(_.interrupt())
80645
a1dce0cc6c26 build_manager: terminate processes if cancelling does not work;
Fabian Huch <huch@in.tum.de>
parents: 80644
diff changeset
  1596
    def terminate(): Unit = Option(_process).foreach(_.terminate())
80279
02424b81472a clarified: add explicit build process;
Fabian Huch <huch@in.tum.de>
parents: 80278
diff changeset
  1597
02424b81472a clarified: add explicit build process;
Fabian Huch <huch@in.tum.de>
parents: 80278
diff changeset
  1598
    def close(): Unit = {
02424b81472a clarified: add explicit build process;
Fabian Huch <huch@in.tum.de>
parents: 80278
diff changeset
  1599
      Option(_dir).foreach(ssh.rm_tree)
80280
7987b33fb6c5 clarified context: operations now in build process;
Fabian Huch <huch@in.tum.de>
parents: 80279
diff changeset
  1600
      Isabelle_System.rm_tree(context.task_dir)
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1601
      ssh.close()
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1602
    }
80281
17d2f775907a add cluster/hosts configurations to build manager: allows running jobs in parallel on distinct hardware;
Fabian Huch <huch@in.tum.de>
parents: 80280
diff changeset
  1603
17d2f775907a add cluster/hosts configurations to build manager: allows running jobs in parallel on distinct hardware;
Fabian Huch <huch@in.tum.de>
parents: 80280
diff changeset
  1604
17d2f775907a add cluster/hosts configurations to build manager: allows running jobs in parallel on distinct hardware;
Fabian Huch <huch@in.tum.de>
parents: 80280
diff changeset
  1605
    /* execution */
17d2f775907a add cluster/hosts configurations to build manager: allows running jobs in parallel on distinct hardware;
Fabian Huch <huch@in.tum.de>
parents: 80280
diff changeset
  1606
17d2f775907a add cluster/hosts configurations to build manager: allows running jobs in parallel on distinct hardware;
Fabian Huch <huch@in.tum.de>
parents: 80280
diff changeset
  1607
    def run(): Process_Result = {
17d2f775907a add cluster/hosts configurations to build manager: allows running jobs in parallel on distinct hardware;
Fabian Huch <huch@in.tum.de>
parents: 80280
diff changeset
  1608
      val process_result =
17d2f775907a add cluster/hosts configurations to build manager: allows running jobs in parallel on distinct hardware;
Fabian Huch <huch@in.tum.de>
parents: 80280
diff changeset
  1609
        _process.result(progress_stdout = progress.echo(_), progress_stderr = progress.echo(_))
17d2f775907a add cluster/hosts configurations to build manager: allows running jobs in parallel on distinct hardware;
Fabian Huch <huch@in.tum.de>
parents: 80280
diff changeset
  1610
      close()
17d2f775907a add cluster/hosts configurations to build manager: allows running jobs in parallel on distinct hardware;
Fabian Huch <huch@in.tum.de>
parents: 80280
diff changeset
  1611
      process_result
17d2f775907a add cluster/hosts configurations to build manager: allows running jobs in parallel on distinct hardware;
Fabian Huch <huch@in.tum.de>
parents: 80280
diff changeset
  1612
    }
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1613
  }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1614
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1615
80344
f05a71fa1a3f tuned comments;
Fabian Huch <huch@in.tum.de>
parents: 80343
diff changeset
  1616
  /** build manager store **/
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1617
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1618
  case class Store(options: Options) {
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1619
    val base_dir = Path.explode(options.string("build_manager_dir"))
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1620
    val identifier = options.string("build_manager_identifier")
80348
3b4f9e8b46cb clarified web server paths;
Fabian Huch <huch@in.tum.de>
parents: 80346
diff changeset
  1621
    val address = Url(options.string("build_manager_address"))
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1622
80336
e070eca8c731 clarified;
Fabian Huch <huch@in.tum.de>
parents: 80335
diff changeset
  1623
    val pending = base_dir + Path.basic("pending")
e070eca8c731 clarified;
Fabian Huch <huch@in.tum.de>
parents: 80335
diff changeset
  1624
    val finished = base_dir + Path.basic("finished")
80252
96543177ab7e build manager: manage directories/permissions, to minimize local administration;
Fabian Huch <huch@in.tum.de>
parents: 80251
diff changeset
  1625
80337
02f8a35ed8e2 clarified names: more canonical;
Fabian Huch <huch@in.tum.de>
parents: 80336
diff changeset
  1626
    def task_dir(task: Task) = pending + Path.basic(task.uuid.toString)
80497
bd00bdf39c86 clarified build report;
Fabian Huch <huch@in.tum.de>
parents: 80470
diff changeset
  1627
    def report(kind: String, id: Long): Report =
bd00bdf39c86 clarified build report;
Fabian Huch <huch@in.tum.de>
parents: 80470
diff changeset
  1628
      Report(kind, id, finished + Path.make(List(kind, id.toString)))
80252
96543177ab7e build manager: manage directories/permissions, to minimize local administration;
Fabian Huch <huch@in.tum.de>
parents: 80251
diff changeset
  1629
96543177ab7e build manager: manage directories/permissions, to minimize local administration;
Fabian Huch <huch@in.tum.de>
parents: 80251
diff changeset
  1630
    def sync_permissions(dir: Path, ssh: SSH.System = SSH.Local): Unit = {
96543177ab7e build manager: manage directories/permissions, to minimize local administration;
Fabian Huch <huch@in.tum.de>
parents: 80251
diff changeset
  1631
      ssh.execute("chmod -R g+rwx " + File.bash_path(dir))
96543177ab7e build manager: manage directories/permissions, to minimize local administration;
Fabian Huch <huch@in.tum.de>
parents: 80251
diff changeset
  1632
      ssh.execute("chown -R :" + ssh_group + " " + File.bash_path(dir))
96543177ab7e build manager: manage directories/permissions, to minimize local administration;
Fabian Huch <huch@in.tum.de>
parents: 80251
diff changeset
  1633
    }
96543177ab7e build manager: manage directories/permissions, to minimize local administration;
Fabian Huch <huch@in.tum.de>
parents: 80251
diff changeset
  1634
96543177ab7e build manager: manage directories/permissions, to minimize local administration;
Fabian Huch <huch@in.tum.de>
parents: 80251
diff changeset
  1635
    def init_dirs(): Unit =
80280
7987b33fb6c5 clarified context: operations now in build process;
Fabian Huch <huch@in.tum.de>
parents: 80279
diff changeset
  1636
      List(pending, finished).foreach(dir => sync_permissions(Isabelle_System.make_directory(dir)))
80252
96543177ab7e build manager: manage directories/permissions, to minimize local administration;
Fabian Huch <huch@in.tum.de>
parents: 80251
diff changeset
  1637
80271
198fc882ec0f tuned whitespace;
wenzelm
parents: 80270
diff changeset
  1638
    val ssh_group: String = options.string("build_manager_ssh_group")
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1639
82040
0dc7b3253aaa clarified options: extra ssh connection to cluster of build_manager;
Fabian Huch <huch@in.tum.de>
parents: 82039
diff changeset
  1640
    def open_cluster_ssh(): SSH.Session =
0dc7b3253aaa clarified options: extra ssh connection to cluster of build_manager;
Fabian Huch <huch@in.tum.de>
parents: 82039
diff changeset
  1641
      SSH.open_session(options,
0dc7b3253aaa clarified options: extra ssh connection to cluster of build_manager;
Fabian Huch <huch@in.tum.de>
parents: 82039
diff changeset
  1642
        host = options.string("build_manager_cluster_ssh_host"),
0dc7b3253aaa clarified options: extra ssh connection to cluster of build_manager;
Fabian Huch <huch@in.tum.de>
parents: 82039
diff changeset
  1643
        port = options.int("build_manager_cluster_ssh_port"),
0dc7b3253aaa clarified options: extra ssh connection to cluster of build_manager;
Fabian Huch <huch@in.tum.de>
parents: 82039
diff changeset
  1644
        user = options.string("build_manager_cluster_ssh_user"))
0dc7b3253aaa clarified options: extra ssh connection to cluster of build_manager;
Fabian Huch <huch@in.tum.de>
parents: 82039
diff changeset
  1645
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1646
    def open_ssh(): SSH.Session =
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1647
      SSH.open_session(options,
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1648
        host = options.string("build_manager_ssh_host"),
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1649
        port = options.int("build_manager_ssh_port"),
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1650
        user = options.string("build_manager_ssh_user"))
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1651
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1652
    def open_database(server: SSH.Server = SSH.no_server): PostgreSQL.Database =
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1653
      PostgreSQL.open_database_server(options, server = server,
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1654
        user = options.string("build_manager_database_user"),
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1655
        password = options.string("build_manager_database_password"),
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1656
        database = options.string("build_manager_database_name"),
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1657
        host = options.string("build_manager_database_host"),
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1658
        port = options.int("build_manager_database_port"),
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1659
        ssh_host = options.string("build_manager_database_ssh_host"),
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1660
        ssh_port = options.int("build_manager_database_ssh_port"),
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1661
        ssh_user = options.string("build_manager_database_ssh_user"))
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1662
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1663
    def open_postgresql_server(): SSH.Server =
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1664
      PostgreSQL.open_server(options,
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1665
        host = options.string("build_manager_database_host"),
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1666
        port = options.int("build_manager_database_port"),
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1667
        ssh_host = options.string("build_manager_ssh_host"),
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1668
        ssh_port = options.int("build_manager_ssh_port"),
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1669
        ssh_user = options.string("build_manager_ssh_user"))
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1670
  }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1671
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1672
80344
f05a71fa1a3f tuned comments;
Fabian Huch <huch@in.tum.de>
parents: 80343
diff changeset
  1673
  /** build manager server **/
f05a71fa1a3f tuned comments;
Fabian Huch <huch@in.tum.de>
parents: 80343
diff changeset
  1674
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1675
  /* build manager */
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1676
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1677
  def build_manager(
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1678
    build_hosts: List[Build_Cluster.Host],
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1679
    options: Options,
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1680
    port: Int,
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1681
    sync_dirs: List[Sync.Dir] = Nil,
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1682
    progress: Progress = new Progress
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1683
  ): Unit = {
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1684
    val store = Store(options)
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1685
    val isabelle_repository = Mercurial.self_repository()
80412
a7f8249533e9 moved ci_build module to build_ci;
Fabian Huch <huch@in.tum.de>
parents: 80411
diff changeset
  1686
    val ci_jobs = space_explode(',', options.string("build_manager_ci_jobs")).map(Build_CI.the_job)
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1687
80349
2503ff5d29ce tuned messages;
Fabian Huch <huch@in.tum.de>
parents: 80348
diff changeset
  1688
    progress.echo_if(ci_jobs.nonEmpty, "Managing ci jobs: " + commas_quote(ci_jobs.map(_.name)))
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1689
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1690
    using(store.open_database())(db =>
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1691
      Build_Manager.private_data.transaction_lock(db,
80252
96543177ab7e build manager: manage directories/permissions, to minimize local administration;
Fabian Huch <huch@in.tum.de>
parents: 80251
diff changeset
  1692
        create = true, label = "Build_Manager.build_manager") { store.init_dirs() })
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1693
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1694
    val processes = List(
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1695
      new Runner(store, build_hosts, isabelle_repository, sync_dirs, progress),
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1696
      new Poller(ci_jobs, store, isabelle_repository, sync_dirs, progress),
80647
3519f026e7d6 tuned and clarified;
Fabian Huch <huch@in.tum.de>
parents: 80646
diff changeset
  1697
      new Timer(ci_jobs, store, progress),
80649
f5ae78dd49d1 build_manager: display more info;
Fabian Huch <huch@in.tum.de>
parents: 80647
diff changeset
  1698
      new Web_Server(port, store, build_hosts, progress))
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1699
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1700
    val threads = processes.map(Isabelle_Thread.create(_))
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1701
    POSIX_Interrupt.handler {
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1702
      progress.stop()
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1703
      processes.foreach(_.interrupt())
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1704
    } {
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1705
      threads.foreach(_.start())
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1706
      threads.foreach(_.join())
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1707
    }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1708
  }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1709
80334
Fabian Huch <huch@in.tum.de>
parents: 80320
diff changeset
  1710
Fabian Huch <huch@in.tum.de>
parents: 80320
diff changeset
  1711
  /* Isabelle tool wrapper */
Fabian Huch <huch@in.tum.de>
parents: 80320
diff changeset
  1712
Fabian Huch <huch@in.tum.de>
parents: 80320
diff changeset
  1713
  val isabelle_tool = Isabelle_Tool("build_manager", "run build manager", Scala_Project.here,
Fabian Huch <huch@in.tum.de>
parents: 80320
diff changeset
  1714
    { args =>
Fabian Huch <huch@in.tum.de>
parents: 80320
diff changeset
  1715
      var afp_root: Option[Path] = None
Fabian Huch <huch@in.tum.de>
parents: 80320
diff changeset
  1716
      val dirs = new mutable.ListBuffer[Path]
Fabian Huch <huch@in.tum.de>
parents: 80320
diff changeset
  1717
      val build_hosts = new mutable.ListBuffer[Build_Cluster.Host]
Fabian Huch <huch@in.tum.de>
parents: 80320
diff changeset
  1718
      var options = Options.init()
82038
42fe486d38d5 tuned: more standard;
Fabian Huch <huch@in.tum.de>
parents: 81882
diff changeset
  1719
      var port = 0
80334
Fabian Huch <huch@in.tum.de>
parents: 80320
diff changeset
  1720
Fabian Huch <huch@in.tum.de>
parents: 80320
diff changeset
  1721
      val getopts = Getopts("""
Fabian Huch <huch@in.tum.de>
parents: 80320
diff changeset
  1722
Usage: isabelle build_manager [OPTIONS]
Fabian Huch <huch@in.tum.de>
parents: 80320
diff changeset
  1723
Fabian Huch <huch@in.tum.de>
parents: 80320
diff changeset
  1724
  Options are:
Fabian Huch <huch@in.tum.de>
parents: 80320
diff changeset
  1725
    -A ROOT      include AFP with given root directory (":" for """ + AFP.BASE.implode + """)
Fabian Huch <huch@in.tum.de>
parents: 80320
diff changeset
  1726
    -D DIR       include extra component in given directory
Fabian Huch <huch@in.tum.de>
parents: 80320
diff changeset
  1727
    -H HOSTS     host specifications for all available hosts of the form
Fabian Huch <huch@in.tum.de>
parents: 80320
diff changeset
  1728
                 NAMES:PARAMETERS (separated by commas)
Fabian Huch <huch@in.tum.de>
parents: 80320
diff changeset
  1729
    -o OPTION    override Isabelle system OPTION (via NAME=VAL or NAME)
Fabian Huch <huch@in.tum.de>
parents: 80320
diff changeset
  1730
    -p PORT      explicit web server port
Fabian Huch <huch@in.tum.de>
parents: 80320
diff changeset
  1731
82039
e0ba5e9850df tuned output;
Fabian Huch <huch@in.tum.de>
parents: 82038
diff changeset
  1732
  Run Isabelle build manager.
e0ba5e9850df tuned output;
Fabian Huch <huch@in.tum.de>
parents: 82038
diff changeset
  1733
""",
80334
Fabian Huch <huch@in.tum.de>
parents: 80320
diff changeset
  1734
        "A:" -> (arg => afp_root = Some(if (arg == ":") AFP.BASE else Path.explode(arg))),
Fabian Huch <huch@in.tum.de>
parents: 80320
diff changeset
  1735
        "D:" -> (arg => dirs += Path.explode(arg)),
Fabian Huch <huch@in.tum.de>
parents: 80320
diff changeset
  1736
        "H:" -> (arg => build_hosts ++= Build_Cluster.Host.parse(Registry.global, arg)),
Fabian Huch <huch@in.tum.de>
parents: 80320
diff changeset
  1737
        "o:" -> (arg => options = options + arg),
Fabian Huch <huch@in.tum.de>
parents: 80320
diff changeset
  1738
        "p:" -> (arg => port = Value.Int.parse(arg)))
Fabian Huch <huch@in.tum.de>
parents: 80320
diff changeset
  1739
Fabian Huch <huch@in.tum.de>
parents: 80320
diff changeset
  1740
      val more_args = getopts(args)
Fabian Huch <huch@in.tum.de>
parents: 80320
diff changeset
  1741
      if (more_args.nonEmpty) getopts.usage()
Fabian Huch <huch@in.tum.de>
parents: 80320
diff changeset
  1742
Fabian Huch <huch@in.tum.de>
parents: 80320
diff changeset
  1743
      val progress = new Console_Progress()
Fabian Huch <huch@in.tum.de>
parents: 80320
diff changeset
  1744
      val sync_dirs =
Fabian Huch <huch@in.tum.de>
parents: 80320
diff changeset
  1745
        Sync.afp_dirs(afp_root) ::: dirs.toList.map(dir => Sync.Dir(dir.file_name, dir))
Fabian Huch <huch@in.tum.de>
parents: 80320
diff changeset
  1746
Fabian Huch <huch@in.tum.de>
parents: 80320
diff changeset
  1747
      sync_dirs.foreach(_.check())
Fabian Huch <huch@in.tum.de>
parents: 80320
diff changeset
  1748
Fabian Huch <huch@in.tum.de>
parents: 80320
diff changeset
  1749
      build_manager(build_hosts = build_hosts.toList, options = options, port = port,
Fabian Huch <huch@in.tum.de>
parents: 80320
diff changeset
  1750
        sync_dirs = sync_dirs, progress = progress)
Fabian Huch <huch@in.tum.de>
parents: 80320
diff changeset
  1751
    })
Fabian Huch <huch@in.tum.de>
parents: 80320
diff changeset
  1752
Fabian Huch <huch@in.tum.de>
parents: 80320
diff changeset
  1753
80344
f05a71fa1a3f tuned comments;
Fabian Huch <huch@in.tum.de>
parents: 80343
diff changeset
  1754
  /** restore build manager database **/
80343
595b362ab851 add build_manager_database tool to restore db from log files;
Fabian Huch <huch@in.tum.de>
parents: 80342
diff changeset
  1755
80545
17786f08b93e allow updating reports via build_manager_database tool, e.g. to generate hg logs/diffs;
Fabian Huch <huch@in.tum.de>
parents: 80544
diff changeset
  1756
  def build_manager_database(
17786f08b93e allow updating reports via build_manager_database tool, e.g. to generate hg logs/diffs;
Fabian Huch <huch@in.tum.de>
parents: 80544
diff changeset
  1757
    options: Options,
17786f08b93e allow updating reports via build_manager_database tool, e.g. to generate hg logs/diffs;
Fabian Huch <huch@in.tum.de>
parents: 80544
diff changeset
  1758
    sync_dirs: List[Sync.Dir] = Sync.afp_dirs(),
17786f08b93e allow updating reports via build_manager_database tool, e.g. to generate hg logs/diffs;
Fabian Huch <huch@in.tum.de>
parents: 80544
diff changeset
  1759
    update_reports: Boolean = false,
17786f08b93e allow updating reports via build_manager_database tool, e.g. to generate hg logs/diffs;
Fabian Huch <huch@in.tum.de>
parents: 80544
diff changeset
  1760
    progress: Progress = new Progress
17786f08b93e allow updating reports via build_manager_database tool, e.g. to generate hg logs/diffs;
Fabian Huch <huch@in.tum.de>
parents: 80544
diff changeset
  1761
  ): Unit = {
80343
595b362ab851 add build_manager_database tool to restore db from log files;
Fabian Huch <huch@in.tum.de>
parents: 80342
diff changeset
  1762
    val store = Store(options)
595b362ab851 add build_manager_database tool to restore db from log files;
Fabian Huch <huch@in.tum.de>
parents: 80342
diff changeset
  1763
    using(store.open_database()) { db =>
595b362ab851 add build_manager_database tool to restore db from log files;
Fabian Huch <huch@in.tum.de>
parents: 80342
diff changeset
  1764
      db.transaction {
595b362ab851 add build_manager_database tool to restore db from log files;
Fabian Huch <huch@in.tum.de>
parents: 80342
diff changeset
  1765
        val tables0 = Build_Manager.private_data.tables.list
595b362ab851 add build_manager_database tool to restore db from log files;
Fabian Huch <huch@in.tum.de>
parents: 80342
diff changeset
  1766
        val tables = tables0.filter(t => db.exists_table(t.name))
595b362ab851 add build_manager_database tool to restore db from log files;
Fabian Huch <huch@in.tum.de>
parents: 80342
diff changeset
  1767
        if (tables.nonEmpty) {
595b362ab851 add build_manager_database tool to restore db from log files;
Fabian Huch <huch@in.tum.de>
parents: 80342
diff changeset
  1768
          progress.echo("Removing tables " + commas_quote(tables.map(_.name)) + " ...")
595b362ab851 add build_manager_database tool to restore db from log files;
Fabian Huch <huch@in.tum.de>
parents: 80342
diff changeset
  1769
          db.execute_statement(SQL.MULTI(tables.map(db.destroy)))
595b362ab851 add build_manager_database tool to restore db from log files;
Fabian Huch <huch@in.tum.de>
parents: 80342
diff changeset
  1770
        }
595b362ab851 add build_manager_database tool to restore db from log files;
Fabian Huch <huch@in.tum.de>
parents: 80342
diff changeset
  1771
      }
595b362ab851 add build_manager_database tool to restore db from log files;
Fabian Huch <huch@in.tum.de>
parents: 80342
diff changeset
  1772
80545
17786f08b93e allow updating reports via build_manager_database tool, e.g. to generate hg logs/diffs;
Fabian Huch <huch@in.tum.de>
parents: 80544
diff changeset
  1773
      val reports =
80343
595b362ab851 add build_manager_database tool to restore db from log files;
Fabian Huch <huch@in.tum.de>
parents: 80342
diff changeset
  1774
        for {
595b362ab851 add build_manager_database tool to restore db from log files;
Fabian Huch <huch@in.tum.de>
parents: 80342
diff changeset
  1775
          kind <- File.read_dir(store.finished)
595b362ab851 add build_manager_database tool to restore db from log files;
Fabian Huch <huch@in.tum.de>
parents: 80342
diff changeset
  1776
          entry <- File.read_dir(store.finished + Path.basic(kind))
595b362ab851 add build_manager_database tool to restore db from log files;
Fabian Huch <huch@in.tum.de>
parents: 80342
diff changeset
  1777
          id <- Value.Long.unapply(entry)
80497
bd00bdf39c86 clarified build report;
Fabian Huch <huch@in.tum.de>
parents: 80470
diff changeset
  1778
          report = store.report(kind, id)
bd00bdf39c86 clarified build report;
Fabian Huch <huch@in.tum.de>
parents: 80470
diff changeset
  1779
          if report.ok
80545
17786f08b93e allow updating reports via build_manager_database tool, e.g. to generate hg logs/diffs;
Fabian Huch <huch@in.tum.de>
parents: 80544
diff changeset
  1780
        } yield report
17786f08b93e allow updating reports via build_manager_database tool, e.g. to generate hg logs/diffs;
Fabian Huch <huch@in.tum.de>
parents: 80544
diff changeset
  1781
80646
b4e116523cb6 build_manager: store submitting user;
Fabian Huch <huch@in.tum.de>
parents: 80645
diff changeset
  1782
      val results = reports.map(report => report -> report.result())
80545
17786f08b93e allow updating reports via build_manager_database tool, e.g. to generate hg logs/diffs;
Fabian Huch <huch@in.tum.de>
parents: 80544
diff changeset
  1783
17786f08b93e allow updating reports via build_manager_database tool, e.g. to generate hg logs/diffs;
Fabian Huch <huch@in.tum.de>
parents: 80544
diff changeset
  1784
      if (update_reports) {
17786f08b93e allow updating reports via build_manager_database tool, e.g. to generate hg logs/diffs;
Fabian Huch <huch@in.tum.de>
parents: 80544
diff changeset
  1785
        val isabelle_repository = Mercurial.self_repository()
17786f08b93e allow updating reports via build_manager_database tool, e.g. to generate hg logs/diffs;
Fabian Huch <huch@in.tum.de>
parents: 80544
diff changeset
  1786
        val afp_repository =
17786f08b93e allow updating reports via build_manager_database tool, e.g. to generate hg logs/diffs;
Fabian Huch <huch@in.tum.de>
parents: 80544
diff changeset
  1787
          sync_dirs.find(_.name == Component.AFP).getOrElse(error("Missing AFP for udpate")).hg
17786f08b93e allow updating reports via build_manager_database tool, e.g. to generate hg logs/diffs;
Fabian Huch <huch@in.tum.de>
parents: 80544
diff changeset
  1788
17786f08b93e allow updating reports via build_manager_database tool, e.g. to generate hg logs/diffs;
Fabian Huch <huch@in.tum.de>
parents: 80544
diff changeset
  1789
        isabelle_repository.pull()
17786f08b93e allow updating reports via build_manager_database tool, e.g. to generate hg logs/diffs;
Fabian Huch <huch@in.tum.de>
parents: 80544
diff changeset
  1790
        afp_repository.pull()
80343
595b362ab851 add build_manager_database tool to restore db from log files;
Fabian Huch <huch@in.tum.de>
parents: 80342
diff changeset
  1791
80545
17786f08b93e allow updating reports via build_manager_database tool, e.g. to generate hg logs/diffs;
Fabian Huch <huch@in.tum.de>
parents: 80544
diff changeset
  1792
        for ((kind, results0) <- results.groupBy(_._1.kind) if kind != User_Build.name) {
17786f08b93e allow updating reports via build_manager_database tool, e.g. to generate hg logs/diffs;
Fabian Huch <huch@in.tum.de>
parents: 80544
diff changeset
  1793
          val results1 = results0.sortBy(_._1.id)
17786f08b93e allow updating reports via build_manager_database tool, e.g. to generate hg logs/diffs;
Fabian Huch <huch@in.tum.de>
parents: 80544
diff changeset
  1794
          results1.foldLeft(("", "")) {
17786f08b93e allow updating reports via build_manager_database tool, e.g. to generate hg logs/diffs;
Fabian Huch <huch@in.tum.de>
parents: 80544
diff changeset
  1795
            case ((isabelle_rev0, afp_rev0), (report, result)) =>
17786f08b93e allow updating reports via build_manager_database tool, e.g. to generate hg logs/diffs;
Fabian Huch <huch@in.tum.de>
parents: 80544
diff changeset
  1796
              val isabelle_rev = result.isabelle_version.getOrElse("")
17786f08b93e allow updating reports via build_manager_database tool, e.g. to generate hg logs/diffs;
Fabian Huch <huch@in.tum.de>
parents: 80544
diff changeset
  1797
              val afp_rev = result.afp_version.getOrElse("")
17786f08b93e allow updating reports via build_manager_database tool, e.g. to generate hg logs/diffs;
Fabian Huch <huch@in.tum.de>
parents: 80544
diff changeset
  1798
17786f08b93e allow updating reports via build_manager_database tool, e.g. to generate hg logs/diffs;
Fabian Huch <huch@in.tum.de>
parents: 80544
diff changeset
  1799
              report.write_log(Component.Isabelle, isabelle_repository, isabelle_rev0, isabelle_rev)
17786f08b93e allow updating reports via build_manager_database tool, e.g. to generate hg logs/diffs;
Fabian Huch <huch@in.tum.de>
parents: 80544
diff changeset
  1800
              report.write_log(Component.AFP, afp_repository, afp_rev0, afp_rev)
17786f08b93e allow updating reports via build_manager_database tool, e.g. to generate hg logs/diffs;
Fabian Huch <huch@in.tum.de>
parents: 80544
diff changeset
  1801
              report.write_diff(
17786f08b93e allow updating reports via build_manager_database tool, e.g. to generate hg logs/diffs;
Fabian Huch <huch@in.tum.de>
parents: 80544
diff changeset
  1802
                Component.Isabelle, isabelle_repository, isabelle_rev0, isabelle_rev)
17786f08b93e allow updating reports via build_manager_database tool, e.g. to generate hg logs/diffs;
Fabian Huch <huch@in.tum.de>
parents: 80544
diff changeset
  1803
              report.write_diff(Component.AFP, afp_repository, afp_rev0, afp_rev)
17786f08b93e allow updating reports via build_manager_database tool, e.g. to generate hg logs/diffs;
Fabian Huch <huch@in.tum.de>
parents: 80544
diff changeset
  1804
17786f08b93e allow updating reports via build_manager_database tool, e.g. to generate hg logs/diffs;
Fabian Huch <huch@in.tum.de>
parents: 80544
diff changeset
  1805
              (isabelle_rev, afp_rev)
17786f08b93e allow updating reports via build_manager_database tool, e.g. to generate hg logs/diffs;
Fabian Huch <huch@in.tum.de>
parents: 80544
diff changeset
  1806
          }
17786f08b93e allow updating reports via build_manager_database tool, e.g. to generate hg logs/diffs;
Fabian Huch <huch@in.tum.de>
parents: 80544
diff changeset
  1807
        }
17786f08b93e allow updating reports via build_manager_database tool, e.g. to generate hg logs/diffs;
Fabian Huch <huch@in.tum.de>
parents: 80544
diff changeset
  1808
      }
17786f08b93e allow updating reports via build_manager_database tool, e.g. to generate hg logs/diffs;
Fabian Huch <huch@in.tum.de>
parents: 80544
diff changeset
  1809
17786f08b93e allow updating reports via build_manager_database tool, e.g. to generate hg logs/diffs;
Fabian Huch <huch@in.tum.de>
parents: 80544
diff changeset
  1810
      val state = State(finished = results.map((_, result) => result.name -> result).toMap)
80343
595b362ab851 add build_manager_database tool to restore db from log files;
Fabian Huch <huch@in.tum.de>
parents: 80342
diff changeset
  1811
595b362ab851 add build_manager_database tool to restore db from log files;
Fabian Huch <huch@in.tum.de>
parents: 80342
diff changeset
  1812
      Build_Manager.private_data.transaction_lock(db,
595b362ab851 add build_manager_database tool to restore db from log files;
Fabian Huch <huch@in.tum.de>
parents: 80342
diff changeset
  1813
        create = true, label = "Build_Manager.build_manager_database") {
595b362ab851 add build_manager_database tool to restore db from log files;
Fabian Huch <huch@in.tum.de>
parents: 80342
diff changeset
  1814
595b362ab851 add build_manager_database tool to restore db from log files;
Fabian Huch <huch@in.tum.de>
parents: 80342
diff changeset
  1815
        progress.echo("Writing " + results.length + " results ...")
595b362ab851 add build_manager_database tool to restore db from log files;
Fabian Huch <huch@in.tum.de>
parents: 80342
diff changeset
  1816
        Build_Manager.private_data.push_state(db, State(), state)
595b362ab851 add build_manager_database tool to restore db from log files;
Fabian Huch <huch@in.tum.de>
parents: 80342
diff changeset
  1817
      }
595b362ab851 add build_manager_database tool to restore db from log files;
Fabian Huch <huch@in.tum.de>
parents: 80342
diff changeset
  1818
    }
595b362ab851 add build_manager_database tool to restore db from log files;
Fabian Huch <huch@in.tum.de>
parents: 80342
diff changeset
  1819
  }
595b362ab851 add build_manager_database tool to restore db from log files;
Fabian Huch <huch@in.tum.de>
parents: 80342
diff changeset
  1820
595b362ab851 add build_manager_database tool to restore db from log files;
Fabian Huch <huch@in.tum.de>
parents: 80342
diff changeset
  1821
595b362ab851 add build_manager_database tool to restore db from log files;
Fabian Huch <huch@in.tum.de>
parents: 80342
diff changeset
  1822
  /* Isabelle tool wrapper */
595b362ab851 add build_manager_database tool to restore db from log files;
Fabian Huch <huch@in.tum.de>
parents: 80342
diff changeset
  1823
595b362ab851 add build_manager_database tool to restore db from log files;
Fabian Huch <huch@in.tum.de>
parents: 80342
diff changeset
  1824
  val isabelle_tool1 = Isabelle_Tool("build_manager_database",
595b362ab851 add build_manager_database tool to restore db from log files;
Fabian Huch <huch@in.tum.de>
parents: 80342
diff changeset
  1825
    "restore build_manager database from log files",
595b362ab851 add build_manager_database tool to restore db from log files;
Fabian Huch <huch@in.tum.de>
parents: 80342
diff changeset
  1826
    Scala_Project.here,
595b362ab851 add build_manager_database tool to restore db from log files;
Fabian Huch <huch@in.tum.de>
parents: 80342
diff changeset
  1827
    { args =>
80545
17786f08b93e allow updating reports via build_manager_database tool, e.g. to generate hg logs/diffs;
Fabian Huch <huch@in.tum.de>
parents: 80544
diff changeset
  1828
      var afp_root: Option[Path] = None
80343
595b362ab851 add build_manager_database tool to restore db from log files;
Fabian Huch <huch@in.tum.de>
parents: 80342
diff changeset
  1829
      var options = Options.init()
80545
17786f08b93e allow updating reports via build_manager_database tool, e.g. to generate hg logs/diffs;
Fabian Huch <huch@in.tum.de>
parents: 80544
diff changeset
  1830
      var update_reports = false
80343
595b362ab851 add build_manager_database tool to restore db from log files;
Fabian Huch <huch@in.tum.de>
parents: 80342
diff changeset
  1831
595b362ab851 add build_manager_database tool to restore db from log files;
Fabian Huch <huch@in.tum.de>
parents: 80342
diff changeset
  1832
      val getopts = Getopts("""
595b362ab851 add build_manager_database tool to restore db from log files;
Fabian Huch <huch@in.tum.de>
parents: 80342
diff changeset
  1833
Usage: isabelle build_manager_database [OPTIONS]
595b362ab851 add build_manager_database tool to restore db from log files;
Fabian Huch <huch@in.tum.de>
parents: 80342
diff changeset
  1834
595b362ab851 add build_manager_database tool to restore db from log files;
Fabian Huch <huch@in.tum.de>
parents: 80342
diff changeset
  1835
  Options are:
80545
17786f08b93e allow updating reports via build_manager_database tool, e.g. to generate hg logs/diffs;
Fabian Huch <huch@in.tum.de>
parents: 80544
diff changeset
  1836
    -A ROOT      include AFP with given root directory (":" for """ + AFP.BASE.implode + """)
80343
595b362ab851 add build_manager_database tool to restore db from log files;
Fabian Huch <huch@in.tum.de>
parents: 80342
diff changeset
  1837
    -o OPTION    override Isabelle system OPTION (via NAME=VAL or NAME)
80545
17786f08b93e allow updating reports via build_manager_database tool, e.g. to generate hg logs/diffs;
Fabian Huch <huch@in.tum.de>
parents: 80544
diff changeset
  1838
    -u           update reports
80343
595b362ab851 add build_manager_database tool to restore db from log files;
Fabian Huch <huch@in.tum.de>
parents: 80342
diff changeset
  1839
595b362ab851 add build_manager_database tool to restore db from log files;
Fabian Huch <huch@in.tum.de>
parents: 80342
diff changeset
  1840
  Restore build_manager database from log files.
595b362ab851 add build_manager_database tool to restore db from log files;
Fabian Huch <huch@in.tum.de>
parents: 80342
diff changeset
  1841
""",
80545
17786f08b93e allow updating reports via build_manager_database tool, e.g. to generate hg logs/diffs;
Fabian Huch <huch@in.tum.de>
parents: 80544
diff changeset
  1842
        "A:" -> (arg => afp_root = Some(if (arg == ":") AFP.BASE else Path.explode(arg))),
17786f08b93e allow updating reports via build_manager_database tool, e.g. to generate hg logs/diffs;
Fabian Huch <huch@in.tum.de>
parents: 80544
diff changeset
  1843
        "o:" -> (arg => options = options + arg),
17786f08b93e allow updating reports via build_manager_database tool, e.g. to generate hg logs/diffs;
Fabian Huch <huch@in.tum.de>
parents: 80544
diff changeset
  1844
        "u" -> (_ => update_reports = true))
80343
595b362ab851 add build_manager_database tool to restore db from log files;
Fabian Huch <huch@in.tum.de>
parents: 80342
diff changeset
  1845
595b362ab851 add build_manager_database tool to restore db from log files;
Fabian Huch <huch@in.tum.de>
parents: 80342
diff changeset
  1846
      val more_args = getopts(args)
595b362ab851 add build_manager_database tool to restore db from log files;
Fabian Huch <huch@in.tum.de>
parents: 80342
diff changeset
  1847
      if (more_args.nonEmpty) getopts.usage()
595b362ab851 add build_manager_database tool to restore db from log files;
Fabian Huch <huch@in.tum.de>
parents: 80342
diff changeset
  1848
595b362ab851 add build_manager_database tool to restore db from log files;
Fabian Huch <huch@in.tum.de>
parents: 80342
diff changeset
  1849
      val progress = new Console_Progress()
595b362ab851 add build_manager_database tool to restore db from log files;
Fabian Huch <huch@in.tum.de>
parents: 80342
diff changeset
  1850
80545
17786f08b93e allow updating reports via build_manager_database tool, e.g. to generate hg logs/diffs;
Fabian Huch <huch@in.tum.de>
parents: 80544
diff changeset
  1851
      build_manager_database(options, sync_dirs = Sync.afp_dirs(afp_root),
17786f08b93e allow updating reports via build_manager_database tool, e.g. to generate hg logs/diffs;
Fabian Huch <huch@in.tum.de>
parents: 80544
diff changeset
  1852
        update_reports = update_reports, progress = progress)
80343
595b362ab851 add build_manager_database tool to restore db from log files;
Fabian Huch <huch@in.tum.de>
parents: 80342
diff changeset
  1853
    })
595b362ab851 add build_manager_database tool to restore db from log files;
Fabian Huch <huch@in.tum.de>
parents: 80342
diff changeset
  1854
595b362ab851 add build_manager_database tool to restore db from log files;
Fabian Huch <huch@in.tum.de>
parents: 80342
diff changeset
  1855
80344
f05a71fa1a3f tuned comments;
Fabian Huch <huch@in.tum.de>
parents: 80343
diff changeset
  1856
  /** build manager client */
f05a71fa1a3f tuned comments;
Fabian Huch <huch@in.tum.de>
parents: 80343
diff changeset
  1857
80334
Fabian Huch <huch@in.tum.de>
parents: 80320
diff changeset
  1858
  /* build task */
Fabian Huch <huch@in.tum.de>
parents: 80320
diff changeset
  1859
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1860
  def build_task(
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1861
    options: Options,
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1862
    store: Store,
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1863
    afp_root: Option[Path] = None,
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1864
    base_sessions: List[String] = Nil,
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1865
    presentation: Boolean = false,
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1866
    requirements: Boolean = false,
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1867
    exclude_session_groups: List[String] = Nil,
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1868
    all_sessions: Boolean = false,
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1869
    build_heap: Boolean = false,
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1870
    clean_build: Boolean = false,
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1871
    export_files: Boolean = false,
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1872
    fresh_build: Boolean = false,
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1873
    session_groups: List[String] = Nil,
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1874
    sessions: List[String] = Nil,
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1875
    prefs: List[Options.Spec] = Nil,
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1876
    exclude_sessions: List[String] = Nil,
80254
6b3374d208b8 add verbose option to build_task;
Fabian Huch <huch@in.tum.de>
parents: 80252
diff changeset
  1877
    verbose: Boolean = false,
80250
8ae6f4e8cc2a allow explicit Isabelle rev in build task (e.g., for older Isabelle versions);
Fabian Huch <huch@in.tum.de>
parents: 80246
diff changeset
  1878
    rev: String = "",
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1879
    progress: Progress = new Progress
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1880
  ): UUID.T = {
80337
02f8a35ed8e2 clarified names: more canonical;
Fabian Huch <huch@in.tum.de>
parents: 80336
diff changeset
  1881
    val uuid = UUID.random()
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1882
    val afp_rev = if (afp_root.nonEmpty) Some("") else None
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1883
80281
17d2f775907a add cluster/hosts configurations to build manager: allows running jobs in parallel on distinct hardware;
Fabian Huch <huch@in.tum.de>
parents: 80280
diff changeset
  1884
    val hosts_spec = options.string("build_manager_cluster")
80469
a3bae6dd7344 add timeout to build manager tasks/jobs (e.g. for cluster builds that don't terminate after error on host);
Fabian Huch <huch@in.tum.de>
parents: 80468
diff changeset
  1885
    val timeout = options.seconds("build_manager_timeout")
80348
3b4f9e8b46cb clarified web server paths;
Fabian Huch <huch@in.tum.de>
parents: 80346
diff changeset
  1886
    val paths = Web_Server.paths(store)
80338
5a6cc89c8f98 proper web server address;
Fabian Huch <huch@in.tum.de>
parents: 80337
diff changeset
  1887
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1888
    progress.interrupt_handler {
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1889
      using(store.open_ssh()) { ssh =>
80646
b4e116523cb6 build_manager: store submitting user;
Fabian Huch <huch@in.tum.de>
parents: 80645
diff changeset
  1890
        val user = ssh.execute("whoami").check.out
81881
f23fc3d21873 tuned whitespace;
Fabian Huch <huch@in.tum.de>
parents: 80782
diff changeset
  1891
80646
b4e116523cb6 build_manager: store submitting user;
Fabian Huch <huch@in.tum.de>
parents: 80645
diff changeset
  1892
        val build_config = User_Build(user, afp_rev, prefs, requirements, all_sessions,
b4e116523cb6 build_manager: store submitting user;
Fabian Huch <huch@in.tum.de>
parents: 80645
diff changeset
  1893
          base_sessions, exclude_session_groups, exclude_sessions, session_groups, sessions,
b4e116523cb6 build_manager: store submitting user;
Fabian Huch <huch@in.tum.de>
parents: 80645
diff changeset
  1894
          build_heap, clean_build, export_files, fresh_build, presentation, verbose)
b4e116523cb6 build_manager: store submitting user;
Fabian Huch <huch@in.tum.de>
parents: 80645
diff changeset
  1895
        val task = Task(build_config, hosts_spec, timeout, uuid = uuid, priority = Priority.high)
b4e116523cb6 build_manager: store submitting user;
Fabian Huch <huch@in.tum.de>
parents: 80645
diff changeset
  1896
b4e116523cb6 build_manager: store submitting user;
Fabian Huch <huch@in.tum.de>
parents: 80645
diff changeset
  1897
        val dir = store.task_dir(task)
b4e116523cb6 build_manager: store submitting user;
Fabian Huch <huch@in.tum.de>
parents: 80645
diff changeset
  1898
80252
96543177ab7e build manager: manage directories/permissions, to minimize local administration;
Fabian Huch <huch@in.tum.de>
parents: 80251
diff changeset
  1899
        val rsync_context = Rsync.Context(ssh = ssh)
80518
d3b96e19ccc7 tuned messages: whitespace following usual Isabelle conventions;
wenzelm
parents: 80502
diff changeset
  1900
        progress.echo("Transferring repositories ...")
80280
7987b33fb6c5 clarified context: operations now in build process;
Fabian Huch <huch@in.tum.de>
parents: 80279
diff changeset
  1901
        Sync.sync(store.options, rsync_context, dir, preserve_jars = true,
80250
8ae6f4e8cc2a allow explicit Isabelle rev in build task (e.g., for older Isabelle versions);
Fabian Huch <huch@in.tum.de>
parents: 80246
diff changeset
  1902
          dirs = Sync.afp_dirs(afp_root), rev = rev)
80280
7987b33fb6c5 clarified context: operations now in build process;
Fabian Huch <huch@in.tum.de>
parents: 80279
diff changeset
  1903
        store.sync_permissions(dir, ssh)
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1904
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1905
        if (progress.stopped) {
80518
d3b96e19ccc7 tuned messages: whitespace following usual Isabelle conventions;
wenzelm
parents: 80502
diff changeset
  1906
          progress.echo("Cancelling submission ...")
80280
7987b33fb6c5 clarified context: operations now in build process;
Fabian Huch <huch@in.tum.de>
parents: 80279
diff changeset
  1907
          ssh.rm_tree(dir)
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1908
        } else {
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1909
          using(store.open_postgresql_server()) { server =>
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1910
            using(store.open_database(server = server)) { db =>
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1911
              Build_Manager.private_data.transaction_lock(db, label = "Build_Manager.build_task") {
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1912
                val old_state = Build_Manager.private_data.pull_state(db, State())
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1913
                val state = old_state.add_pending(task)
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1914
                Build_Manager.private_data.push_state(db, old_state, state)
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1915
              }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1916
            }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1917
          }
80338
5a6cc89c8f98 proper web server address;
Fabian Huch <huch@in.tum.de>
parents: 80337
diff changeset
  1918
5a6cc89c8f98 proper web server address;
Fabian Huch <huch@in.tum.de>
parents: 80337
diff changeset
  1919
          val address = paths.frontend_url(Web_Server.Page.BUILD, Web_Server.Id(task.uuid.toString))
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1920
          progress.echo("Submitted task. Private url: " + address)
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1921
        }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1922
      }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1923
    }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1924
80337
02f8a35ed8e2 clarified names: more canonical;
Fabian Huch <huch@in.tum.de>
parents: 80336
diff changeset
  1925
    uuid
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1926
  }
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1927
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1928
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1929
  /* Isabelle tool wrapper */
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1930
80343
595b362ab851 add build_manager_database tool to restore db from log files;
Fabian Huch <huch@in.tum.de>
parents: 80342
diff changeset
  1931
  val isabelle_tool2 = Isabelle_Tool("build_task", "submit build task for build manager",
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1932
    Scala_Project.here,
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1933
    { args =>
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1934
      var afp_root: Option[Path] = None
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1935
      val base_sessions = new mutable.ListBuffer[String]
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1936
      var presentation = false
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1937
      var requirements = false
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1938
      val exclude_session_groups = new mutable.ListBuffer[String]
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1939
      var all_sessions = false
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1940
      var build_heap = false
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1941
      var clean_build = false
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1942
      var export_files = false
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1943
      var fresh_build = false
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1944
      val session_groups = new mutable.ListBuffer[String]
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1945
      var options = Options.init(specs = Options.Spec.ISABELLE_BUILD_OPTIONS)
80423
797196669573 tuned cli;
Fabian Huch <huch@in.tum.de>
parents: 80422
diff changeset
  1946
      val prefs = new mutable.ListBuffer[Options.Spec]
80254
6b3374d208b8 add verbose option to build_task;
Fabian Huch <huch@in.tum.de>
parents: 80252
diff changeset
  1947
      var verbose = false
80250
8ae6f4e8cc2a allow explicit Isabelle rev in build task (e.g., for older Isabelle versions);
Fabian Huch <huch@in.tum.de>
parents: 80246
diff changeset
  1948
      var rev = ""
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1949
      val exclude_sessions = new mutable.ListBuffer[String]
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1950
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1951
      val getopts = Getopts("""
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1952
Usage: isabelle build_task [OPTIONS] [SESSIONS ...]
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1953
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1954
  Options are:
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1955
    -A ROOT      include AFP with given root directory (":" for """ + AFP.BASE.implode + """)
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1956
    -B NAME      include session NAME and all descendants
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1957
    -P           enable HTML/PDF presentation
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1958
    -R           refer to requirements of selected sessions
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1959
    -X NAME      exclude sessions from group NAME and all descendants
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1960
    -a           select all sessions
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1961
    -b           build heap images
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1962
    -c           clean build
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1963
    -e           export files from session specification into file-system
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1964
    -f           fresh build
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1965
    -g NAME      select session group NAME
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1966
    -o OPTION    override Isabelle system OPTION (via NAME=VAL or NAME)
80423
797196669573 tuned cli;
Fabian Huch <huch@in.tum.de>
parents: 80422
diff changeset
  1967
    -p OPTION    override Isabelle system OPTION for build process (via NAME=VAL or NAME)
80250
8ae6f4e8cc2a allow explicit Isabelle rev in build task (e.g., for older Isabelle versions);
Fabian Huch <huch@in.tum.de>
parents: 80246
diff changeset
  1968
    -r REV       explicit revision (default: state of working directory)
80254
6b3374d208b8 add verbose option to build_task;
Fabian Huch <huch@in.tum.de>
parents: 80252
diff changeset
  1969
    -v           verbose
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1970
    -x NAME      exclude session NAME and all descendants
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1971
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1972
  Submit build task on SSH server. Notable system options:
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1973
82039
e0ba5e9850df tuned output;
Fabian Huch <huch@in.tum.de>
parents: 82038
diff changeset
  1974
""" + Library.indent_lines(2, options.get("build_manager_ssh_user").get.print) + "\n",
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1975
        "A:" -> (arg => afp_root = Some(if (arg == ":") AFP.BASE else Path.explode(arg))),
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1976
        "B:" -> (arg => base_sessions += arg),
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1977
        "P" -> (_ => presentation = true),
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1978
        "R" -> (_ => requirements = true),
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1979
        "X:" -> (arg => exclude_session_groups += arg),
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1980
        "a" -> (_ => all_sessions = true),
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1981
        "b" -> (_ => build_heap = true),
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1982
        "c" -> (_ => clean_build = true),
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1983
        "e" -> (_ => export_files = true),
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1984
        "f" -> (_ => fresh_build = true),
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1985
        "g:" -> (arg => session_groups += arg),
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1986
        "o:" -> (arg => options = options + arg),
80423
797196669573 tuned cli;
Fabian Huch <huch@in.tum.de>
parents: 80422
diff changeset
  1987
        "p:" -> (arg => prefs += Options.Spec.make(arg)),
80250
8ae6f4e8cc2a allow explicit Isabelle rev in build task (e.g., for older Isabelle versions);
Fabian Huch <huch@in.tum.de>
parents: 80246
diff changeset
  1988
        "r:" -> (arg => rev = arg),
80254
6b3374d208b8 add verbose option to build_task;
Fabian Huch <huch@in.tum.de>
parents: 80252
diff changeset
  1989
        "v" -> (_ => verbose = true),
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1990
        "x:" -> (arg => exclude_sessions += arg))
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1991
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1992
      val sessions = getopts(args)
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1993
      val store = Store(options)
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1994
      val progress = new Console_Progress()
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  1995
80470
Fabian Huch <huch@in.tum.de>
parents: 80469
diff changeset
  1996
      build_task(options, store, afp_root = afp_root, base_sessions = base_sessions.toList,
Fabian Huch <huch@in.tum.de>
parents: 80469
diff changeset
  1997
        presentation = presentation, requirements = requirements, exclude_session_groups =
Fabian Huch <huch@in.tum.de>
parents: 80469
diff changeset
  1998
        exclude_session_groups.toList, all_sessions = all_sessions, build_heap = build_heap,
Fabian Huch <huch@in.tum.de>
parents: 80469
diff changeset
  1999
        clean_build = clean_build, export_files = export_files, fresh_build = fresh_build,
Fabian Huch <huch@in.tum.de>
parents: 80469
diff changeset
  2000
        session_groups = session_groups.toList, sessions = sessions, prefs = prefs.toList, verbose =
Fabian Huch <huch@in.tum.de>
parents: 80469
diff changeset
  2001
        verbose, rev = rev, exclude_sessions = exclude_sessions.toList, progress = progress)
80246
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  2002
    })
245dd5f82462 add build manager module;
Fabian Huch <huch@in.tum.de>
parents:
diff changeset
  2003
}