| author | wenzelm | 
| Wed, 02 Oct 2024 11:17:47 +0200 | |
| changeset 81099 | 9dde09c065e1 | 
| parent 80782 | 32247ad40647 | 
| child 81881 | f23fc3d21873 | 
| permissions | -rw-r--r-- | 
| 80246 | 1  | 
/* Title: Pure/Build/build_manager.scala  | 
2  | 
Author: Fabian Huch, TU Muenchen  | 
|
3  | 
||
4  | 
Isabelle manager for automated and quasi-interactive builds, with web frontend.  | 
|
5  | 
*/  | 
|
6  | 
||
7  | 
package isabelle  | 
|
8  | 
||
9  | 
||
10  | 
import scala.collection.mutable  | 
|
11  | 
import scala.annotation.tailrec  | 
|
12  | 
||
13  | 
||
14  | 
object Build_Manager {
 | 
|
| 80344 | 15  | 
/** task state synchronized via db **/  | 
| 80246 | 16  | 
|
17  | 
  object Component {
 | 
|
18  | 
def parse(s: String): Component =  | 
|
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 | 21  | 
case name :: rev :: Nil => Component(name, rev)  | 
22  | 
        case _ => error("Malformed component: " + quote(s))
 | 
|
23  | 
}  | 
|
24  | 
||
| 80543 | 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 | 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 | 30  | 
}  | 
31  | 
||
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 | 34  | 
|
35  | 
def is_local: Boolean = rev.isEmpty  | 
|
| 80246 | 36  | 
}  | 
37  | 
||
38  | 
  sealed trait Build_Config {
 | 
|
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 | 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 | 44  | 
}  | 
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 | 49  | 
|
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 | 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 | 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 | 63  | 
}  | 
64  | 
||
65  | 
  object User_Build {
 | 
|
66  | 
val name: String = "user"  | 
|
67  | 
}  | 
|
68  | 
||
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 | 71  | 
afp_rev: Option[String] = None,  | 
72  | 
prefs: List[Options.Spec] = Nil,  | 
|
73  | 
requirements: Boolean = false,  | 
|
74  | 
all_sessions: Boolean = false,  | 
|
75  | 
base_sessions: List[String] = Nil,  | 
|
76  | 
exclude_session_groups: List[String] = Nil,  | 
|
77  | 
exclude_sessions: List[String] = Nil,  | 
|
78  | 
session_groups: List[String] = Nil,  | 
|
79  | 
sessions: List[String] = Nil,  | 
|
80  | 
build_heap: Boolean = false,  | 
|
81  | 
clean_build: Boolean = false,  | 
|
82  | 
export_files: Boolean = false,  | 
|
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 | 86  | 
  ) extends Build_Config {
 | 
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 | 91  | 
" build" +  | 
92  | 
if_proper(afp_rev, " -A:") +  | 
|
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 | 95  | 
if_proper(presentation, " -P:") +  | 
96  | 
if_proper(requirements, " -R") +  | 
|
| 80422 | 97  | 
exclude_session_groups.map(session => " -X " + Bash.string(session)).mkString +  | 
| 80246 | 98  | 
if_proper(all_sessions, " -a") +  | 
99  | 
if_proper(build_heap, " -b") +  | 
|
100  | 
if_proper(clean_build, " -c") +  | 
|
101  | 
if_proper(export_files, " -e") +  | 
|
102  | 
if_proper(fresh_build, " -f") +  | 
|
| 80422 | 103  | 
session_groups.map(session => " -g " + Bash.string(session)).mkString +  | 
| 80246 | 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 | 106  | 
exclude_sessions.map(session => " -x " + Bash.string(session)).mkString +  | 
| 80246 | 107  | 
sessions.map(session => " " + Bash.string(session)).mkString  | 
108  | 
}  | 
|
109  | 
}  | 
|
110  | 
||
111  | 
  enum Priority { case low, normal, high }
 | 
|
112  | 
||
| 80339 | 113  | 
  object Build {
 | 
114  | 
def name(kind: String, id: Long): String = kind + "/" + id  | 
|
115  | 
}  | 
|
| 80410 | 116  | 
|
| 80339 | 117  | 
sealed trait Build extends Name.T  | 
| 80246 | 118  | 
|
119  | 
sealed case class Task(  | 
|
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 | 125  | 
submit_date: Date = Date.now(),  | 
126  | 
priority: Priority = Priority.normal,  | 
|
127  | 
isabelle_rev: String = ""  | 
|
| 80339 | 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 | 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 | 142  | 
}  | 
143  | 
||
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 | 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 | 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 | 153  | 
start_date: Date = Date.now(),  | 
154  | 
cancelled: Boolean = false  | 
|
| 80339 | 155  | 
  ) extends Build { def name: String = Build.name(kind, id) }
 | 
| 80246 | 156  | 
|
157  | 
  object Status {
 | 
|
158  | 
    def from_result(result: Process_Result): Status = {
 | 
|
159  | 
if (result.ok) Status.ok  | 
|
160  | 
else if (result.interrupted) Status.cancelled  | 
|
161  | 
else Status.failed  | 
|
162  | 
}  | 
|
163  | 
}  | 
|
164  | 
||
| 80502 | 165  | 
  enum Status { case ok, cancelled, aborted, failed }
 | 
| 80246 | 166  | 
|
167  | 
sealed case class Result(  | 
|
168  | 
kind: String,  | 
|
| 
80337
 
02f8a35ed8e2
clarified names: more canonical;
 
Fabian Huch <huch@in.tum.de> 
parents: 
80336 
diff
changeset
 | 
169  | 
id: Long,  | 
| 80246 | 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 | 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 | 184  | 
|
185  | 
  object State {
 | 
|
186  | 
def max_serial(serials: Iterable[Long]): Long = serials.maxOption.getOrElse(0L)  | 
|
187  | 
    def inc_serial(serial: Long): Long = {
 | 
|
188  | 
require(serial < Long.MaxValue, "number overflow")  | 
|
189  | 
serial + 1  | 
|
190  | 
}  | 
|
191  | 
||
| 80272 | 192  | 
type Pending = Name.Data[Task]  | 
193  | 
type Running = Name.Data[Job]  | 
|
| 80246 | 194  | 
type Finished = Map[String, Result]  | 
195  | 
}  | 
|
196  | 
||
197  | 
sealed case class State(  | 
|
198  | 
serial: Long = 0,  | 
|
199  | 
pending: State.Pending = Map.empty,  | 
|
200  | 
running: State.Running = Map.empty,  | 
|
201  | 
finished: State.Finished = Map.empty  | 
|
202  | 
  ) {
 | 
|
203  | 
def next_serial: Long = State.inc_serial(serial)  | 
|
204  | 
||
205  | 
def add_pending(task: Task): State = copy(pending = pending + (task.name -> task))  | 
|
206  | 
def remove_pending(name: String): State = copy(pending = pending - name)  | 
|
207  | 
||
208  | 
def num_builds = running.size + finished.size  | 
|
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 | 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 | 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 | 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 | 226  | 
|
227  | 
def add_running(job: Job): State = copy(running = running + (job.name -> job))  | 
|
228  | 
def remove_running(name: String): State = copy(running = running - name)  | 
|
| 80468 | 229  | 
def cancel_running(name: String): State =  | 
230  | 
      running.get(name) match {
 | 
|
231  | 
case Some(job) => copy(running = (running - name) + (name -> job.copy(cancelled = true)))  | 
|
232  | 
case None => this  | 
|
233  | 
}  | 
|
| 80246 | 234  | 
|
235  | 
def add_finished(result: Result): State = copy(finished = finished + (result.name -> result))  | 
|
236  | 
||
237  | 
lazy val kinds = (  | 
|
238  | 
pending.values.map(_.kind) ++  | 
|
239  | 
running.values.map(_.kind) ++  | 
|
240  | 
finished.values.map(_.kind)).toList.distinct  | 
|
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 | 244  | 
State.inc_serial(State.max_serial(serials))  | 
245  | 
}  | 
|
246  | 
||
247  | 
def get_running(kind: String): List[Job] =  | 
|
248  | 
(for ((_, job) <- running if job.kind == kind) yield job).toList  | 
|
249  | 
||
250  | 
def get_finished(kind: String): List[Result] =  | 
|
251  | 
(for ((_, result) <- finished if result.kind == kind) yield result).toList  | 
|
252  | 
||
| 80339 | 253  | 
def get(name: String): Option[Build] =  | 
| 80246 | 254  | 
pending.get(name).orElse(running.get(name)).orElse(finished.get(name))  | 
255  | 
||
| 80339 | 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 | 260  | 
}  | 
261  | 
||
262  | 
||
| 80344 | 263  | 
/** SQL data model **/  | 
| 80246 | 264  | 
|
265  | 
  object private_data extends SQL.Data("isabelle_build_manager") {
 | 
|
266  | 
/* tables */  | 
|
267  | 
||
268  | 
override lazy val tables: SQL.Tables =  | 
|
269  | 
SQL.Tables(State.table, Pending.table, Running.table, Finished.table)  | 
|
270  | 
||
271  | 
||
272  | 
/* state */  | 
|
273  | 
||
274  | 
    object State {
 | 
|
275  | 
      val serial = SQL.Column.long("serial").make_primary_key
 | 
|
276  | 
||
277  | 
val table = make_table(List(serial), name = "state")  | 
|
278  | 
}  | 
|
279  | 
||
280  | 
def read_serial(db: SQL.Database): Long =  | 
|
281  | 
db.execute_query_statementO[Long](  | 
|
282  | 
State.table.select(List(State.serial.max)),  | 
|
283  | 
_.long(State.serial)).getOrElse(0L)  | 
|
284  | 
||
285  | 
    def pull_state(db: SQL.Database, state: State): State = {
 | 
|
286  | 
val serial_db = read_serial(db)  | 
|
287  | 
if (serial_db == state.serial) state  | 
|
288  | 
      else {
 | 
|
289  | 
val serial = serial_db max state.serial  | 
|
290  | 
||
291  | 
val pending = pull_pending(db)  | 
|
292  | 
val running = pull_running(db)  | 
|
293  | 
val finished = pull_finished(db, state.finished)  | 
|
294  | 
||
295  | 
state.copy(serial = serial, pending = pending, running = running, finished = finished)  | 
|
296  | 
}  | 
|
297  | 
}  | 
|
298  | 
||
299  | 
    def push_state(db: SQL.Database, old_state: State, state: State): State = {
 | 
|
300  | 
val finished = push_finished(db, state.finished)  | 
|
301  | 
val updates =  | 
|
302  | 
List(  | 
|
303  | 
update_pending(db, old_state.pending, state.pending),  | 
|
304  | 
update_running(db, old_state.running, state.running),  | 
|
305  | 
).filter(_.defined)  | 
|
306  | 
||
307  | 
if (updates.isEmpty && finished == old_state.finished) state  | 
|
308  | 
      else {
 | 
|
309  | 
val serial = state.next_serial  | 
|
310  | 
db.execute_statement(State.table.delete(State.serial.where_equal(old_state.serial)))  | 
|
311  | 
db.execute_statement(State.table.insert(), body =  | 
|
312  | 
          { (stmt: SQL.Statement) =>
 | 
|
313  | 
stmt.long(1) = serial  | 
|
314  | 
})  | 
|
315  | 
state.copy(serial = serial, finished = finished)  | 
|
316  | 
}  | 
|
317  | 
}  | 
|
318  | 
||
319  | 
||
320  | 
/* pending */  | 
|
321  | 
||
322  | 
    object Pending {
 | 
|
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 | 329  | 
      val submit_date = SQL.Column.date("submit_date")
 | 
330  | 
      val priority = SQL.Column.string("priority")
 | 
|
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 | 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 | 335  | 
      val prefs = SQL.Column.string("prefs")
 | 
336  | 
      val requirements = SQL.Column.bool("requirements")
 | 
|
337  | 
      val all_sessions = SQL.Column.bool("all_sessions")
 | 
|
338  | 
      val base_sessions = SQL.Column.string("base_sessions")
 | 
|
339  | 
      val exclude_session_groups = SQL.Column.string("exclude_session_groups")
 | 
|
340  | 
      val exclude_sessions = SQL.Column.string("exclude_sessions")
 | 
|
341  | 
      val session_groups = SQL.Column.string("session_groups")
 | 
|
342  | 
      val sessions = SQL.Column.string("sessions")
 | 
|
343  | 
      val build_heap = SQL.Column.bool("build_heap")
 | 
|
344  | 
      val clean_build = SQL.Column.bool("clean_build")
 | 
|
345  | 
      val export_files = SQL.Column.bool("export_files")
 | 
|
346  | 
      val fresh_build = SQL.Column.bool("fresh_build")
 | 
|
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 | 349  | 
|
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 | 355  | 
name = "pending")  | 
356  | 
}  | 
|
357  | 
||
358  | 
def pull_pending(db: SQL.Database): Build_Manager.State.Pending =  | 
|
359  | 
db.execute_query_statement(Pending.table.select(), Map.from[String, Task], get =  | 
|
360  | 
        { res =>
 | 
|
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 | 367  | 
val submit_date = res.date(Pending.submit_date)  | 
368  | 
val priority = Priority.valueOf(res.string(Pending.priority))  | 
|
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 | 372  | 
|
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 | 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 | 377  | 
val prefs = Options.Spec.parse(res.string(Pending.prefs))  | 
378  | 
val requirements = res.bool(Pending.requirements)  | 
|
379  | 
val all_sessions = res.bool(Pending.all_sessions)  | 
|
380  | 
              val base_sessions = space_explode(',', res.string(Pending.base_sessions))
 | 
|
381  | 
val exclude_session_groups =  | 
|
382  | 
                space_explode(',', res.string(Pending.exclude_session_groups))
 | 
|
383  | 
              val exclude_sessions = space_explode(',', res.string(Pending.exclude_sessions))
 | 
|
384  | 
              val session_groups = space_explode(',', res.string(Pending.session_groups))
 | 
|
385  | 
              val sessions = space_explode(',', res.string(Pending.sessions))
 | 
|
386  | 
val build_heap = res.bool(Pending.build_heap)  | 
|
387  | 
val clean_build = res.bool(Pending.clean_build)  | 
|
388  | 
val export_files = res.bool(Pending.export_files)  | 
|
389  | 
val fresh_build = res.bool(Pending.fresh_build)  | 
|
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 | 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 | 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 | 397  | 
}  | 
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 | 401  | 
|
402  | 
task.name -> task  | 
|
403  | 
})  | 
|
404  | 
||
405  | 
def update_pending(  | 
|
406  | 
db: SQL.Database,  | 
|
407  | 
old_pending: Build_Manager.State.Pending,  | 
|
408  | 
pending: Build_Manager.State.Pending  | 
|
| 80274 | 409  | 
    ): Update = {
 | 
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 | 412  | 
|
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 | 415  | 
|
416  | 
      if (update.inserts) {
 | 
|
417  | 
db.execute_batch_statement(Pending.table.insert(), batch =  | 
|
418  | 
          for (name <- update.insert) yield { (stmt: SQL.Statement) =>
 | 
|
419  | 
val task = pending(name)  | 
|
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 | 431  | 
|
432  | 
def get[A](f: User_Build => A): Option[A] =  | 
|
433  | 
              task.build_config match {
 | 
|
434  | 
case user_build: User_Build => Some(f(user_build))  | 
|
435  | 
case _ => None  | 
|
436  | 
}  | 
|
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 | 452  | 
})  | 
453  | 
}  | 
|
454  | 
||
455  | 
update  | 
|
456  | 
}  | 
|
457  | 
||
458  | 
||
459  | 
/* running */  | 
|
460  | 
||
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 | 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 | 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 | 470  | 
      val start_date = SQL.Column.date("start_date")
 | 
471  | 
      val cancelled = SQL.Column.bool("cancelled")
 | 
|
472  | 
||
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 | 476  | 
name = "running")  | 
477  | 
}  | 
|
478  | 
||
479  | 
def pull_running(db: SQL.Database): Build_Manager.State.Running =  | 
|
480  | 
db.execute_query_statement(Running.table.select(), Map.from[String, Job], get =  | 
|
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 | 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 | 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 | 490  | 
val start_date = res.date(Running.start_date)  | 
491  | 
val cancelled = res.bool(Running.cancelled)  | 
|
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 | 495  | 
|
496  | 
job.name -> job  | 
|
497  | 
})  | 
|
498  | 
||
499  | 
def update_running(  | 
|
500  | 
db: SQL.Database,  | 
|
501  | 
old_running: Build_Manager.State.Running,  | 
|
502  | 
running: Build_Manager.State.Running  | 
|
| 80274 | 503  | 
    ): Update = {
 | 
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 | 506  | 
|
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 | 509  | 
|
510  | 
      if (update.inserts) {
 | 
|
511  | 
db.execute_batch_statement(Running.table.insert(), batch =  | 
|
512  | 
          for (name <- update.insert) yield { (stmt: SQL.Statement) =>
 | 
|
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 | 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 | 524  | 
})  | 
525  | 
}  | 
|
526  | 
update  | 
|
527  | 
}  | 
|
528  | 
||
529  | 
||
530  | 
/* finished */  | 
|
531  | 
||
532  | 
    object Finished {
 | 
|
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 | 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 | 543  | 
      val serial = SQL.Column.long("serial").make_primary_key
 | 
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 | 550  | 
}  | 
551  | 
||
552  | 
def read_finished_serial(db: SQL.Database): Long =  | 
|
553  | 
db.execute_query_statementO[Long](  | 
|
554  | 
Finished.table.select(List(Finished.serial.max)),  | 
|
555  | 
_.long(Finished.serial)).getOrElse(0L)  | 
|
556  | 
||
557  | 
def pull_finished(  | 
|
558  | 
db: SQL.Database,  | 
|
559  | 
finished: Build_Manager.State.Finished  | 
|
560  | 
    ): Build_Manager.State.Finished = {
 | 
|
561  | 
val max_serial0 = Build_Manager.State.max_serial(finished.values.map(_.serial))  | 
|
562  | 
val max_serial1 = read_finished_serial(db)  | 
|
563  | 
val missing = (max_serial0 + 1) to max_serial1  | 
|
564  | 
finished ++ db.execute_query_statement(  | 
|
565  | 
Finished.table.select(sql = Finished.serial.where_member_long(missing)),  | 
|
566  | 
Map.from[String, Result], get =  | 
|
567  | 
        { res =>
 | 
|
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 | 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 | 578  | 
val serial = res.long(Finished.serial)  | 
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 | 582  | 
result.name -> result  | 
583  | 
}  | 
|
584  | 
)  | 
|
585  | 
}  | 
|
586  | 
||
587  | 
def push_finished(  | 
|
588  | 
db: SQL.Database,  | 
|
589  | 
finished: Build_Manager.State.Finished  | 
|
590  | 
    ): Build_Manager.State.Finished = {
 | 
|
591  | 
val (insert0, old) = finished.partition(_._2.serial == 0L)  | 
|
592  | 
val max_serial = Build_Manager.State.max_serial(finished.map(_._2.serial))  | 
|
593  | 
val insert =  | 
|
594  | 
for (((_, result), n) <- insert0.zipWithIndex)  | 
|
595  | 
yield result.copy(serial = max_serial + 1 + n)  | 
|
596  | 
||
597  | 
if (insert.nonEmpty)  | 
|
598  | 
db.execute_batch_statement(Finished.table.insert(), batch =  | 
|
599  | 
          for (result <- insert) yield { (stmt: SQL.Statement) =>
 | 
|
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 | 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 | 611  | 
})  | 
612  | 
||
613  | 
old ++ insert.map(result => result.serial.toString -> result)  | 
|
614  | 
}  | 
|
615  | 
}  | 
|
616  | 
||
617  | 
||
| 80497 | 618  | 
/** build reports **/  | 
619  | 
||
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 | 625  | 
}  | 
626  | 
||
627  | 
  case class Report(kind: String, id: Long, dir: Path) {
 | 
|
628  | 
private val log_name = "build-manager"  | 
|
| 80531 | 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 | 631  | 
|
632  | 
private def log_file = dir + Path.basic(log_name).log  | 
|
| 80498 | 633  | 
private def log_file_gz = dir + Path.basic(log_name).log.gz  | 
| 80497 | 634  | 
|
635  | 
def init(): Unit = Isabelle_System.make_directory(dir)  | 
|
636  | 
||
| 80498 | 637  | 
def ok: Boolean = log_file.is_file != log_file_gz.is_file  | 
| 80497 | 638  | 
|
639  | 
def progress: Progress = new File_Progress(log_file)  | 
|
640  | 
||
| 80531 | 641  | 
private def read_gz(file: Path, ext: String): Option[(String, String)] =  | 
642  | 
if (!File.is_gz(file.file_name) || file.drop_ext.get_ext != ext) None  | 
|
643  | 
else Some(file.drop_ext.drop_ext.file_name -> File.read_gzip(file))  | 
|
644  | 
||
| 80498 | 645  | 
    def read: Report.Data = {
 | 
| 80532 | 646  | 
val build_log =  | 
| 80498 | 647  | 
if_proper(ok, if (log_file.is_file) File.read(log_file) else File.read_gzip(log_file_gz))  | 
| 80531 | 648  | 
|
| 80532 | 649  | 
val component_diffs =  | 
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 | 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 | 655  | 
}  | 
| 80497 | 656  | 
|
| 80544 | 657  | 
def write_log(  | 
658  | 
component: String,  | 
|
659  | 
repository: Mercurial.Repository,  | 
|
660  | 
rev0: String,  | 
|
661  | 
rev: String  | 
|
662  | 
): Unit =  | 
|
663  | 
      if (rev0.nonEmpty && rev.nonEmpty && rev0 != rev) {
 | 
|
664  | 
val log_opts = "--graph --color always"  | 
|
665  | 
        val rev1 = "children(" + rev0 + ")"
 | 
|
666  | 
        val cmd = repository.command_line("log", Mercurial.opt_rev(rev1 + ":" + rev), log_opts)
 | 
|
667  | 
        val log = Isabelle_System.bash("export HGPLAINEXCEPT=color\n" + cmd).check.out
 | 
|
668  | 
if (log.nonEmpty) File.write_gzip(dir + Path.basic(component).ext(log_ext).gz, log)  | 
|
669  | 
}  | 
|
| 80500 | 670  | 
|
| 80544 | 671  | 
def write_diff(  | 
672  | 
component: String,  | 
|
673  | 
repository: Mercurial.Repository,  | 
|
674  | 
rev0: String,  | 
|
675  | 
rev: String  | 
|
676  | 
): Unit =  | 
|
677  | 
      if (rev0.nonEmpty && rev.nonEmpty) {
 | 
|
678  | 
val diff_opts = "--noprefix --nodates --ignore-all-space --color always"  | 
|
679  | 
        val cmd = repository.command_line("diff", Mercurial.opt_rev(rev0 + ":" + rev), diff_opts)
 | 
|
680  | 
        val diff = Isabelle_System.bash("export HGPLAINEXCEPT=color\n" + cmd).check.out
 | 
|
681  | 
if (diff.nonEmpty) File.write_gzip(dir + Path.basic(component).ext(diff_ext).gz, diff)  | 
|
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 | 685  | 
val End = """^Job ended at [^,]+, with status (\w+)$""".r  | 
686  | 
||
| 80532 | 687  | 
val build_log_file = Build_Log.Log_File(log_name, Library.trim_split_lines(read.build_log))  | 
| 80497 | 688  | 
|
689  | 
val meta_info = build_log_file.parse_meta_info()  | 
|
690  | 
val status =  | 
|
691  | 
        build_log_file.lines.last match {
 | 
|
692  | 
case End(status) => Status.valueOf(status)  | 
|
693  | 
case _ => Status.aborted  | 
|
694  | 
}  | 
|
695  | 
      val build_host = meta_info.get_build_host.getOrElse(error("No build host"))
 | 
|
696  | 
      val start_date = meta_info.get_build_start.getOrElse(error("No start date"))
 | 
|
697  | 
val end_date = meta_info.get_build_end  | 
|
698  | 
val isabelle_version = meta_info.get(Build_Log.Prop.isabelle_version)  | 
|
699  | 
val afp_version = meta_info.get(Build_Log.Prop.afp_version)  | 
|
700  | 
||
| 80498 | 701  | 
      if (log_file.is_file) {
 | 
702  | 
File.write_gzip(log_file_gz, build_log_file.text)  | 
|
703  | 
Isabelle_System.rm_tree(log_file)  | 
|
704  | 
}  | 
|
705  | 
||
| 80497 | 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 | 708  | 
}  | 
709  | 
}  | 
|
710  | 
||
711  | 
||
| 80344 | 712  | 
/** running build manager processes **/  | 
| 80246 | 713  | 
|
714  | 
abstract class Loop_Process[A](name: String, store: Store, progress: Progress)  | 
|
715  | 
    extends Runnable {
 | 
|
716  | 
val options = store.options  | 
|
717  | 
||
718  | 
private val _database =  | 
|
719  | 
      try { store.open_database() }
 | 
|
720  | 
      catch { case exn: Throwable => close(); throw exn }
 | 
|
721  | 
||
722  | 
def close(): Unit = Option(_database).foreach(_.close())  | 
|
723  | 
||
724  | 
protected var _state = State()  | 
|
725  | 
||
726  | 
    protected def synchronized_database[A](label: String)(body: => A): A = synchronized {
 | 
|
727  | 
      Build_Manager.private_data.transaction_lock(_database, label = name + "." + label) {
 | 
|
728  | 
val old_state = Build_Manager.private_data.pull_state(_database, _state)  | 
|
729  | 
_state = old_state  | 
|
730  | 
val res = body  | 
|
731  | 
_state = Build_Manager.private_data.push_state(_database, old_state, _state)  | 
|
732  | 
res  | 
|
733  | 
}  | 
|
734  | 
}  | 
|
735  | 
||
736  | 
    protected def delay = options.seconds("build_manager_delay")
 | 
|
737  | 
||
738  | 
def init: A  | 
|
739  | 
def loop_body(a: A): A  | 
|
740  | 
def stopped(a: A): Boolean = progress.stopped  | 
|
741  | 
||
742  | 
private val interrupted = Synchronized(false)  | 
|
743  | 
private def sleep(time_limit: Time): Unit =  | 
|
744  | 
interrupted.timed_access(_ => Some(time_limit), b => if (b) Some((), false) else None)  | 
|
745  | 
def interrupt(): Unit = interrupted.change(_ => true)  | 
|
746  | 
||
747  | 
@tailrec private def loop(a: A): Unit =  | 
|
748  | 
      if (!stopped(a)) {
 | 
|
749  | 
val start = Time.now()  | 
|
750  | 
val a1 = loop_body(a)  | 
|
751  | 
        if (!stopped(a)) {
 | 
|
752  | 
sleep(start + delay)  | 
|
753  | 
loop(a1)  | 
|
754  | 
}  | 
|
755  | 
}  | 
|
756  | 
||
757  | 
    override def run(): Unit = {
 | 
|
758  | 
      progress.echo("Started " + name)
 | 
|
759  | 
loop(init)  | 
|
760  | 
close()  | 
|
761  | 
      progress.echo("Stopped " + name)
 | 
|
762  | 
}  | 
|
763  | 
||
764  | 
def echo(msg: String) = progress.echo(name + ": " + msg)  | 
|
765  | 
def echo_error_message(msg: String) = progress.echo_error_message(name + ": " + msg)  | 
|
766  | 
}  | 
|
767  | 
||
768  | 
||
769  | 
/* build runner */  | 
|
770  | 
||
771  | 
  object Runner {
 | 
|
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 | 775  | 
}  | 
776  | 
||
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 | 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 | 789  | 
def is_empty = process_futures.isEmpty && result_futures.isEmpty  | 
| 80246 | 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 | 793  | 
val result_future =  | 
| 80246 | 794  | 
Future.fork(  | 
| 80277 | 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 | 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 | 803  | 
}  | 
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 | 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 | 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 | 816  | 
if (is_late) process_futures(name).join.terminate()  | 
817  | 
is_late  | 
|
818  | 
}  | 
|
| 
80645
 
a1dce0cc6c26
build_manager: terminate processes if cancelling does not work;
 
Fabian Huch <huch@in.tum.de> 
parents: 
80644 
diff
changeset
 | 
819  | 
|
| 80246 | 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 | 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 | 843  | 
}  | 
844  | 
||
| 80730 | 845  | 
      private def do_cancel(process_future: Future[Build_Process]): Boolean = {
 | 
846  | 
val is_finished = process_future.is_finished  | 
|
847  | 
if (is_finished) process_future.join.cancel() else process_future.cancel()  | 
|
848  | 
is_finished  | 
|
849  | 
}  | 
|
| 80246 | 850  | 
|
| 80730 | 851  | 
      def cancel(cancelled: List[String]): State = {
 | 
852  | 
val cancelling_until1 =  | 
|
853  | 
          for {
 | 
|
854  | 
name <- cancelled  | 
|
855  | 
process_future <- process_futures.get(name)  | 
|
856  | 
if do_cancel(process_future)  | 
|
857  | 
} yield name -> (Time.now() + cancel_timeout)  | 
|
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 | 860  | 
}  | 
| 80246 | 861  | 
}  | 
862  | 
}  | 
|
863  | 
||
864  | 
class Runner(  | 
|
865  | 
store: Store,  | 
|
866  | 
build_hosts: List[Build_Cluster.Host],  | 
|
867  | 
isabelle_repository: Mercurial.Repository,  | 
|
868  | 
sync_dirs: List[Sync.Dir],  | 
|
869  | 
progress: Progress  | 
|
870  | 
  ) extends Loop_Process[Runner.State]("Runner", store, progress) {
 | 
|
871  | 
val rsync_context = Rsync.Context()  | 
|
872  | 
||
873  | 
    private def sync(repository: Mercurial.Repository, rev: String, target: Path): String = {
 | 
|
874  | 
repository.pull()  | 
|
875  | 
||
876  | 
if (rev.nonEmpty) repository.sync(rsync_context, target, rev = rev)  | 
|
877  | 
||
878  | 
      Exn.capture(repository.id(File.read(target + Mercurial.Hg_Sync.PATH_ID))) match {
 | 
|
879  | 
case Exn.Res(res) => res  | 
|
| 80647 | 880  | 
case Exn.Exn(_) => ""  | 
| 80246 | 881  | 
}  | 
882  | 
}  | 
|
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 | 893  | 
|
894  | 
_state = _state.remove_pending(task.name)  | 
|
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 | 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 | 910  | 
          Exn.capture {
 | 
| 80497 | 911  | 
context.report.init()  | 
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 | 916  | 
val isabelle_rev = sync(isabelle_repository, task.isabelle_rev, context.task_dir)  | 
| 80246 | 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 | 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 | 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 | 933  | 
}  | 
934  | 
||
| 80500 | 935  | 
            if (task.kind != User_Build.name && _state.get_finished(task.kind).nonEmpty) {
 | 
936  | 
val previous = _state.get_finished(task.kind).maxBy(_.id)  | 
|
937  | 
||
938  | 
              for (isabelle_rev0 <- previous.isabelle_version) {
 | 
|
| 80544 | 939  | 
context.report.write_log(Component.Isabelle,  | 
940  | 
isabelle_repository, isabelle_rev0, isabelle_rev)  | 
|
941  | 
context.report.write_diff(Component.Isabelle,  | 
|
942  | 
isabelle_repository, isabelle_rev0, isabelle_rev)  | 
|
| 80500 | 943  | 
}  | 
944  | 
||
945  | 
              for {
 | 
|
946  | 
afp_rev0 <- previous.afp_version  | 
|
947  | 
afp <- extra_components.find(_.name == Component.AFP)  | 
|
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 | 950  | 
context.report.write_log(afp.name, sync_dir.hg, afp_rev0, afp.rev)  | 
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 | 953  | 
}  | 
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 | 959  | 
          } match {
 | 
960  | 
case Exn.Res(job) =>  | 
|
961  | 
_state = _state.add_running(job)  | 
|
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 | 965  | 
|
| 
80280
 
7987b33fb6c5
clarified context: operations now in build process;
 
Fabian Huch <huch@in.tum.de> 
parents: 
80279 
diff
changeset
 | 
966  | 
Some(context)  | 
| 80246 | 967  | 
case Exn.Exn(exn) =>  | 
| 80497 | 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 | 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 | 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 | 975  | 
None  | 
976  | 
}  | 
|
977  | 
}  | 
|
978  | 
}  | 
|
979  | 
||
980  | 
private def stop_cancelled(state: Runner.State): Runner.State =  | 
|
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 | 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 | 1004  | 
}  | 
1005  | 
||
1006  | 
private def finish_job(name: String, process_result: Process_Result): Unit =  | 
|
1007  | 
      synchronized_database("finish_job") {
 | 
|
1008  | 
val job = _state.running(name)  | 
|
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 | 1014  | 
val report = store.report(job.kind, job.id)  | 
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 | 1020  | 
|
1021  | 
_state = _state  | 
|
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 | 1024  | 
}  | 
1025  | 
||
1026  | 
override def stopped(state: Runner.State): Boolean = progress.stopped && state.is_empty  | 
|
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 | 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 | 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 | 1055  | 
}  | 
1056  | 
}  | 
|
1057  | 
||
1058  | 
||
1059  | 
/* repository poller */  | 
|
1060  | 
||
1061  | 
  object Poller {
 | 
|
| 80574 | 1062  | 
case class State(current: List[Component], next: Future[List[Component]])  | 
| 80246 | 1063  | 
}  | 
1064  | 
||
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 | 1067  | 
store: Store,  | 
1068  | 
isabelle_repository: Mercurial.Repository,  | 
|
1069  | 
sync_dirs: List[Sync.Dir],  | 
|
1070  | 
progress: Progress  | 
|
1071  | 
  ) extends Loop_Process[Poller.State]("Poller", store, progress) {
 | 
|
1072  | 
||
1073  | 
    override def delay = options.seconds("build_manager_poll_delay")
 | 
|
1074  | 
||
| 80574 | 1075  | 
private def current: List[Component] =  | 
1076  | 
      Component.isabelle(isabelle_repository.id("default")) ::
 | 
|
1077  | 
        sync_dirs.map(dir => Component(dir.name, dir.hg.id("default")))
 | 
|
| 80246 | 1078  | 
|
| 80574 | 1079  | 
    private def poll: Future[List[Component]] = Future.fork {
 | 
| 80246 | 1080  | 
Par_List.map((repo: Mercurial.Repository) => repo.pull(),  | 
1081  | 
isabelle_repository :: sync_dirs.map(_.hg))  | 
|
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 | 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 | 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 | 1106  | 
} _state = _state.add_pending(CI_Build.task(ci_job))  | 
| 80246 | 1107  | 
}  | 
1108  | 
}  | 
|
1109  | 
||
1110  | 
def loop_body(state: Poller.State): Poller.State =  | 
|
1111  | 
if (!state.next.is_finished) state  | 
|
1112  | 
      else {
 | 
|
1113  | 
        state.next.join_result match {
 | 
|
1114  | 
case Exn.Exn(exn) =>  | 
|
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 | 1121  | 
}  | 
| 
80260
 
ed9b1598d293
manage components of ci builds;
 
Fabian Huch <huch@in.tum.de> 
parents: 
80259 
diff
changeset
 | 
1122  | 
Poller.State(next, poll)  | 
| 80246 | 1123  | 
}  | 
1124  | 
}  | 
|
1125  | 
}  | 
|
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 | 1134  | 
|
| 80405 | 1135  | 
    private def add_tasks(previous: Date, next: Date): Unit = synchronized_database("add_tasks") {
 | 
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 {
 | 
| 
80412
 
a7f8249533e9
moved ci_build module to build_ci;
 
Fabian Huch <huch@in.tum.de> 
parents: 
80411 
diff
changeset
 | 
1138  | 
case Build_CI.Timed(in_interval) if in_interval(previous, next) =>  | 
| 80416 | 1139  | 
val task = CI_Build.task(ci_job)  | 
| 80349 | 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 | 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 | 1154  | 
|
1155  | 
/* web server */  | 
|
1156  | 
||
1157  | 
  object Web_Server {
 | 
|
| 80338 | 1158  | 
val Id = new Properties.String(Markup.ID)  | 
1159  | 
||
| 80246 | 1160  | 
    object Page {
 | 
1161  | 
      val HOME = Path.basic("home")
 | 
|
1162  | 
      val OVERVIEW = Path.basic("overview")
 | 
|
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 | 1165  | 
}  | 
1166  | 
||
| 80348 | 1167  | 
def paths(store: Store): Web_App.Paths =  | 
1168  | 
Web_App.Paths(store.address, Path.current, serve_frontend = true, landing = Page.HOME)  | 
|
1169  | 
||
| 80246 | 1170  | 
    object API {
 | 
1171  | 
      val BUILD_CANCEL = Path.explode("api/build/cancel")
 | 
|
1172  | 
}  | 
|
1173  | 
||
1174  | 
    object Cache {
 | 
|
1175  | 
def empty: Cache = new Cache()  | 
|
1176  | 
}  | 
|
1177  | 
||
1178  | 
    class Cache private(keep: Time = Time.minutes(1)) {
 | 
|
| 80497 | 1179  | 
private var cached: Map[Report, (Time, Report.Data)] = Map.empty  | 
| 80246 | 1180  | 
|
| 80497 | 1181  | 
      def update(): Unit = synchronized {
 | 
1182  | 
cached =  | 
|
| 80246 | 1183  | 
          for {
 | 
| 80497 | 1184  | 
(report, (time, _)) <- cached  | 
| 80246 | 1185  | 
if time + keep > Time.now()  | 
| 80497 | 1186  | 
} yield report -> (time, report.read)  | 
| 80246 | 1187  | 
}  | 
1188  | 
||
| 80497 | 1189  | 
      def lookup(report: Report): Report.Data = synchronized {
 | 
1190  | 
        cached.get(report) match {
 | 
|
1191  | 
case Some((_, data)) =>  | 
|
1192  | 
cached += report -> (Time.now(), data)  | 
|
| 80246 | 1193  | 
case None =>  | 
| 80497 | 1194  | 
cached += report -> (Time.now(), report.read)  | 
| 80246 | 1195  | 
}  | 
| 80497 | 1196  | 
cached(report)._2  | 
| 80246 | 1197  | 
}  | 
1198  | 
}  | 
|
1199  | 
}  | 
|
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 | 1207  | 
import Web_App.*  | 
1208  | 
import Web_Server.*  | 
|
1209  | 
||
| 80348 | 1210  | 
val paths = Web_Server.paths(store)  | 
| 80246 | 1211  | 
val cache = Cache.empty  | 
1212  | 
||
1213  | 
    enum Model {
 | 
|
1214  | 
case Error extends Model  | 
|
1215  | 
case Cancelled extends Model  | 
|
1216  | 
case Home(state: State) extends Model  | 
|
1217  | 
case Overview(kind: String, state: State) extends Model  | 
|
| 80339 | 1218  | 
case Details(build: Build, state: State, public: Boolean = true) extends Model  | 
| 80647 | 1219  | 
case Diff(build: Build) extends Model  | 
| 80246 | 1220  | 
}  | 
1221  | 
||
1222  | 
    object View {
 | 
|
1223  | 
import HTML.*  | 
|
1224  | 
import More_HTML.*  | 
|
1225  | 
||
1226  | 
def render_if(cond: Boolean, body: XML.Body): XML.Body = if (cond) body else Nil  | 
|
1227  | 
||
| 80534 | 1228  | 
def page_link(path: Path, s: String, props: Properties.T = Nil): XML.Elem =  | 
1229  | 
        link(paths.frontend_url(path, props).toString, text(s)) + ("target" -> "_parent")
 | 
|
| 80246 | 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 | 1232  | 
page_link(Page.BUILD, "#" + id, Markup.Name(name))  | 
| 80246 | 1233  | 
|
| 80647 | 1234  | 
private def render_page(name: String)(body: => XML.Body): XML.Body =  | 
1235  | 
More_HTML.header(List(nav(List(page_link(Page.HOME, "home"))))) ::  | 
|
| 80258 | 1236  | 
main(chapter(name) :: body ::: Nil) :: Nil  | 
1237  | 
||
| 80419 | 1238  | 
private def summary(start: Date): XML.Body =  | 
1239  | 
        text(" running since " + Build_Log.print_date(start))
 | 
|
1240  | 
||
1241  | 
private def summary(status: Status, start: Date, end: Option[Date]): XML.Body =  | 
|
1242  | 
        text(" (" + status.toString + if_proper(end, " in " + (end.get - start).message_hms) +
 | 
|
1243  | 
") on " + Build_Log.print_date(start))  | 
|
1244  | 
||
| 80258 | 1245  | 
      def render_home(state: State): XML.Body = render_page("Dashboard") {
 | 
| 80246 | 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 | 1249  | 
|
1250  | 
          def render_previous(finished: List[Result]): XML.Body = {
 | 
|
1251  | 
val (failed, rest) = finished.span(_.status != Status.ok)  | 
|
1252  | 
val first_failed = failed.lastOption.map(result =>  | 
|
1253  | 
par(  | 
|
| 80419 | 1254  | 
                text("first failure: ") ::: link_build(result.name, result.id) ::
 | 
1255  | 
summary(result.status, result.start_date, result.end_date)))  | 
|
| 80246 | 1256  | 
val last_success = rest.headOption.map(result =>  | 
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 | 1259  | 
summary(result.status, result.start_date, result.end_date)))  | 
| 80246 | 1260  | 
first_failed.toList ::: last_success.toList  | 
1261  | 
}  | 
|
1262  | 
||
1263  | 
def render_job(job: Job): XML.Body =  | 
|
| 80419 | 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 | 1268  | 
|
1269  | 
def render_result(result: Result): XML.Body =  | 
|
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 | 1272  | 
summary(result.status, result.start_date, result.end_date)) ::  | 
| 80258 | 1273  | 
render_if(result.status != Status.ok && result.kind != User_Build.name,  | 
1274  | 
render_previous(finished.tail))  | 
|
| 80246 | 1275  | 
|
1276  | 
fieldset(  | 
|
| 80534 | 1277  | 
            XML.elem("legend", List(page_link(Page.OVERVIEW, kind, Markup.Kind(kind)))) ::
 | 
| 80246 | 1278  | 
(if (running.nonEmpty) render_job(running.head)  | 
1279  | 
else if (finished.nonEmpty) render_result(finished.head)  | 
|
1280  | 
else Nil))  | 
|
1281  | 
}  | 
|
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 | 1305  | 
state.kinds.sorted.map(render_kind)  | 
| 80246 | 1306  | 
}  | 
1307  | 
||
| 80258 | 1308  | 
def render_overview(kind: String, state: State): XML.Body =  | 
1309  | 
        render_page("Overview: " + kind + " job ") {
 | 
|
1310  | 
def render_job(job: Job): XML.Body =  | 
|
| 80419 | 1311  | 
List(par(link_build(job.name, job.id) :: summary(job.start_date)))  | 
| 80246 | 1312  | 
|
| 80258 | 1313  | 
def render_result(result: Result): XML.Body =  | 
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 | 1316  | 
summary(result.status, result.start_date, result.end_date)))  | 
| 80246 | 1317  | 
|
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 | 1321  | 
}  | 
| 80246 | 1322  | 
|
1323  | 
private val ID = Params.key(Markup.ID)  | 
|
1324  | 
||
| 80339 | 1325  | 
def render_details(build: Build, state: State, public: Boolean): XML.Body =  | 
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 | 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 | 1330  | 
api_button(paths.api_route(API.BUILD_CANCEL), "cancel build")))))  | 
| 80246 | 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 | 1335  | 
|
| 80547 | 1336  | 
            if (!components.map(_.name).exists(hg_info.toSet)) text("Components: " + s)
 | 
1337  | 
            else text("Components: ") :+ page_link(Page.DIFF, s, Markup.Name(build.name))
 | 
|
| 80501 | 1338  | 
}  | 
| 80500 | 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 | 1363  | 
          build match {
 | 
| 80258 | 1364  | 
case task: Task =>  | 
| 80420 | 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 | 1369  | 
|
| 80258 | 1370  | 
case job: Job =>  | 
| 80497 | 1371  | 
val report_data = cache.lookup(store.report(job.kind, job.id))  | 
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 | 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 | 1379  | 
|
| 80258 | 1380  | 
case result: Result =>  | 
| 80497 | 1381  | 
val report_data = cache.lookup(store.report(result.kind, result.id))  | 
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 | 1384  | 
if_proper(result.end_date,  | 
1385  | 
", took " + (result.end_date.get - result.start_date).message_hms))) ::  | 
|
| 80258 | 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 | 1389  | 
}  | 
1390  | 
}  | 
|
| 80246 | 1391  | 
|
| 80647 | 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 {
 | 
| 80538 | 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 | 1416  | 
data.component_diffs.toMap.get(component.name).toList.flatMap(colored)  | 
1417  | 
||
| 80547 | 1418  | 
val header = if (infos.isEmpty) component.toString else component.name + ":"  | 
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 | 1431  | 
def render_cancelled: XML.Body =  | 
1432  | 
        render_page("Build cancelled")(List(page_link(Page.HOME, "Home")))
 | 
|
| 80246 | 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 | 1435  | 
        for {
 | 
1436  | 
id <- params.get(ID)  | 
|
1437  | 
uuid <- UUID.unapply(id)  | 
|
1438  | 
} yield uuid  | 
|
1439  | 
}  | 
|
1440  | 
||
1441  | 
    private val server = new Server[Model](paths, port, progress = progress) {
 | 
|
1442  | 
/* control */  | 
|
1443  | 
||
1444  | 
def overview: Some[Model.Home] = Some(Model.Home(_state))  | 
|
1445  | 
||
1446  | 
def get_overview(props: Properties.T): Option[Model.Overview] =  | 
|
1447  | 
        props match {
 | 
|
1448  | 
case Markup.Kind(kind) => Some(Model.Overview(kind, _state))  | 
|
1449  | 
case _ => None  | 
|
1450  | 
}  | 
|
1451  | 
||
| 80339 | 1452  | 
def get_build(props: Properties.T): Option[Model.Details] =  | 
| 80246 | 1453  | 
        props match {
 | 
1454  | 
case Markup.Name(name) =>  | 
|
1455  | 
val state = _state  | 
|
| 80339 | 1456  | 
state.get(name).map(Model.Details(_, state))  | 
| 80338 | 1457  | 
case Web_Server.Id(UUID(uuid)) =>  | 
| 80246 | 1458  | 
val state = _state  | 
| 80339 | 1459  | 
state.get(uuid).map(Model.Details(_, state, public = false))  | 
| 80246 | 1460  | 
case _ => None  | 
1461  | 
}  | 
|
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 | 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 | 1469  | 
def cancel_build(params: Params.Data): Option[Model] =  | 
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 | 1472  | 
model <-  | 
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 | 1475  | 
case task: Task =>  | 
1476  | 
_state = _state.remove_pending(task.name)  | 
|
1477  | 
Model.Cancelled  | 
|
1478  | 
case job: Job =>  | 
|
| 80468 | 1479  | 
_state = _state.cancel_running(job.name)  | 
| 80467 | 1480  | 
Model.Cancelled  | 
| 80339 | 1481  | 
case result: Result => Model.Details(result, _state, public = false)  | 
| 80246 | 1482  | 
}  | 
1483  | 
}  | 
|
1484  | 
} yield model  | 
|
1485  | 
||
1486  | 
def render(model: Model): XML.Body =  | 
|
1487  | 
        HTML.title("Isabelle Build Manager") :: (
 | 
|
1488  | 
          model match {
 | 
|
1489  | 
            case Model.Error => HTML.text("invalid request")
 | 
|
1490  | 
case Model.Home(state) => View.render_home(state)  | 
|
1491  | 
case Model.Overview(kind, state) => View.render_overview(kind, state)  | 
|
| 80339 | 1492  | 
case Model.Details(build, state, public) => View.render_details(build, state, public)  | 
| 80647 | 1493  | 
case Model.Diff(build) => View.render_diff(build)  | 
| 80246 | 1494  | 
case Model.Cancelled => View.render_cancelled  | 
1495  | 
})  | 
|
1496  | 
||
1497  | 
val error_model: Model = Model.Error  | 
|
1498  | 
val endpoints = List(  | 
|
1499  | 
Get(Page.HOME, "home", _ => overview),  | 
|
1500  | 
Get(Page.OVERVIEW, "overview", get_overview),  | 
|
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 | 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 | 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("""
 | 
| 
 
5555a40b2ed4
build_manager: change colors;
 
Fabian Huch <huch@in.tum.de> 
parents: 
80649 
diff
changeset
 | 
1511  | 
:root { 
 | 
| 
 
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 | 1516  | 
}  | 
1517  | 
||
| 80782 | 1518  | 
    override def close(): Unit = {
 | 
1519  | 
server.stop()  | 
|
1520  | 
super.close()  | 
|
1521  | 
}  | 
|
1522  | 
||
| 80246 | 1523  | 
def init: Unit = server.start()  | 
| 80782 | 1524  | 
def loop_body(u: Unit): Unit =  | 
1525  | 
      if (!progress.stopped) synchronized_database("iterate") { cache.update() }
 | 
|
| 80246 | 1526  | 
}  | 
1527  | 
||
1528  | 
||
| 80344 | 1529  | 
/** context **/  | 
| 80246 | 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 | 1532  | 
def name = Build.name(task.kind, id)  | 
| 80497 | 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 = {
 | 
| 
 
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
 | 
1540  | 
if (task.build_cluster) store.open_ssh()  | 
| 
 
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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 1601  | 
ssh.close()  | 
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 | 1613  | 
}  | 
1614  | 
||
1615  | 
||
| 80344 | 1616  | 
/** build manager store **/  | 
| 80246 | 1617  | 
|
1618  | 
  case class Store(options: Options) {
 | 
|
1619  | 
    val base_dir = Path.explode(options.string("build_manager_dir"))
 | 
|
1620  | 
    val identifier = options.string("build_manager_identifier")
 | 
|
| 80348 | 1621  | 
    val address = Url(options.string("build_manager_address"))
 | 
| 80246 | 1622  | 
|
| 80336 | 1623  | 
    val pending = base_dir + Path.basic("pending")
 | 
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 | 1627  | 
def report(kind: String, id: Long): Report =  | 
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 | 1638  | 
    val ssh_group: String = options.string("build_manager_ssh_group")
 | 
| 80246 | 1639  | 
|
1640  | 
def open_ssh(): SSH.Session =  | 
|
1641  | 
SSH.open_session(options,  | 
|
1642  | 
        host = options.string("build_manager_ssh_host"),
 | 
|
1643  | 
        port = options.int("build_manager_ssh_port"),
 | 
|
1644  | 
        user = options.string("build_manager_ssh_user"))
 | 
|
1645  | 
||
1646  | 
def open_database(server: SSH.Server = SSH.no_server): PostgreSQL.Database =  | 
|
1647  | 
PostgreSQL.open_database_server(options, server = server,  | 
|
1648  | 
        user = options.string("build_manager_database_user"),
 | 
|
1649  | 
        password = options.string("build_manager_database_password"),
 | 
|
1650  | 
        database = options.string("build_manager_database_name"),
 | 
|
1651  | 
        host = options.string("build_manager_database_host"),
 | 
|
1652  | 
        port = options.int("build_manager_database_port"),
 | 
|
1653  | 
        ssh_host = options.string("build_manager_database_ssh_host"),
 | 
|
1654  | 
        ssh_port = options.int("build_manager_database_ssh_port"),
 | 
|
1655  | 
        ssh_user = options.string("build_manager_database_ssh_user"))
 | 
|
1656  | 
||
1657  | 
def open_postgresql_server(): SSH.Server =  | 
|
1658  | 
PostgreSQL.open_server(options,  | 
|
1659  | 
        host = options.string("build_manager_database_host"),
 | 
|
1660  | 
        port = options.int("build_manager_database_port"),
 | 
|
1661  | 
        ssh_host = options.string("build_manager_ssh_host"),
 | 
|
1662  | 
        ssh_port = options.int("build_manager_ssh_port"),
 | 
|
1663  | 
        ssh_user = options.string("build_manager_ssh_user"))
 | 
|
1664  | 
}  | 
|
1665  | 
||
1666  | 
||
| 80344 | 1667  | 
/** build manager server **/  | 
1668  | 
||
| 80246 | 1669  | 
/* build manager */  | 
1670  | 
||
1671  | 
def build_manager(  | 
|
1672  | 
build_hosts: List[Build_Cluster.Host],  | 
|
1673  | 
options: Options,  | 
|
1674  | 
port: Int,  | 
|
1675  | 
sync_dirs: List[Sync.Dir] = Nil,  | 
|
1676  | 
progress: Progress = new Progress  | 
|
1677  | 
  ): Unit = {
 | 
|
1678  | 
val store = Store(options)  | 
|
1679  | 
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
 | 
1680  | 
    val ci_jobs = space_explode(',', options.string("build_manager_ci_jobs")).map(Build_CI.the_job)
 | 
| 80246 | 1681  | 
|
| 80349 | 1682  | 
progress.echo_if(ci_jobs.nonEmpty, "Managing ci jobs: " + commas_quote(ci_jobs.map(_.name)))  | 
| 80246 | 1683  | 
|
1684  | 
using(store.open_database())(db =>  | 
|
1685  | 
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
 | 
1686  | 
        create = true, label = "Build_Manager.build_manager") { store.init_dirs() })
 | 
| 80246 | 1687  | 
|
1688  | 
val processes = List(  | 
|
1689  | 
new Runner(store, build_hosts, isabelle_repository, sync_dirs, progress),  | 
|
1690  | 
new Poller(ci_jobs, store, isabelle_repository, sync_dirs, progress),  | 
|
| 80647 | 1691  | 
new Timer(ci_jobs, store, progress),  | 
| 
80649
 
f5ae78dd49d1
build_manager: display more info;
 
Fabian Huch <huch@in.tum.de> 
parents: 
80647 
diff
changeset
 | 
1692  | 
new Web_Server(port, store, build_hosts, progress))  | 
| 80246 | 1693  | 
|
1694  | 
val threads = processes.map(Isabelle_Thread.create(_))  | 
|
1695  | 
    POSIX_Interrupt.handler {
 | 
|
1696  | 
progress.stop()  | 
|
1697  | 
processes.foreach(_.interrupt())  | 
|
1698  | 
    } {
 | 
|
1699  | 
threads.foreach(_.start())  | 
|
1700  | 
threads.foreach(_.join())  | 
|
1701  | 
}  | 
|
1702  | 
}  | 
|
1703  | 
||
| 80334 | 1704  | 
|
1705  | 
/* Isabelle tool wrapper */  | 
|
1706  | 
||
1707  | 
private def show_options(relevant_options: List[String], options: Options): String =  | 
|
1708  | 
cat_lines(relevant_options.flatMap(options.get).map(_.print))  | 
|
1709  | 
||
1710  | 
private val notable_server_options =  | 
|
1711  | 
List(  | 
|
1712  | 
"build_manager_dir",  | 
|
1713  | 
"build_manager_address",  | 
|
1714  | 
"build_manager_ssh_host",  | 
|
1715  | 
"build_manager_ssh_group",  | 
|
1716  | 
"build_manager_ci_jobs")  | 
|
1717  | 
||
1718  | 
  val isabelle_tool = Isabelle_Tool("build_manager", "run build manager", Scala_Project.here,
 | 
|
1719  | 
    { args =>
 | 
|
1720  | 
var afp_root: Option[Path] = None  | 
|
1721  | 
val dirs = new mutable.ListBuffer[Path]  | 
|
1722  | 
val build_hosts = new mutable.ListBuffer[Build_Cluster.Host]  | 
|
1723  | 
var options = Options.init()  | 
|
1724  | 
var port = 8080  | 
|
1725  | 
||
1726  | 
      val getopts = Getopts("""
 | 
|
1727  | 
Usage: isabelle build_manager [OPTIONS]  | 
|
1728  | 
||
1729  | 
Options are:  | 
|
1730  | 
    -A ROOT      include AFP with given root directory (":" for """ + AFP.BASE.implode + """)
 | 
|
1731  | 
-D DIR include extra component in given directory  | 
|
1732  | 
-H HOSTS host specifications for all available hosts of the form  | 
|
1733  | 
NAMES:PARAMETERS (separated by commas)  | 
|
1734  | 
-o OPTION override Isabelle system OPTION (via NAME=VAL or NAME)  | 
|
1735  | 
-p PORT explicit web server port  | 
|
1736  | 
||
1737  | 
Run Isabelle build manager. Notable system options:  | 
|
1738  | 
||
1739  | 
""" + Library.indent_lines(2, show_options(notable_server_options, options)) + "\n",  | 
|
1740  | 
"A:" -> (arg => afp_root = Some(if (arg == ":") AFP.BASE else Path.explode(arg))),  | 
|
1741  | 
"D:" -> (arg => dirs += Path.explode(arg)),  | 
|
1742  | 
"H:" -> (arg => build_hosts ++= Build_Cluster.Host.parse(Registry.global, arg)),  | 
|
1743  | 
"o:" -> (arg => options = options + arg),  | 
|
1744  | 
"p:" -> (arg => port = Value.Int.parse(arg)))  | 
|
1745  | 
||
1746  | 
val more_args = getopts(args)  | 
|
1747  | 
if (more_args.nonEmpty) getopts.usage()  | 
|
1748  | 
||
1749  | 
val progress = new Console_Progress()  | 
|
1750  | 
val sync_dirs =  | 
|
1751  | 
Sync.afp_dirs(afp_root) ::: dirs.toList.map(dir => Sync.Dir(dir.file_name, dir))  | 
|
1752  | 
||
1753  | 
sync_dirs.foreach(_.check())  | 
|
1754  | 
||
1755  | 
build_manager(build_hosts = build_hosts.toList, options = options, port = port,  | 
|
1756  | 
sync_dirs = sync_dirs, progress = progress)  | 
|
1757  | 
})  | 
|
1758  | 
||
1759  | 
||
| 80344 | 1760  | 
/** 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
 | 
1761  | 
|
| 
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
 | 
1762  | 
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
 | 
1763  | 
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
 | 
1764  | 
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
 | 
1765  | 
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
 | 
1766  | 
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
 | 
1767  | 
  ): Unit = {
 | 
| 
80343
 
595b362ab851
add build_manager_database tool to restore db from log files;
 
Fabian Huch <huch@in.tum.de> 
parents: 
80342 
diff
changeset
 | 
1768  | 
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
 | 
1769  | 
    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
 | 
1770  | 
      db.transaction {
 | 
| 
 
595b362ab851
add build_manager_database tool to restore db from log files;
 
Fabian Huch <huch@in.tum.de> 
parents: 
80342 
diff
changeset
 | 
1771  | 
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
 | 
1772  | 
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
 | 
1773  | 
        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
 | 
1774  | 
          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
 | 
1775  | 
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
 | 
1776  | 
}  | 
| 
 
595b362ab851
add build_manager_database tool to restore db from log files;
 
Fabian Huch <huch@in.tum.de> 
parents: 
80342 
diff
changeset
 | 
1777  | 
}  | 
| 
 
595b362ab851
add build_manager_database tool to restore db from log files;
 
Fabian Huch <huch@in.tum.de> 
parents: 
80342 
diff
changeset
 | 
1778  | 
|
| 
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
 | 
1779  | 
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
 | 
1780  | 
        for {
 | 
| 
 
595b362ab851
add build_manager_database tool to restore db from log files;
 
Fabian Huch <huch@in.tum.de> 
parents: 
80342 
diff
changeset
 | 
1781  | 
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
 | 
1782  | 
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
 | 
1783  | 
id <- Value.Long.unapply(entry)  | 
| 80497 | 1784  | 
report = store.report(kind, id)  | 
1785  | 
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
 | 
1786  | 
} 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
 | 
1787  | 
|
| 
80646
 
b4e116523cb6
build_manager: store submitting user;
 
Fabian Huch <huch@in.tum.de> 
parents: 
80645 
diff
changeset
 | 
1788  | 
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
 | 
1789  | 
|
| 
 
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  | 
      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
 | 
1791  | 
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
 | 
1792  | 
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
 | 
1793  | 
          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
 | 
1794  | 
|
| 
 
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  | 
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
 | 
1796  | 
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
 | 
1797  | 
|
| 
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
 | 
1798  | 
        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
 | 
1799  | 
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
 | 
1800  | 
          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
 | 
1801  | 
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
 | 
1802  | 
              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
 | 
1803  | 
              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
 | 
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  | 
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
 | 
1806  | 
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
 | 
1807  | 
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
 | 
1808  | 
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
 | 
1809  | 
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
 | 
1810  | 
|
| 
 
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
 | 
1811  | 
(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
 | 
1812  | 
}  | 
| 
 
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
 | 
1813  | 
}  | 
| 
 
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
 | 
1814  | 
}  | 
| 
 
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
 | 
1815  | 
|
| 
 
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
 | 
1816  | 
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
 | 
1817  | 
|
| 
 
595b362ab851
add build_manager_database tool to restore db from log files;
 
Fabian Huch <huch@in.tum.de> 
parents: 
80342 
diff
changeset
 | 
1818  | 
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
 | 
1819  | 
        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
 | 
1820  | 
|
| 
 
595b362ab851
add build_manager_database tool to restore db from log files;
 
Fabian Huch <huch@in.tum.de> 
parents: 
80342 
diff
changeset
 | 
1821  | 
        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
 | 
1822  | 
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
 | 
1823  | 
}  | 
| 
 
595b362ab851
add build_manager_database tool to restore db from log files;
 
Fabian Huch <huch@in.tum.de> 
parents: 
80342 
diff
changeset
 | 
1824  | 
}  | 
| 
 
595b362ab851
add build_manager_database tool to restore db from log files;
 
Fabian Huch <huch@in.tum.de> 
parents: 
80342 
diff
changeset
 | 
1825  | 
}  | 
| 
 
595b362ab851
add build_manager_database tool to restore db from log files;
 
Fabian Huch <huch@in.tum.de> 
parents: 
80342 
diff
changeset
 | 
1826  | 
|
| 
 
595b362ab851
add build_manager_database tool to restore db from log files;
 
Fabian Huch <huch@in.tum.de> 
parents: 
80342 
diff
changeset
 | 
1827  | 
|
| 
 
595b362ab851
add build_manager_database tool to restore db from log files;
 
Fabian Huch <huch@in.tum.de> 
parents: 
80342 
diff
changeset
 | 
1828  | 
/* 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
 | 
1829  | 
|
| 
 
595b362ab851
add build_manager_database tool to restore db from log files;
 
Fabian Huch <huch@in.tum.de> 
parents: 
80342 
diff
changeset
 | 
1830  | 
  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
 | 
1831  | 
"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
 | 
1832  | 
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
 | 
1833  | 
    { 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
 | 
1834  | 
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
 | 
1835  | 
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
 | 
1836  | 
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
 | 
1837  | 
|
| 
 
595b362ab851
add build_manager_database tool to restore db from log files;
 
Fabian Huch <huch@in.tum.de> 
parents: 
80342 
diff
changeset
 | 
1838  | 
      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
 | 
1839  | 
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
 | 
1840  | 
|
| 
 
595b362ab851
add build_manager_database tool to restore db from log files;
 
Fabian Huch <huch@in.tum.de> 
parents: 
80342 
diff
changeset
 | 
1841  | 
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
 | 
1842  | 
    -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
 | 
1843  | 
-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
 | 
1844  | 
-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
 | 
1845  | 
|
| 
 
595b362ab851
add build_manager_database tool to restore db from log files;
 
Fabian Huch <huch@in.tum.de> 
parents: 
80342 
diff
changeset
 | 
1846  | 
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
 | 
1847  | 
""",  | 
| 
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
 | 
1848  | 
"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
 | 
1849  | 
"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
 | 
1850  | 
"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
 | 
1851  | 
|
| 
 
595b362ab851
add build_manager_database tool to restore db from log files;
 
Fabian Huch <huch@in.tum.de> 
parents: 
80342 
diff
changeset
 | 
1852  | 
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
 | 
1853  | 
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
 | 
1854  | 
|
| 
 
595b362ab851
add build_manager_database tool to restore db from log files;
 
Fabian Huch <huch@in.tum.de> 
parents: 
80342 
diff
changeset
 | 
1855  | 
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
 | 
1856  | 
|
| 
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
 | 
1857  | 
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
 | 
1858  | 
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
 | 
1859  | 
})  | 
| 
 
595b362ab851
add build_manager_database tool to restore db from log files;
 
Fabian Huch <huch@in.tum.de> 
parents: 
80342 
diff
changeset
 | 
1860  | 
|
| 
 
595b362ab851
add build_manager_database tool to restore db from log files;
 
Fabian Huch <huch@in.tum.de> 
parents: 
80342 
diff
changeset
 | 
1861  | 
|
| 80344 | 1862  | 
/** build manager client */  | 
1863  | 
||
| 80334 | 1864  | 
/* build task */  | 
1865  | 
||
| 80246 | 1866  | 
def build_task(  | 
1867  | 
options: Options,  | 
|
1868  | 
store: Store,  | 
|
1869  | 
afp_root: Option[Path] = None,  | 
|
1870  | 
base_sessions: List[String] = Nil,  | 
|
1871  | 
presentation: Boolean = false,  | 
|
1872  | 
requirements: Boolean = false,  | 
|
1873  | 
exclude_session_groups: List[String] = Nil,  | 
|
1874  | 
all_sessions: Boolean = false,  | 
|
1875  | 
build_heap: Boolean = false,  | 
|
1876  | 
clean_build: Boolean = false,  | 
|
1877  | 
export_files: Boolean = false,  | 
|
1878  | 
fresh_build: Boolean = false,  | 
|
1879  | 
session_groups: List[String] = Nil,  | 
|
1880  | 
sessions: List[String] = Nil,  | 
|
1881  | 
prefs: List[Options.Spec] = Nil,  | 
|
1882  | 
exclude_sessions: List[String] = Nil,  | 
|
| 
80254
 
6b3374d208b8
add verbose option to build_task;
 
Fabian Huch <huch@in.tum.de> 
parents: 
80252 
diff
changeset
 | 
1883  | 
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
 | 
1884  | 
rev: String = "",  | 
| 80246 | 1885  | 
progress: Progress = new Progress  | 
1886  | 
  ): UUID.T = {
 | 
|
| 
80337
 
02f8a35ed8e2
clarified names: more canonical;
 
Fabian Huch <huch@in.tum.de> 
parents: 
80336 
diff
changeset
 | 
1887  | 
val uuid = UUID.random()  | 
| 80246 | 1888  | 
    val afp_rev = if (afp_root.nonEmpty) Some("") else None
 | 
1889  | 
||
| 
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
 | 
1890  | 
    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
 | 
1891  | 
    val timeout = options.seconds("build_manager_timeout")
 | 
| 80348 | 1892  | 
val paths = Web_Server.paths(store)  | 
| 80338 | 1893  | 
|
| 80246 | 1894  | 
    progress.interrupt_handler {
 | 
1895  | 
      using(store.open_ssh()) { ssh =>
 | 
|
| 
80646
 
b4e116523cb6
build_manager: store submitting user;
 
Fabian Huch <huch@in.tum.de> 
parents: 
80645 
diff
changeset
 | 
1896  | 
        val user = ssh.execute("whoami").check.out
 | 
| 
 
b4e116523cb6
build_manager: store submitting user;
 
Fabian Huch <huch@in.tum.de> 
parents: 
80645 
diff
changeset
 | 
1897  | 
|
| 
 
b4e116523cb6
build_manager: store submitting user;
 
Fabian Huch <huch@in.tum.de> 
parents: 
80645 
diff
changeset
 | 
1898  | 
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
 | 
1899  | 
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
 | 
1900  | 
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
 | 
1901  | 
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
 | 
1902  | 
|
| 
 
b4e116523cb6
build_manager: store submitting user;
 
Fabian Huch <huch@in.tum.de> 
parents: 
80645 
diff
changeset
 | 
1903  | 
val dir = store.task_dir(task)  | 
| 
 
b4e116523cb6
build_manager: store submitting user;
 
Fabian Huch <huch@in.tum.de> 
parents: 
80645 
diff
changeset
 | 
1904  | 
|
| 
80252
 
96543177ab7e
build manager: manage directories/permissions, to minimize local administration;
 
Fabian Huch <huch@in.tum.de> 
parents: 
80251 
diff
changeset
 | 
1905  | 
val rsync_context = Rsync.Context(ssh = ssh)  | 
| 
80518
 
d3b96e19ccc7
tuned messages: whitespace following usual Isabelle conventions;
 
wenzelm 
parents: 
80502 
diff
changeset
 | 
1906  | 
        progress.echo("Transferring repositories ...")
 | 
| 
80280
 
7987b33fb6c5
clarified context: operations now in build process;
 
Fabian Huch <huch@in.tum.de> 
parents: 
80279 
diff
changeset
 | 
1907  | 
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
 | 
1908  | 
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
 | 
1909  | 
store.sync_permissions(dir, ssh)  | 
| 80246 | 1910  | 
|
1911  | 
        if (progress.stopped) {
 | 
|
| 
80518
 
d3b96e19ccc7
tuned messages: whitespace following usual Isabelle conventions;
 
wenzelm 
parents: 
80502 
diff
changeset
 | 
1912  | 
          progress.echo("Cancelling submission ...")
 | 
| 
80280
 
7987b33fb6c5
clarified context: operations now in build process;
 
Fabian Huch <huch@in.tum.de> 
parents: 
80279 
diff
changeset
 | 
1913  | 
ssh.rm_tree(dir)  | 
| 80246 | 1914  | 
        } else {
 | 
1915  | 
          using(store.open_postgresql_server()) { server =>
 | 
|
1916  | 
            using(store.open_database(server = server)) { db =>
 | 
|
1917  | 
              Build_Manager.private_data.transaction_lock(db, label = "Build_Manager.build_task") {
 | 
|
1918  | 
val old_state = Build_Manager.private_data.pull_state(db, State())  | 
|
1919  | 
val state = old_state.add_pending(task)  | 
|
1920  | 
Build_Manager.private_data.push_state(db, old_state, state)  | 
|
1921  | 
}  | 
|
1922  | 
}  | 
|
1923  | 
}  | 
|
| 80338 | 1924  | 
|
1925  | 
val address = paths.frontend_url(Web_Server.Page.BUILD, Web_Server.Id(task.uuid.toString))  | 
|
| 80246 | 1926  | 
          progress.echo("Submitted task. Private url: " + address)
 | 
1927  | 
}  | 
|
1928  | 
}  | 
|
1929  | 
}  | 
|
1930  | 
||
| 
80337
 
02f8a35ed8e2
clarified names: more canonical;
 
Fabian Huch <huch@in.tum.de> 
parents: 
80336 
diff
changeset
 | 
1931  | 
uuid  | 
| 80246 | 1932  | 
}  | 
1933  | 
||
1934  | 
||
1935  | 
/* Isabelle tool wrapper */  | 
|
1936  | 
||
| 
80252
 
96543177ab7e
build manager: manage directories/permissions, to minimize local administration;
 
Fabian Huch <huch@in.tum.de> 
parents: 
80251 
diff
changeset
 | 
1937  | 
  val notable_client_options = List("build_manager_ssh_user", "build_manager_ssh_group")
 | 
| 
 
96543177ab7e
build manager: manage directories/permissions, to minimize local administration;
 
Fabian Huch <huch@in.tum.de> 
parents: 
80251 
diff
changeset
 | 
1938  | 
|
| 
80343
 
595b362ab851
add build_manager_database tool to restore db from log files;
 
Fabian Huch <huch@in.tum.de> 
parents: 
80342 
diff
changeset
 | 
1939  | 
  val isabelle_tool2 = Isabelle_Tool("build_task", "submit build task for build manager",
 | 
| 80246 | 1940  | 
Scala_Project.here,  | 
1941  | 
    { args =>
 | 
|
1942  | 
var afp_root: Option[Path] = None  | 
|
1943  | 
val base_sessions = new mutable.ListBuffer[String]  | 
|
1944  | 
var presentation = false  | 
|
1945  | 
var requirements = false  | 
|
1946  | 
val exclude_session_groups = new mutable.ListBuffer[String]  | 
|
1947  | 
var all_sessions = false  | 
|
1948  | 
var build_heap = false  | 
|
1949  | 
var clean_build = false  | 
|
1950  | 
var export_files = false  | 
|
1951  | 
var fresh_build = false  | 
|
1952  | 
val session_groups = new mutable.ListBuffer[String]  | 
|
1953  | 
var options = Options.init(specs = Options.Spec.ISABELLE_BUILD_OPTIONS)  | 
|
| 80423 | 1954  | 
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
 | 
1955  | 
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
 | 
1956  | 
var rev = ""  | 
| 80246 | 1957  | 
val exclude_sessions = new mutable.ListBuffer[String]  | 
1958  | 
||
1959  | 
      val getopts = Getopts("""
 | 
|
1960  | 
Usage: isabelle build_task [OPTIONS] [SESSIONS ...]  | 
|
1961  | 
||
1962  | 
Options are:  | 
|
1963  | 
    -A ROOT      include AFP with given root directory (":" for """ + AFP.BASE.implode + """)
 | 
|
1964  | 
-B NAME include session NAME and all descendants  | 
|
1965  | 
-P enable HTML/PDF presentation  | 
|
1966  | 
-R refer to requirements of selected sessions  | 
|
1967  | 
-X NAME exclude sessions from group NAME and all descendants  | 
|
1968  | 
-a select all sessions  | 
|
1969  | 
-b build heap images  | 
|
1970  | 
-c clean build  | 
|
1971  | 
-e export files from session specification into file-system  | 
|
1972  | 
-f fresh build  | 
|
1973  | 
-g NAME select session group NAME  | 
|
1974  | 
-o OPTION override Isabelle system OPTION (via NAME=VAL or NAME)  | 
|
| 80423 | 1975  | 
-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
 | 
1976  | 
-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
 | 
1977  | 
-v verbose  | 
| 80246 | 1978  | 
-x NAME exclude session NAME and all descendants  | 
1979  | 
||
1980  | 
Submit build task on SSH server. Notable system options:  | 
|
1981  | 
||
| 
80252
 
96543177ab7e
build manager: manage directories/permissions, to minimize local administration;
 
Fabian Huch <huch@in.tum.de> 
parents: 
80251 
diff
changeset
 | 
1982  | 
""" + Library.indent_lines(2, show_options(notable_client_options, options)) + "\n",  | 
| 80246 | 1983  | 
"A:" -> (arg => afp_root = Some(if (arg == ":") AFP.BASE else Path.explode(arg))),  | 
1984  | 
"B:" -> (arg => base_sessions += arg),  | 
|
1985  | 
"P" -> (_ => presentation = true),  | 
|
1986  | 
"R" -> (_ => requirements = true),  | 
|
1987  | 
"X:" -> (arg => exclude_session_groups += arg),  | 
|
1988  | 
"a" -> (_ => all_sessions = true),  | 
|
1989  | 
"b" -> (_ => build_heap = true),  | 
|
1990  | 
"c" -> (_ => clean_build = true),  | 
|
1991  | 
"e" -> (_ => export_files = true),  | 
|
1992  | 
"f" -> (_ => fresh_build = true),  | 
|
1993  | 
"g:" -> (arg => session_groups += arg),  | 
|
1994  | 
"o:" -> (arg => options = options + arg),  | 
|
| 80423 | 1995  | 
"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
 | 
1996  | 
"r:" -> (arg => rev = arg),  | 
| 
80254
 
6b3374d208b8
add verbose option to build_task;
 
Fabian Huch <huch@in.tum.de> 
parents: 
80252 
diff
changeset
 | 
1997  | 
"v" -> (_ => verbose = true),  | 
| 80246 | 1998  | 
"x:" -> (arg => exclude_sessions += arg))  | 
1999  | 
||
2000  | 
val sessions = getopts(args)  | 
|
2001  | 
val store = Store(options)  | 
|
2002  | 
val progress = new Console_Progress()  | 
|
2003  | 
||
| 80470 | 2004  | 
build_task(options, store, afp_root = afp_root, base_sessions = base_sessions.toList,  | 
2005  | 
presentation = presentation, requirements = requirements, exclude_session_groups =  | 
|
2006  | 
exclude_session_groups.toList, all_sessions = all_sessions, build_heap = build_heap,  | 
|
2007  | 
clean_build = clean_build, export_files = export_files, fresh_build = fresh_build,  | 
|
2008  | 
session_groups = session_groups.toList, sessions = sessions, prefs = prefs.toList, verbose =  | 
|
2009  | 
verbose, rev = rev, exclude_sessions = exclude_sessions.toList, progress = progress)  | 
|
| 80246 | 2010  | 
})  | 
2011  | 
}  |