| author | immler | 
| Thu, 27 Dec 2018 21:00:50 +0100 | |
| changeset 69510 | 0f31dd2e540d | 
| parent 69432 | d072f3287ffa | 
| child 69693 | 06153e2e0cdb | 
| permissions | -rw-r--r-- | 
| 64148 | 1  | 
/* Title: Pure/Admin/isabelle_cronjob.scala  | 
2  | 
Author: Makarius  | 
|
3  | 
||
4  | 
Main entry point for administrative cronjob at TUM.  | 
|
5  | 
*/  | 
|
6  | 
||
7  | 
package isabelle  | 
|
8  | 
||
9  | 
||
| 
67854
 
8374c80165e1
publish current log file, e.g. for easy error detection;
 
wenzelm 
parents: 
67775 
diff
changeset
 | 
10  | 
import java.nio.file.Files  | 
| 
 
8374c80165e1
publish current log file, e.g. for easy error detection;
 
wenzelm 
parents: 
67775 
diff
changeset
 | 
11  | 
|
| 64170 | 12  | 
import scala.annotation.tailrec  | 
13  | 
import scala.collection.mutable  | 
|
14  | 
||
15  | 
||
| 64148 | 16  | 
object Isabelle_Cronjob  | 
17  | 
{
 | 
|
| 66897 | 18  | 
/* global resources: owned by main cronjob */  | 
| 
64153
 
769791954872
some timing and logging, similar to old isatest.log;
 
wenzelm 
parents: 
64148 
diff
changeset
 | 
19  | 
|
| 
67766
 
603334230303
consolidated main cronjob server on virtual machine together with build_log database;
 
wenzelm 
parents: 
67763 
diff
changeset
 | 
20  | 
val backup = "lxbroy10:cronjob"  | 
| 
64153
 
769791954872
some timing and logging, similar to old isatest.log;
 
wenzelm 
parents: 
64148 
diff
changeset
 | 
21  | 
  val main_dir = Path.explode("~/cronjob")
 | 
| 
64194
 
b5ada7dcceaa
integrity test of build_history vs. build_history_base;
 
wenzelm 
parents: 
64193 
diff
changeset
 | 
22  | 
  val main_state_file = main_dir + Path.explode("run/main.state")
 | 
| 64219 | 23  | 
  val current_log = main_dir + Path.explode("run/main.log")  // owned by log service
 | 
24  | 
  val cumulative_log = main_dir + Path.explode("log/main.log")  // owned by log service
 | 
|
| 
64153
 
769791954872
some timing and logging, similar to old isatest.log;
 
wenzelm 
parents: 
64148 
diff
changeset
 | 
25  | 
|
| 
68650
 
7538b5f301ea
evade odd connection problems to https://isabelle.in.tum.de from some remote hosts;
 
wenzelm 
parents: 
68530 
diff
changeset
 | 
26  | 
val isabelle_repos_source = "https://isabelle.sketis.net/repos/isabelle"  | 
| 
64231
 
dbc8294c75d3
added remote_build_history tasks: parallel on several remote hosts;
 
wenzelm 
parents: 
64220 
diff
changeset
 | 
27  | 
  val isabelle_repos = main_dir + Path.explode("isabelle")
 | 
| 
 
dbc8294c75d3
added remote_build_history tasks: parallel on several remote hosts;
 
wenzelm 
parents: 
64220 
diff
changeset
 | 
28  | 
  val afp_repos = main_dir + Path.explode("AFP")
 | 
| 
64236
 
358f9ff08681
discontinued somewhat pointless cronjob.options -- compile-time constants are sufficient;
 
wenzelm 
parents: 
64235 
diff
changeset
 | 
29  | 
|
| 66896 | 30  | 
val build_log_dirs =  | 
31  | 
    List(Path.explode("~/log"), Path.explode("~/afp/log"), Path.explode("~/cronjob/log"))
 | 
|
32  | 
||
| 
64153
 
769791954872
some timing and logging, similar to old isatest.log;
 
wenzelm 
parents: 
64148 
diff
changeset
 | 
33  | 
|
| 64192 | 34  | 
|
| 
67752
 
636f633552a3
clarified signature: facilitate interactive experimentation;
 
wenzelm 
parents: 
67751 
diff
changeset
 | 
35  | 
/** logger tasks **/  | 
| 
 
636f633552a3
clarified signature: facilitate interactive experimentation;
 
wenzelm 
parents: 
67751 
diff
changeset
 | 
36  | 
|
| 
 
636f633552a3
clarified signature: facilitate interactive experimentation;
 
wenzelm 
parents: 
67751 
diff
changeset
 | 
37  | 
sealed case class Logger_Task(name: String = "", body: Logger => Unit)  | 
| 
 
636f633552a3
clarified signature: facilitate interactive experimentation;
 
wenzelm 
parents: 
67751 
diff
changeset
 | 
38  | 
|
| 64192 | 39  | 
|
| 
67766
 
603334230303
consolidated main cronjob server on virtual machine together with build_log database;
 
wenzelm 
parents: 
67763 
diff
changeset
 | 
40  | 
/* init and exit */  | 
| 64192 | 41  | 
|
| 
67753
 
f28aee3ad1e6
uniform setup_repository (pull/clone without update);
 
wenzelm 
parents: 
67752 
diff
changeset
 | 
42  | 
def get_rev(): String = Mercurial.repository(isabelle_repos).id()  | 
| 
 
f28aee3ad1e6
uniform setup_repository (pull/clone without update);
 
wenzelm 
parents: 
67752 
diff
changeset
 | 
43  | 
def get_afp_rev(): String = Mercurial.repository(afp_repos).id()  | 
| 
 
f28aee3ad1e6
uniform setup_repository (pull/clone without update);
 
wenzelm 
parents: 
67752 
diff
changeset
 | 
44  | 
|
| 
67752
 
636f633552a3
clarified signature: facilitate interactive experimentation;
 
wenzelm 
parents: 
67751 
diff
changeset
 | 
45  | 
val init =  | 
| 67751 | 46  | 
    Logger_Task("init", logger =>
 | 
| 66859 | 47  | 
      {
 | 
48  | 
Isabelle_Devel.make_index()  | 
|
| 65771 | 49  | 
|
| 
67753
 
f28aee3ad1e6
uniform setup_repository (pull/clone without update);
 
wenzelm 
parents: 
67752 
diff
changeset
 | 
50  | 
Mercurial.setup_repository(isabelle_repos_source, isabelle_repos)  | 
| 
 
f28aee3ad1e6
uniform setup_repository (pull/clone without update);
 
wenzelm 
parents: 
67752 
diff
changeset
 | 
51  | 
Mercurial.setup_repository(AFP.repos_source, afp_repos)  | 
| 64192 | 52  | 
|
| 66859 | 53  | 
        File.write(logger.log_dir + Build_Log.log_filename("isabelle_identify", logger.start_date),
 | 
| 
67753
 
f28aee3ad1e6
uniform setup_repository (pull/clone without update);
 
wenzelm 
parents: 
67752 
diff
changeset
 | 
54  | 
Build_Log.Identify.content(logger.start_date, Some(get_rev()), Some(get_afp_rev())))  | 
| 
67766
 
603334230303
consolidated main cronjob server on virtual machine together with build_log database;
 
wenzelm 
parents: 
67763 
diff
changeset
 | 
55  | 
|
| 
 
603334230303
consolidated main cronjob server on virtual machine together with build_log database;
 
wenzelm 
parents: 
67763 
diff
changeset
 | 
56  | 
Isabelle_System.bash(  | 
| 
 
603334230303
consolidated main cronjob server on virtual machine together with build_log database;
 
wenzelm 
parents: 
67763 
diff
changeset
 | 
57  | 
"""rsync -a --include="*/" --include="plain_identify*" --exclude="*" """ +  | 
| 69199 | 58  | 
Bash.string(backup + "/log/.") + " " + File.bash_path(main_dir) + "/log/.").check  | 
| 
67854
 
8374c80165e1
publish current log file, e.g. for easy error detection;
 
wenzelm 
parents: 
67775 
diff
changeset
 | 
59  | 
|
| 
 
8374c80165e1
publish current log file, e.g. for easy error detection;
 
wenzelm 
parents: 
67775 
diff
changeset
 | 
60  | 
if (!Isabelle_Devel.cronjob_log.is_file)  | 
| 
 
8374c80165e1
publish current log file, e.g. for easy error detection;
 
wenzelm 
parents: 
67775 
diff
changeset
 | 
61  | 
Files.createSymbolicLink(Isabelle_Devel.cronjob_log.file.toPath, current_log.file.toPath)  | 
| 
67766
 
603334230303
consolidated main cronjob server on virtual machine together with build_log database;
 
wenzelm 
parents: 
67763 
diff
changeset
 | 
62  | 
})  | 
| 
 
603334230303
consolidated main cronjob server on virtual machine together with build_log database;
 
wenzelm 
parents: 
67763 
diff
changeset
 | 
63  | 
|
| 
 
603334230303
consolidated main cronjob server on virtual machine together with build_log database;
 
wenzelm 
parents: 
67763 
diff
changeset
 | 
64  | 
val exit =  | 
| 
 
603334230303
consolidated main cronjob server on virtual machine together with build_log database;
 
wenzelm 
parents: 
67763 
diff
changeset
 | 
65  | 
    Logger_Task("exit", logger =>
 | 
| 
 
603334230303
consolidated main cronjob server on virtual machine together with build_log database;
 
wenzelm 
parents: 
67763 
diff
changeset
 | 
66  | 
      {
 | 
| 
 
603334230303
consolidated main cronjob server on virtual machine together with build_log database;
 
wenzelm 
parents: 
67763 
diff
changeset
 | 
67  | 
Isabelle_System.bash(  | 
| 69199 | 68  | 
"rsync -a " + File.bash_path(main_dir) + "/log/." + " " + Bash.string(backup) + "/log/.")  | 
| 67769 | 69  | 
.check  | 
| 67751 | 70  | 
})  | 
71  | 
||
72  | 
||
73  | 
/* build release */  | 
|
74  | 
||
| 
67752
 
636f633552a3
clarified signature: facilitate interactive experimentation;
 
wenzelm 
parents: 
67751 
diff
changeset
 | 
75  | 
val build_release =  | 
| 67751 | 76  | 
    Logger_Task("build_release", logger =>
 | 
77  | 
      {
 | 
|
| 
69432
 
d072f3287ffa
discontinued somewhat point dmg: plain .tar.gz is smaller and more convenient to install;
 
wenzelm 
parents: 
69401 
diff
changeset
 | 
78  | 
Isabelle_Devel.release_snapshot(logger.options, rev = get_rev(), afp_rev = get_afp_rev())  | 
| 66859 | 79  | 
})  | 
| 64192 | 80  | 
|
81  | 
||
| 
64194
 
b5ada7dcceaa
integrity test of build_history vs. build_history_base;
 
wenzelm 
parents: 
64193 
diff
changeset
 | 
82  | 
/* integrity test of build_history vs. build_history_base */  | 
| 64193 | 83  | 
|
| 
67752
 
636f633552a3
clarified signature: facilitate interactive experimentation;
 
wenzelm 
parents: 
67751 
diff
changeset
 | 
84  | 
val build_history_base =  | 
| 64193 | 85  | 
    Logger_Task("build_history_base", logger =>
 | 
86  | 
      {
 | 
|
| 
67774
 
5437491732d2
build_history_base as remote build on lxbroy10: thus self_update has already happened once, and thus avoids conflicts with parallel builds on shared home directory;
 
wenzelm 
parents: 
67772 
diff
changeset
 | 
87  | 
        using(logger.ssh_context.open_session("lxbroy10"))(ssh =>
 | 
| 
 
5437491732d2
build_history_base as remote build on lxbroy10: thus self_update has already happened once, and thus avoids conflicts with parallel builds on shared home directory;
 
wenzelm 
parents: 
67772 
diff
changeset
 | 
88  | 
          {
 | 
| 
 
5437491732d2
build_history_base as remote build on lxbroy10: thus self_update has already happened once, and thus avoids conflicts with parallel builds on shared home directory;
 
wenzelm 
parents: 
67772 
diff
changeset
 | 
89  | 
val results =  | 
| 
 
5437491732d2
build_history_base as remote build on lxbroy10: thus self_update has already happened once, and thus avoids conflicts with parallel builds on shared home directory;
 
wenzelm 
parents: 
67772 
diff
changeset
 | 
90  | 
Build_History.remote_build_history(ssh,  | 
| 
 
5437491732d2
build_history_base as remote build on lxbroy10: thus self_update has already happened once, and thus avoids conflicts with parallel builds on shared home directory;
 
wenzelm 
parents: 
67772 
diff
changeset
 | 
91  | 
isabelle_repos,  | 
| 
 
5437491732d2
build_history_base as remote build on lxbroy10: thus self_update has already happened once, and thus avoids conflicts with parallel builds on shared home directory;
 
wenzelm 
parents: 
67772 
diff
changeset
 | 
92  | 
                isabelle_repos.ext("build_history_base"),
 | 
| 
 
5437491732d2
build_history_base as remote build on lxbroy10: thus self_update has already happened once, and thus avoids conflicts with parallel builds on shared home directory;
 
wenzelm 
parents: 
67772 
diff
changeset
 | 
93  | 
isabelle_identifier = "cronjob_build_history",  | 
| 
 
5437491732d2
build_history_base as remote build on lxbroy10: thus self_update has already happened once, and thus avoids conflicts with parallel builds on shared home directory;
 
wenzelm 
parents: 
67772 
diff
changeset
 | 
94  | 
self_update = true,  | 
| 
 
5437491732d2
build_history_base as remote build on lxbroy10: thus self_update has already happened once, and thus avoids conflicts with parallel builds on shared home directory;
 
wenzelm 
parents: 
67772 
diff
changeset
 | 
95  | 
rev = "build_history_base",  | 
| 
 
5437491732d2
build_history_base as remote build on lxbroy10: thus self_update has already happened once, and thus avoids conflicts with parallel builds on shared home directory;
 
wenzelm 
parents: 
67772 
diff
changeset
 | 
96  | 
options = "-f",  | 
| 
 
5437491732d2
build_history_base as remote build on lxbroy10: thus self_update has already happened once, and thus avoids conflicts with parallel builds on shared home directory;
 
wenzelm 
parents: 
67772 
diff
changeset
 | 
97  | 
args = "HOL")  | 
| 
 
5437491732d2
build_history_base as remote build on lxbroy10: thus self_update has already happened once, and thus avoids conflicts with parallel builds on shared home directory;
 
wenzelm 
parents: 
67772 
diff
changeset
 | 
98  | 
|
| 
 
5437491732d2
build_history_base as remote build on lxbroy10: thus self_update has already happened once, and thus avoids conflicts with parallel builds on shared home directory;
 
wenzelm 
parents: 
67772 
diff
changeset
 | 
99  | 
            for ((log_name, bytes) <- results) {
 | 
| 
 
5437491732d2
build_history_base as remote build on lxbroy10: thus self_update has already happened once, and thus avoids conflicts with parallel builds on shared home directory;
 
wenzelm 
parents: 
67772 
diff
changeset
 | 
100  | 
Bytes.write(logger.log_dir + Path.explode(log_name), bytes)  | 
| 
 
5437491732d2
build_history_base as remote build on lxbroy10: thus self_update has already happened once, and thus avoids conflicts with parallel builds on shared home directory;
 
wenzelm 
parents: 
67772 
diff
changeset
 | 
101  | 
}  | 
| 
 
5437491732d2
build_history_base as remote build on lxbroy10: thus self_update has already happened once, and thus avoids conflicts with parallel builds on shared home directory;
 
wenzelm 
parents: 
67772 
diff
changeset
 | 
102  | 
})  | 
| 64193 | 103  | 
})  | 
104  | 
||
105  | 
||
| 
64231
 
dbc8294c75d3
added remote_build_history tasks: parallel on several remote hosts;
 
wenzelm 
parents: 
64220 
diff
changeset
 | 
106  | 
/* remote build_history */  | 
| 
 
dbc8294c75d3
added remote_build_history tasks: parallel on several remote hosts;
 
wenzelm 
parents: 
64220 
diff
changeset
 | 
107  | 
|
| 66864 | 108  | 
sealed case class Item(  | 
109  | 
known: Boolean,  | 
|
110  | 
isabelle_version: String,  | 
|
111  | 
afp_version: Option[String],  | 
|
112  | 
pull_date: Date)  | 
|
| 
65783
 
d3d5cb2d6866
pick isabelle_version based on build_log database;
 
wenzelm 
parents: 
65771 
diff
changeset
 | 
113  | 
  {
 | 
| 
 
d3d5cb2d6866
pick isabelle_version based on build_log database;
 
wenzelm 
parents: 
65771 
diff
changeset
 | 
114  | 
def unknown: Boolean = !known  | 
| 66864 | 115  | 
def versions: (String, Option[String]) = (isabelle_version, afp_version)  | 
116  | 
||
117  | 
def known_versions(rev: String, afp_rev: Option[String]): Boolean =  | 
|
118  | 
known && rev != "" && isabelle_version == rev &&  | 
|
119  | 
(afp_rev.isEmpty || afp_rev.get != "" && afp_version == afp_rev.get)  | 
|
| 
65783
 
d3d5cb2d6866
pick isabelle_version based on build_log database;
 
wenzelm 
parents: 
65771 
diff
changeset
 | 
120  | 
}  | 
| 
 
d3d5cb2d6866
pick isabelle_version based on build_log database;
 
wenzelm 
parents: 
65771 
diff
changeset
 | 
121  | 
|
| 66864 | 122  | 
def recent_items(db: SQL.Database,  | 
123  | 
days: Int, rev: String, afp_rev: Option[String], sql: SQL.Source): List[Item] =  | 
|
| 65807 | 124  | 
  {
 | 
| 
66880
 
486f4af28db9
more thorough treatment of afp_version and afp_pull_date;
 
wenzelm 
parents: 
66879 
diff
changeset
 | 
125  | 
val afp = afp_rev.isDefined  | 
| 65807 | 126  | 
val select =  | 
| 66864 | 127  | 
Build_Log.Data.select_recent_versions(  | 
128  | 
days = days, rev = rev, afp_rev = afp_rev, sql = "WHERE " + sql)  | 
|
| 65807 | 129  | 
|
130  | 
db.using_statement(select)(stmt =>  | 
|
131  | 
stmt.execute_query().iterator(res =>  | 
|
132  | 
      {
 | 
|
133  | 
val known = res.bool(Build_Log.Data.known)  | 
|
134  | 
val isabelle_version = res.string(Build_Log.Prop.isabelle_version)  | 
|
| 
66880
 
486f4af28db9
more thorough treatment of afp_version and afp_pull_date;
 
wenzelm 
parents: 
66879 
diff
changeset
 | 
135  | 
val afp_version = if (afp) proper_string(res.string(Build_Log.Prop.afp_version)) else None  | 
| 
 
486f4af28db9
more thorough treatment of afp_version and afp_pull_date;
 
wenzelm 
parents: 
66879 
diff
changeset
 | 
136  | 
val pull_date = res.date(Build_Log.Data.pull_date(afp))  | 
| 66864 | 137  | 
Item(known, isabelle_version, afp_version, pull_date)  | 
| 65807 | 138  | 
}).toList)  | 
139  | 
}  | 
|
140  | 
||
141  | 
def unknown_runs(items: List[Item]): List[List[Item]] =  | 
|
142  | 
  {
 | 
|
143  | 
val (run, rest) = Library.take_prefix[Item](_.unknown, items.dropWhile(_.known))  | 
|
144  | 
if (run.nonEmpty) run :: unknown_runs(rest) else Nil  | 
|
145  | 
}  | 
|
146  | 
||
| 
64409
 
70c87ca55f2c
tuned signature -- more friendly for experimentation;
 
wenzelm 
parents: 
64405 
diff
changeset
 | 
147  | 
sealed case class Remote_Build(  | 
| 65764 | 148  | 
description: String,  | 
| 
64231
 
dbc8294c75d3
added remote_build_history tasks: parallel on several remote hosts;
 
wenzelm 
parents: 
64220 
diff
changeset
 | 
149  | 
host: String,  | 
| 
 
dbc8294c75d3
added remote_build_history tasks: parallel on several remote hosts;
 
wenzelm 
parents: 
64220 
diff
changeset
 | 
150  | 
user: String = "",  | 
| 65594 | 151  | 
port: Int = 0,  | 
| 67746 | 152  | 
ssh_host: String = "",  | 
| 67772 | 153  | 
ssh_permissive: Boolean = false,  | 
| 67746 | 154  | 
proxy_host: String = "",  | 
155  | 
proxy_user: String = "",  | 
|
156  | 
proxy_port: Int = 0,  | 
|
| 67775 | 157  | 
self_update: Boolean = false,  | 
| 65820 | 158  | 
historic: Boolean = false,  | 
| 65789 | 159  | 
history: Int = 0,  | 
| 65820 | 160  | 
history_base: String = "build_history_base",  | 
| 
64231
 
dbc8294c75d3
added remote_build_history tasks: parallel on several remote hosts;
 
wenzelm 
parents: 
64220 
diff
changeset
 | 
161  | 
options: String = "",  | 
| 65732 | 162  | 
args: String = "",  | 
| 66864 | 163  | 
afp: Boolean = false,  | 
| 66980 | 164  | 
slow: Boolean = false,  | 
| 
67075
 
eada9bd5fff2
avoid lxbroy7, which is presently inaccessible, but retain its build history in db queries;
 
wenzelm 
parents: 
67070 
diff
changeset
 | 
165  | 
more_hosts: List[String] = Nil,  | 
| 67080 | 166  | 
detect: SQL.Source = "",  | 
167  | 
active: Boolean = true)  | 
|
| 65732 | 168  | 
  {
 | 
| 67750 | 169  | 
def ssh_session(context: SSH.Context): SSH.Session =  | 
170  | 
context.open_session(host = proper_string(ssh_host) getOrElse host, user = user, port = port,  | 
|
| 67772 | 171  | 
proxy_host = proxy_host, proxy_user = proxy_user, proxy_port = proxy_port,  | 
172  | 
permissive = ssh_permissive)  | 
|
| 67750 | 173  | 
|
| 
65783
 
d3d5cb2d6866
pick isabelle_version based on build_log database;
 
wenzelm 
parents: 
65771 
diff
changeset
 | 
174  | 
def sql: SQL.Source =  | 
| 
 
d3d5cb2d6866
pick isabelle_version based on build_log database;
 
wenzelm 
parents: 
65771 
diff
changeset
 | 
175  | 
Build_Log.Prop.build_engine + " = " + SQL.string(Build_History.engine) + " AND " +  | 
| 
67075
 
eada9bd5fff2
avoid lxbroy7, which is presently inaccessible, but retain its build history in db queries;
 
wenzelm 
parents: 
67070 
diff
changeset
 | 
176  | 
SQL.member(Build_Log.Prop.build_host.ident, host :: more_hosts) +  | 
| 
65783
 
d3d5cb2d6866
pick isabelle_version based on build_log database;
 
wenzelm 
parents: 
65771 
diff
changeset
 | 
177  | 
(if (detect == "") "" else " AND " + SQL.enclose(detect))  | 
| 
 
d3d5cb2d6866
pick isabelle_version based on build_log database;
 
wenzelm 
parents: 
65771 
diff
changeset
 | 
178  | 
|
| 65747 | 179  | 
def profile: Build_Status.Profile =  | 
| 66980 | 180  | 
Build_Status.Profile(description, history = history, afp = afp, slow = slow, sql = sql)  | 
| 
65783
 
d3d5cb2d6866
pick isabelle_version based on build_log database;
 
wenzelm 
parents: 
65771 
diff
changeset
 | 
181  | 
|
| 66864 | 182  | 
def pick(  | 
183  | 
options: Options,  | 
|
184  | 
rev: String = "",  | 
|
| 66865 | 185  | 
filter: Item => Boolean = _ => true): Option[(String, Option[String])] =  | 
| 65747 | 186  | 
    {
 | 
| 
67753
 
f28aee3ad1e6
uniform setup_repository (pull/clone without update);
 
wenzelm 
parents: 
67752 
diff
changeset
 | 
187  | 
val afp_rev = if (afp) Some(get_afp_rev()) else None  | 
| 66864 | 188  | 
|
| 
65783
 
d3d5cb2d6866
pick isabelle_version based on build_log database;
 
wenzelm 
parents: 
65771 
diff
changeset
 | 
189  | 
val store = Build_Log.store(options)  | 
| 
 
d3d5cb2d6866
pick isabelle_version based on build_log database;
 
wenzelm 
parents: 
65771 
diff
changeset
 | 
190  | 
using(store.open_database())(db =>  | 
| 
 
d3d5cb2d6866
pick isabelle_version based on build_log database;
 
wenzelm 
parents: 
65771 
diff
changeset
 | 
191  | 
      {
 | 
| 66864 | 192  | 
def pick_days(days: Int, gap: Int): Option[(String, Option[String])] =  | 
| 65810 | 193  | 
        {
 | 
| 66865 | 194  | 
val items = recent_items(db, days, rev, afp_rev, sql).filter(filter)  | 
| 66007 | 195  | 
def runs = unknown_runs(items).filter(run => run.length >= gap)  | 
| 
65783
 
d3d5cb2d6866
pick isabelle_version based on build_log database;
 
wenzelm 
parents: 
65771 
diff
changeset
 | 
196  | 
|
| 66864 | 197  | 
          if (historic || items.exists(_.known_versions(rev, afp_rev))) {
 | 
| 65810 | 198  | 
val longest_run =  | 
199  | 
              (List.empty[Item] /: runs)({ case (item1, item2) =>
 | 
|
200  | 
if (item1.length >= item2.length) item1 else item2  | 
|
201  | 
})  | 
|
202  | 
if (longest_run.isEmpty) None  | 
|
| 66864 | 203  | 
else Some(longest_run(longest_run.length / 2).versions)  | 
| 65810 | 204  | 
}  | 
| 66864 | 205  | 
else if (rev != "") Some((rev, afp_rev))  | 
206  | 
else runs.flatten.headOption.map(_.versions)  | 
|
| 
65783
 
d3d5cb2d6866
pick isabelle_version based on build_log database;
 
wenzelm 
parents: 
65771 
diff
changeset
 | 
207  | 
}  | 
| 65810 | 208  | 
|
| 66007 | 209  | 
        pick_days(options.int("build_log_history") max history, 2) orElse
 | 
210  | 
pick_days(200, 5) orElse  | 
|
211  | 
pick_days(2000, 1)  | 
|
| 
65783
 
d3d5cb2d6866
pick isabelle_version based on build_log database;
 
wenzelm 
parents: 
65771 
diff
changeset
 | 
212  | 
})  | 
| 65747 | 213  | 
}  | 
| 65732 | 214  | 
}  | 
| 
64231
 
dbc8294c75d3
added remote_build_history tasks: parallel on several remote hosts;
 
wenzelm 
parents: 
64220 
diff
changeset
 | 
215  | 
|
| 65806 | 216  | 
val remote_builds_old: List[Remote_Build] =  | 
217  | 
List(  | 
|
| 67608 | 218  | 
      Remote_Build("AFP", "lxbroy7",
 | 
219  | 
args = "-N -X slow",  | 
|
220  | 
afp = true,  | 
|
221  | 
          detect = Build_Log.Prop.build_tags + " = " + SQL.string("AFP")),
 | 
|
| 66762 | 222  | 
      Remote_Build("Poly/ML 5.7 Linux", "lxbroy8",
 | 
223  | 
history_base = "37074e22e8be",  | 
|
224  | 
options = "-m32 -B -M1x2,2 -t polyml-5.7 -i 'init_component /home/isabelle/contrib/polyml-5.7'",  | 
|
225  | 
args = "-N -g timing",  | 
|
226  | 
        detect = Build_Log.Prop.build_tags + " = " + SQL.string("polyml-5.7") + " AND " +
 | 
|
227  | 
          Build_Log.Settings.ML_OPTIONS + " <> " + SQL.string("-H 500")),
 | 
|
| 66931 | 228  | 
      Remote_Build("Poly/ML 5.7.1 Linux", "lxbroy8",
 | 
229  | 
history_base = "a9d5b59c3e12",  | 
|
230  | 
options = "-m32 -B -M1x2,2 -t polyml-5.7.1-pre2 -i 'init_component /home/isabelle/contrib/polyml-test-905dae2ebfda'",  | 
|
231  | 
args = "-N -g timing",  | 
|
232  | 
detect =  | 
|
233  | 
          Build_Log.Prop.build_tags + " = " + SQL.string("polyml-5.7.1-pre1") + " OR " +
 | 
|
234  | 
          Build_Log.Prop.build_tags + " = " + SQL.string("polyml-5.7.1-pre2")),
 | 
|
| 66762 | 235  | 
      Remote_Build("Poly/ML 5.7 Mac OS X", "macbroy2",
 | 
236  | 
history_base = "37074e22e8be",  | 
|
237  | 
options = "-m32 -B -M1x4,4 -t polyml-5.7 -i 'init_component /home/isabelle/contrib/polyml-5.7'",  | 
|
238  | 
args = "-a",  | 
|
239  | 
        detect = Build_Log.Prop.build_tags + " = " + SQL.string("polyml-5.7")),
 | 
|
| 66931 | 240  | 
      Remote_Build("Poly/ML 5.7.1 Mac OS X", "macbroy2",
 | 
241  | 
history_base = "a9d5b59c3e12",  | 
|
242  | 
options = "-m32 -B -M1x4,4 -t polyml-5.7.1-pre2 -i 'init_component /home/isabelle/contrib/polyml-test-905dae2ebfda'",  | 
|
243  | 
args = "-a",  | 
|
244  | 
detect =  | 
|
245  | 
        Build_Log.Prop.build_tags + " = " + SQL.string("polyml-5.7.1-pre1") + " OR " +
 | 
|
246  | 
        Build_Log.Prop.build_tags + " = " + SQL.string("polyml-5.7.1-pre2")),
 | 
|
| 65806 | 247  | 
      Remote_Build("Poly/ML test", "lxbroy8",
 | 
| 
65843
 
d547173212d2
proper init_settings for init_component (before generated ML_OPTIONS etc.);
 
wenzelm 
parents: 
65840 
diff
changeset
 | 
248  | 
options = "-m32 -B -M1x2,2 -t polyml-test -i 'init_component /home/isabelle/contrib/polyml-5.7-20170217'",  | 
| 65806 | 249  | 
args = "-N -g timing",  | 
250  | 
        detect = Build_Log.Prop.build_tags + " = " + SQL.string("polyml-test")),
 | 
|
251  | 
      Remote_Build("Mac OS X 10.8 Mountain Lion", "macbroy30", options = "-m32 -M2", args = "-a",
 | 
|
252  | 
detect = Build_Log.Prop.build_start + " < date '2017-03-03'"))  | 
|
253  | 
||
| 
66898
 
8b7c4679c05b
parallel remote_builds2 for the sake of "AFP slow" (with theoretical data race on build_log_dirs);
 
wenzelm 
parents: 
66897 
diff
changeset
 | 
254  | 
val remote_builds1: List[List[Remote_Build]] =  | 
| 65732 | 255  | 
  {
 | 
| 
64231
 
dbc8294c75d3
added remote_build_history tasks: parallel on several remote hosts;
 
wenzelm 
parents: 
64220 
diff
changeset
 | 
256  | 
List(  | 
| 65764 | 257  | 
      List(Remote_Build("Linux A", "lxbroy9",
 | 
| 65732 | 258  | 
options = "-m32 -B -M1x2,2", args = "-N -g timing")),  | 
| 65820 | 259  | 
      List(Remote_Build("Linux B", "lxbroy10", historic = true, history = 90,
 | 
| 65732 | 260  | 
options = "-m32 -B -M1x4,2,4,6", args = "-N -g timing")),  | 
| 
68384
 
4a3fc3420747
full benchmarks, including all conditional theories;
 
wenzelm 
parents: 
68209 
diff
changeset
 | 
261  | 
      List(Remote_Build("Linux Benchmarks", "lxbroy5", historic = true, history = 90,
 | 
| 68385 | 262  | 
options = "-m32 -B -M1x2,2 -t Benchmarks" +  | 
| 
68384
 
4a3fc3420747
full benchmarks, including all conditional theories;
 
wenzelm 
parents: 
68209 
diff
changeset
 | 
263  | 
" -e ISABELLE_GHC=ghc -e ISABELLE_MLTON=mlton -e ISABELLE_OCAML=ocaml" +  | 
| 
 
4a3fc3420747
full benchmarks, including all conditional theories;
 
wenzelm 
parents: 
68209 
diff
changeset
 | 
264  | 
" -e ISABELLE_OCAMLC=ocamlc -e ISABELLE_SMLNJ=sml -e ISABELLE_SWIPL=swipl",  | 
| 
 
4a3fc3420747
full benchmarks, including all conditional theories;
 
wenzelm 
parents: 
68209 
diff
changeset
 | 
265  | 
args = "-N -a -d '~~/src/Benchmarks'",  | 
| 
 
4a3fc3420747
full benchmarks, including all conditional theories;
 
wenzelm 
parents: 
68209 
diff
changeset
 | 
266  | 
          detect = Build_Log.Prop.build_tags + " = " + SQL.string("Benchmarks"))),
 | 
| 64351 | 267  | 
List(  | 
| 
67103
 
39cc38a06610
clarified description for mixed Mavericks / El Capitan system;
 
wenzelm 
parents: 
67089 
diff
changeset
 | 
268  | 
        Remote_Build("Mac OS X", "macbroy2",
 | 
| 65906 | 269  | 
options = "-m32 -M8" +  | 
270  | 
" -e ISABELLE_GHC=ghc -e ISABELLE_MLTON=mlton -e ISABELLE_OCAML=ocaml" +  | 
|
271  | 
" -e ISABELLE_OCAMLC=ocamlc -e ISABELLE_SMLNJ=/mnt/nfsbroy/home/smlnj/bin/sml",  | 
|
| 65902 | 272  | 
args = "-a",  | 
| 67080 | 273  | 
detect = Build_Log.Prop.build_tags.undefined,  | 
| 
67089
 
c96ee0eb0d5f
macbroy2 is back, still pretending to be on Mavericks for better comparison of performance;
 
wenzelm 
parents: 
67080 
diff
changeset
 | 
274  | 
history_base = "2c0f24e927dd"),  | 
| 
67103
 
39cc38a06610
clarified description for mixed Mavericks / El Capitan system;
 
wenzelm 
parents: 
67089 
diff
changeset
 | 
275  | 
        Remote_Build("Mac OS X, quick_and_dirty", "macbroy2",
 | 
| 65732 | 276  | 
options = "-m32 -M8 -t quick_and_dirty", args = "-a -o quick_and_dirty",  | 
| 67080 | 277  | 
          detect = Build_Log.Prop.build_tags + " = " + SQL.string("quick_and_dirty"),
 | 
| 
67089
 
c96ee0eb0d5f
macbroy2 is back, still pretending to be on Mavericks for better comparison of performance;
 
wenzelm 
parents: 
67080 
diff
changeset
 | 
278  | 
history_base = "2c0f24e927dd"),  | 
| 
67103
 
39cc38a06610
clarified description for mixed Mavericks / El Capitan system;
 
wenzelm 
parents: 
67089 
diff
changeset
 | 
279  | 
        Remote_Build("Mac OS X, skip_proofs", "macbroy2",
 | 
| 65732 | 280  | 
options = "-m32 -M8 -t skip_proofs", args = "-a -o skip_proofs",  | 
| 67080 | 281  | 
          detect = Build_Log.Prop.build_tags + " = " + SQL.string("skip_proofs"),
 | 
| 
67089
 
c96ee0eb0d5f
macbroy2 is back, still pretending to be on Mavericks for better comparison of performance;
 
wenzelm 
parents: 
67080 
diff
changeset
 | 
282  | 
history_base = "2c0f24e927dd")),  | 
| 65768 | 283  | 
List(  | 
284  | 
        Remote_Build("Mac OS X 10.12 Sierra", "macbroy30", options = "-m32 -M2", args = "-a",
 | 
|
285  | 
detect = Build_Log.Prop.build_start + " > date '2017-03-03'")),  | 
|
286  | 
      List(Remote_Build("Mac OS X 10.10 Yosemite", "macbroy31", options = "-m32 -M2", args = "-a")),
 | 
|
| 69309 | 287  | 
      List(Remote_Build("Mac OS X 10.14 High Sierra", "lapbroy68", self_update = true,
 | 
288  | 
options = "-m32 -M1,2,4 -e ISABELLE_GHC_SETUP=true -e ISABELLE_OCAML_SETUP=true",  | 
|
289  | 
args = "-a -d '~~/src/Benchmarks'")),  | 
|
| 69245 | 290  | 
      List(Remote_Build("Mac OS X 10.14 Mojave", "lapnipkow3", self_update = true,
 | 
| 
69253
 
8bfa615ddde4
proper ghc_setup / ocaml_setup on target Isabelle distribution (amending 2a17c481d05e);
 
wenzelm 
parents: 
69245 
diff
changeset
 | 
291  | 
options = "-m32 -M1,2 -e ISABELLE_GHC_SETUP=true -e ISABELLE_OCAML_SETUP=true",  | 
| 
 
8bfa615ddde4
proper ghc_setup / ocaml_setup on target Isabelle distribution (amending 2a17c481d05e);
 
wenzelm 
parents: 
69245 
diff
changeset
 | 
292  | 
args = "-a -d '~~/src/Benchmarks'")),  | 
| 64351 | 293  | 
List(  | 
| 67775 | 294  | 
        Remote_Build("Windows", "vmnipkow9", historic = true, history = 90, self_update = true,
 | 
| 65906 | 295  | 
options = "-m32 -M4" +  | 
296  | 
" -e ISABELLE_OCAML=ocaml -e ISABELLE_OCAMLC=ocamlc" +  | 
|
297  | 
" -e ISABELLE_GHC=/usr/local/ghc-8.0.2/bin/ghc" +  | 
|
298  | 
" -e ISABELLE_SMLNJ=/usr/local/smlnj-110.81/bin/sml",  | 
|
| 65902 | 299  | 
args = "-a",  | 
| 65732 | 300  | 
          detect = Build_Log.Settings.ML_PLATFORM + " = " + SQL.string("x86-windows")),
 | 
| 67775 | 301  | 
        Remote_Build("Windows", "vmnipkow9", historic = true, history = 90, self_update = true,
 | 
| 65906 | 302  | 
options = "-m64 -M4" +  | 
303  | 
" -e ISABELLE_OCAML=ocaml -e ISABELLE_OCAMLC=ocamlc" +  | 
|
304  | 
" -e ISABELLE_GHC=/usr/local/ghc-8.0.2/bin/ghc" +  | 
|
305  | 
" -e ISABELLE_SMLNJ=/usr/local/smlnj-110.81/bin/sml",  | 
|
| 65902 | 306  | 
args = "-a",  | 
| 68530 | 307  | 
          detect = Build_Log.Settings.ML_PLATFORM + " = " + SQL.string("x86_64-windows")))
 | 
| 66864 | 308  | 
) :::  | 
309  | 
    {
 | 
|
| 67607 | 310  | 
      for { (n, hosts) <- List(1 -> List("lxbroy6"), 2 -> List("lxbroy8", "lxbroy5")) }
 | 
| 66864 | 311  | 
      yield {
 | 
| 
67075
 
eada9bd5fff2
avoid lxbroy7, which is presently inaccessible, but retain its build history in db queries;
 
wenzelm 
parents: 
67070 
diff
changeset
 | 
312  | 
        List(Remote_Build("AFP", host = hosts.head, more_hosts = hosts.tail,
 | 
| 67568 | 313  | 
options = "-m32 -M1x2 -t AFP -P" + n +  | 
314  | 
" -e ISABELLE_GHC=ghc" +  | 
|
315  | 
" -e ISABELLE_MLTON=mlton" +  | 
|
316  | 
" -e ISABELLE_OCAML=ocaml -e ISABELLE_OCAMLC=ocamlc" +  | 
|
317  | 
" -e ISABELLE_SMLNJ=/home/smlnj/bin/sml",  | 
|
| 66864 | 318  | 
args = "-N -X slow",  | 
319  | 
afp = true,  | 
|
320  | 
          detect = Build_Log.Prop.build_tags + " = " + SQL.string("AFP")))
 | 
|
321  | 
}  | 
|
322  | 
}  | 
|
| 65732 | 323  | 
}  | 
| 
64231
 
dbc8294c75d3
added remote_build_history tasks: parallel on several remote hosts;
 
wenzelm 
parents: 
64220 
diff
changeset
 | 
324  | 
|
| 
66898
 
8b7c4679c05b
parallel remote_builds2 for the sake of "AFP slow" (with theoretical data race on build_log_dirs);
 
wenzelm 
parents: 
66897 
diff
changeset
 | 
325  | 
val remote_builds2: List[List[Remote_Build]] =  | 
| 
 
8b7c4679c05b
parallel remote_builds2 for the sake of "AFP slow" (with theoretical data race on build_log_dirs);
 
wenzelm 
parents: 
66897 
diff
changeset
 | 
326  | 
List(  | 
| 
 
8b7c4679c05b
parallel remote_builds2 for the sake of "AFP slow" (with theoretical data race on build_log_dirs);
 
wenzelm 
parents: 
66897 
diff
changeset
 | 
327  | 
List(  | 
| 67775 | 328  | 
        Remote_Build("AFP slow", "lrzcloud1", self_update = true,
 | 
| 67868 | 329  | 
proxy_host = "lxbroy10", proxy_user = "i21isatest",  | 
| 67772 | 330  | 
ssh_host = "10.155.208.96", ssh_permissive = true,  | 
| 
66898
 
8b7c4679c05b
parallel remote_builds2 for the sake of "AFP slow" (with theoretical data race on build_log_dirs);
 
wenzelm 
parents: 
66897 
diff
changeset
 | 
331  | 
options = "-m64 -M6 -U30000 -s10 -t AFP",  | 
| 
 
8b7c4679c05b
parallel remote_builds2 for the sake of "AFP slow" (with theoretical data race on build_log_dirs);
 
wenzelm 
parents: 
66897 
diff
changeset
 | 
332  | 
args = "-g slow",  | 
| 
 
8b7c4679c05b
parallel remote_builds2 for the sake of "AFP slow" (with theoretical data race on build_log_dirs);
 
wenzelm 
parents: 
66897 
diff
changeset
 | 
333  | 
afp = true,  | 
| 66980 | 334  | 
slow = true,  | 
| 
66898
 
8b7c4679c05b
parallel remote_builds2 for the sake of "AFP slow" (with theoretical data race on build_log_dirs);
 
wenzelm 
parents: 
66897 
diff
changeset
 | 
335  | 
          detect = Build_Log.Prop.build_tags + " = " + SQL.string("AFP"))))
 | 
| 
 
8b7c4679c05b
parallel remote_builds2 for the sake of "AFP slow" (with theoretical data race on build_log_dirs);
 
wenzelm 
parents: 
66897 
diff
changeset
 | 
336  | 
|
| 
67752
 
636f633552a3
clarified signature: facilitate interactive experimentation;
 
wenzelm 
parents: 
67751 
diff
changeset
 | 
337  | 
def remote_build_history(rev: String, afp_rev: Option[String], i: Int, r: Remote_Build)  | 
| 
 
636f633552a3
clarified signature: facilitate interactive experimentation;
 
wenzelm 
parents: 
67751 
diff
changeset
 | 
338  | 
: Logger_Task =  | 
| 
64294
 
303976a45afe
shared_home is default for classic isatest home setup;
 
wenzelm 
parents: 
64277 
diff
changeset
 | 
339  | 
  {
 | 
| 
 
303976a45afe
shared_home is default for classic isatest home setup;
 
wenzelm 
parents: 
64277 
diff
changeset
 | 
340  | 
val task_name = "build_history-" + r.host  | 
| 
 
303976a45afe
shared_home is default for classic isatest home setup;
 
wenzelm 
parents: 
64277 
diff
changeset
 | 
341  | 
Logger_Task(task_name, logger =>  | 
| 
64231
 
dbc8294c75d3
added remote_build_history tasks: parallel on several remote hosts;
 
wenzelm 
parents: 
64220 
diff
changeset
 | 
342  | 
      {
 | 
| 67750 | 343  | 
using(r.ssh_session(logger.ssh_context))(ssh =>  | 
344  | 
          {
 | 
|
345  | 
val results =  | 
|
346  | 
Build_History.remote_build_history(ssh,  | 
|
347  | 
isabelle_repos,  | 
|
348  | 
isabelle_repos.ext(r.host),  | 
|
349  | 
isabelle_identifier = "cronjob_build_history",  | 
|
| 67775 | 350  | 
self_update = r.self_update,  | 
| 67750 | 351  | 
rev = rev,  | 
352  | 
afp_rev = afp_rev,  | 
|
353  | 
options =  | 
|
354  | 
" -N " + Bash.string(task_name) + (if (i < 0) "" else "_" + (i + 1).toString) +  | 
|
| 
69304
 
1f4afcde3334
more robust hostname for Isabelle cronjobs: do not rely on target OS installation for resulting build_log database content;
 
wenzelm 
parents: 
69253 
diff
changeset
 | 
355  | 
" -f -h " + Bash.string(r.host) + " " + r.options,  | 
| 67750 | 356  | 
args = "-o timeout=10800 " + r.args)  | 
| 64346 | 357  | 
|
| 67750 | 358  | 
            for ((log_name, bytes) <- results) {
 | 
359  | 
logger.log(Date.now(), log_name)  | 
|
360  | 
Bytes.write(logger.log_dir + Path.explode(log_name), bytes)  | 
|
361  | 
}  | 
|
362  | 
})  | 
|
| 
64231
 
dbc8294c75d3
added remote_build_history tasks: parallel on several remote hosts;
 
wenzelm 
parents: 
64220 
diff
changeset
 | 
363  | 
})  | 
| 
64294
 
303976a45afe
shared_home is default for classic isatest home setup;
 
wenzelm 
parents: 
64277 
diff
changeset
 | 
364  | 
}  | 
| 
64231
 
dbc8294c75d3
added remote_build_history tasks: parallel on several remote hosts;
 
wenzelm 
parents: 
64220 
diff
changeset
 | 
365  | 
|
| 65747 | 366  | 
val build_status_profiles: List[Build_Status.Profile] =  | 
| 
66898
 
8b7c4679c05b
parallel remote_builds2 for the sake of "AFP slow" (with theoretical data race on build_log_dirs);
 
wenzelm 
parents: 
66897 
diff
changeset
 | 
367  | 
(remote_builds_old :: remote_builds1 ::: remote_builds2).flatten.map(_.profile)  | 
| 65747 | 368  | 
|
| 65746 | 369  | 
|
| 64192 | 370  | 
|
371  | 
/** task logging **/  | 
|
| 64171 | 372  | 
|
| 
67752
 
636f633552a3
clarified signature: facilitate interactive experimentation;
 
wenzelm 
parents: 
67751 
diff
changeset
 | 
373  | 
object Log_Service  | 
| 
 
636f633552a3
clarified signature: facilitate interactive experimentation;
 
wenzelm 
parents: 
67751 
diff
changeset
 | 
374  | 
  {
 | 
| 
 
636f633552a3
clarified signature: facilitate interactive experimentation;
 
wenzelm 
parents: 
67751 
diff
changeset
 | 
375  | 
def apply(options: Options, progress: Progress = No_Progress): Log_Service =  | 
| 
 
636f633552a3
clarified signature: facilitate interactive experimentation;
 
wenzelm 
parents: 
67751 
diff
changeset
 | 
376  | 
new Log_Service(SSH.init_context(options), progress)  | 
| 
 
636f633552a3
clarified signature: facilitate interactive experimentation;
 
wenzelm 
parents: 
67751 
diff
changeset
 | 
377  | 
}  | 
| 64154 | 378  | 
|
| 
67752
 
636f633552a3
clarified signature: facilitate interactive experimentation;
 
wenzelm 
parents: 
67751 
diff
changeset
 | 
379  | 
class Log_Service private(val ssh_context: SSH.Context, progress: Progress)  | 
| 64171 | 380  | 
  {
 | 
| 64219 | 381  | 
current_log.file.delete  | 
382  | 
||
| 64171 | 383  | 
private val thread: Consumer_Thread[String] =  | 
384  | 
      Consumer_Thread.fork("cronjob: logger", daemon = true)(
 | 
|
385  | 
consume = (text: String) =>  | 
|
| 64219 | 386  | 
          { // critical
 | 
387  | 
File.append(current_log, text + "\n")  | 
|
388  | 
File.append(cumulative_log, text + "\n")  | 
|
| 64171 | 389  | 
progress.echo(text)  | 
390  | 
true  | 
|
391  | 
})  | 
|
392  | 
||
393  | 
    def shutdown() { thread.shutdown() }
 | 
|
394  | 
||
395  | 
val hostname = Isabelle_System.hostname()  | 
|
396  | 
||
397  | 
def log(date: Date, task_name: String, msg: String): Unit =  | 
|
| 64193 | 398  | 
if (task_name != "")  | 
399  | 
thread.send(  | 
|
400  | 
"[" + Build_Log.print_date(date) + ", " + hostname + ", " + task_name + "]: " + msg)  | 
|
| 64171 | 401  | 
|
402  | 
def start_logger(start_date: Date, task_name: String): Logger =  | 
|
403  | 
new Logger(this, start_date, task_name)  | 
|
| 64154 | 404  | 
|
| 64171 | 405  | 
def run_task(start_date: Date, task: Logger_Task)  | 
406  | 
    {
 | 
|
407  | 
val logger = start_logger(start_date, task.name)  | 
|
408  | 
      val res = Exn.capture { task.body(logger) }
 | 
|
409  | 
val end_date = Date.now()  | 
|
410  | 
val err =  | 
|
411  | 
        res match {
 | 
|
412  | 
case Exn.Res(_) => None  | 
|
| 64295 | 413  | 
case Exn.Exn(exn) =>  | 
| 67178 | 414  | 
            Output.writeln("Exception trace for " + quote(task.name) + ":")
 | 
| 64397 | 415  | 
exn.printStackTrace()  | 
| 66923 | 416  | 
val first_line = split_lines(Exn.message(exn)).headOption getOrElse "exception"  | 
| 64295 | 417  | 
Some(first_line)  | 
| 64171 | 418  | 
}  | 
419  | 
logger.log_end(end_date, err)  | 
|
420  | 
}  | 
|
421  | 
||
422  | 
def fork_task(start_date: Date, task: Logger_Task): Task =  | 
|
423  | 
new Task(task.name, run_task(start_date, task))  | 
|
424  | 
}  | 
|
425  | 
||
426  | 
class Logger private[Isabelle_Cronjob](  | 
|
427  | 
val log_service: Log_Service, val start_date: Date, val task_name: String)  | 
|
| 64162 | 428  | 
  {
 | 
| 64257 | 429  | 
def ssh_context: SSH.Context = log_service.ssh_context  | 
| 65640 | 430  | 
def options: Options = ssh_context.options  | 
| 
64231
 
dbc8294c75d3
added remote_build_history tasks: parallel on several remote hosts;
 
wenzelm 
parents: 
64220 
diff
changeset
 | 
431  | 
|
| 64171 | 432  | 
def log(date: Date, msg: String): Unit = log_service.log(date, task_name, msg)  | 
433  | 
||
434  | 
def log_end(end_date: Date, err: Option[String])  | 
|
435  | 
    {
 | 
|
436  | 
val elapsed_time = end_date.time - start_date.time  | 
|
437  | 
val msg =  | 
|
438  | 
(if (err.isEmpty) "finished" else "ERROR " + err.get) +  | 
|
| 64197 | 439  | 
        (if (elapsed_time.seconds < 3.0) "" else " (" + elapsed_time.message_hms + " elapsed time)")
 | 
| 64171 | 440  | 
log(end_date, msg)  | 
441  | 
}  | 
|
442  | 
||
| 64195 | 443  | 
val log_dir: Path = main_dir + Build_Log.log_subdir(start_date)  | 
444  | 
||
445  | 
Isabelle_System.mkdirs(log_dir)  | 
|
| 64171 | 446  | 
log(start_date, "started")  | 
447  | 
}  | 
|
448  | 
||
449  | 
class Task private[Isabelle_Cronjob](name: String, body: => Unit)  | 
|
450  | 
  {
 | 
|
451  | 
    private val future: Future[Unit] = Future.thread("cronjob: " + name) { body }
 | 
|
452  | 
def is_finished: Boolean = future.is_finished  | 
|
| 64162 | 453  | 
}  | 
| 
64153
 
769791954872
some timing and logging, similar to old isatest.log;
 
wenzelm 
parents: 
64148 
diff
changeset
 | 
454  | 
|
| 64170 | 455  | 
|
456  | 
||
| 
64153
 
769791954872
some timing and logging, similar to old isatest.log;
 
wenzelm 
parents: 
64148 
diff
changeset
 | 
457  | 
/** cronjob **/  | 
| 
 
769791954872
some timing and logging, similar to old isatest.log;
 
wenzelm 
parents: 
64148 
diff
changeset
 | 
458  | 
|
| 64187 | 459  | 
def cronjob(progress: Progress, exclude_task: Set[String])  | 
| 
64153
 
769791954872
some timing and logging, similar to old isatest.log;
 
wenzelm 
parents: 
64148 
diff
changeset
 | 
460  | 
  {
 | 
| 64171 | 461  | 
/* soft lock */  | 
| 
64153
 
769791954872
some timing and logging, similar to old isatest.log;
 
wenzelm 
parents: 
64148 
diff
changeset
 | 
462  | 
|
| 
 
769791954872
some timing and logging, similar to old isatest.log;
 
wenzelm 
parents: 
64148 
diff
changeset
 | 
463  | 
val still_running =  | 
| 
 
769791954872
some timing and logging, similar to old isatest.log;
 
wenzelm 
parents: 
64148 
diff
changeset
 | 
464  | 
      try { Some(File.read(main_state_file)) }
 | 
| 
 
769791954872
some timing and logging, similar to old isatest.log;
 
wenzelm 
parents: 
64148 
diff
changeset
 | 
465  | 
      catch { case ERROR(_) => None }
 | 
| 
 
769791954872
some timing and logging, similar to old isatest.log;
 
wenzelm 
parents: 
64148 
diff
changeset
 | 
466  | 
|
| 
 
769791954872
some timing and logging, similar to old isatest.log;
 
wenzelm 
parents: 
64148 
diff
changeset
 | 
467  | 
    still_running match {
 | 
| 64170 | 468  | 
      case None | Some("") =>
 | 
| 
64153
 
769791954872
some timing and logging, similar to old isatest.log;
 
wenzelm 
parents: 
64148 
diff
changeset
 | 
469  | 
case Some(running) =>  | 
| 
 
769791954872
some timing and logging, similar to old isatest.log;
 
wenzelm 
parents: 
64148 
diff
changeset
 | 
470  | 
        error("Isabelle cronjob appears to be still running: " + running)
 | 
| 
 
769791954872
some timing and logging, similar to old isatest.log;
 
wenzelm 
parents: 
64148 
diff
changeset
 | 
471  | 
}  | 
| 
 
769791954872
some timing and logging, similar to old isatest.log;
 
wenzelm 
parents: 
64148 
diff
changeset
 | 
472  | 
|
| 64199 | 473  | 
|
474  | 
/* log service */  | 
|
475  | 
||
| 
67752
 
636f633552a3
clarified signature: facilitate interactive experimentation;
 
wenzelm 
parents: 
67751 
diff
changeset
 | 
476  | 
val log_service = Log_Service(Options.init(), progress = progress)  | 
| 64154 | 477  | 
|
| 64199 | 478  | 
    def run(start_date: Date, task: Logger_Task) { log_service.run_task(start_date, task) }
 | 
479  | 
||
480  | 
    def run_now(task: Logger_Task) { run(Date.now(), task) }
 | 
|
| 64154 | 481  | 
|
482  | 
||
| 64199 | 483  | 
/* structured tasks */  | 
| 64184 | 484  | 
|
| 
64350
 
3af8566788e7
remote_builds has PAR-SEQ semantics of old isatest-makedist;
 
wenzelm 
parents: 
64348 
diff
changeset
 | 
485  | 
def SEQ(tasks: List[Logger_Task]): Logger_Task = Logger_Task(body = _ =>  | 
| 64193 | 486  | 
for (task <- tasks.iterator if !exclude_task(task.name) || task.name == "")  | 
| 64199 | 487  | 
run_now(task))  | 
| 
64153
 
769791954872
some timing and logging, similar to old isatest.log;
 
wenzelm 
parents: 
64148 
diff
changeset
 | 
488  | 
|
| 
64350
 
3af8566788e7
remote_builds has PAR-SEQ semantics of old isatest-makedist;
 
wenzelm 
parents: 
64348 
diff
changeset
 | 
489  | 
def PAR(tasks: List[Logger_Task]): Logger_Task = Logger_Task(body = _ =>  | 
| 64170 | 490  | 
      {
 | 
| 64199 | 491  | 
@tailrec def join(running: List[Task])  | 
492  | 
        {
 | 
|
493  | 
          running.partition(_.is_finished) match {
 | 
|
494  | 
case (Nil, Nil) =>  | 
|
495  | 
case (Nil, _ :: _) => Thread.sleep(500); join(running)  | 
|
496  | 
case (_ :: _, remaining) => join(remaining)  | 
|
497  | 
}  | 
|
| 64170 | 498  | 
}  | 
| 64199 | 499  | 
val start_date = Date.now()  | 
500  | 
val running =  | 
|
| 
64350
 
3af8566788e7
remote_builds has PAR-SEQ semantics of old isatest-makedist;
 
wenzelm 
parents: 
64348 
diff
changeset
 | 
501  | 
for (task <- tasks if !exclude_task(task.name))  | 
| 64199 | 502  | 
yield log_service.fork_task(start_date, task)  | 
503  | 
join(running)  | 
|
504  | 
})  | 
|
| 64193 | 505  | 
|
| 64170 | 506  | 
|
| 66897 | 507  | 
/* repository structure */  | 
| 64199 | 508  | 
|
| 65820 | 509  | 
val hg = Mercurial.repository(isabelle_repos)  | 
| 66895 | 510  | 
val hg_graph = hg.graph()  | 
| 
67048
 
ec438988b65a
local user_home for improved performance, but only after given changeset for stability of measurement history;
 
wenzelm 
parents: 
67008 
diff
changeset
 | 
511  | 
|
| 66895 | 512  | 
def history_base_filter(r: Remote_Build): Item => Boolean =  | 
513  | 
    {
 | 
|
514  | 
val base_rev = hg.id(r.history_base)  | 
|
515  | 
val nodes = hg_graph.all_succs(List(base_rev)).toSet  | 
|
516  | 
(item: Item) => nodes(item.isabelle_version)  | 
|
517  | 
}  | 
|
518  | 
||
| 66897 | 519  | 
|
520  | 
/* main */  | 
|
521  | 
||
522  | 
val main_start_date = Date.now()  | 
|
523  | 
File.write(main_state_file, main_start_date + " " + log_service.hostname)  | 
|
524  | 
||
| 64193 | 525  | 
run(main_start_date,  | 
| 
65783
 
d3d5cb2d6866
pick isabelle_version based on build_log database;
 
wenzelm 
parents: 
65771 
diff
changeset
 | 
526  | 
      Logger_Task("isabelle_cronjob", logger =>
 | 
| 
64231
 
dbc8294c75d3
added remote_build_history tasks: parallel on several remote hosts;
 
wenzelm 
parents: 
64220 
diff
changeset
 | 
527  | 
run_now(  | 
| 
67766
 
603334230303
consolidated main cronjob server on virtual machine together with build_log database;
 
wenzelm 
parents: 
67763 
diff
changeset
 | 
528  | 
SEQ(List(  | 
| 
 
603334230303
consolidated main cronjob server on virtual machine together with build_log database;
 
wenzelm 
parents: 
67763 
diff
changeset
 | 
529  | 
init,  | 
| 
67774
 
5437491732d2
build_history_base as remote build on lxbroy10: thus self_update has already happened once, and thus avoids conflicts with parallel builds on shared home directory;
 
wenzelm 
parents: 
67772 
diff
changeset
 | 
530  | 
build_history_base,  | 
| 
67766
 
603334230303
consolidated main cronjob server on virtual machine together with build_log database;
 
wenzelm 
parents: 
67763 
diff
changeset
 | 
531  | 
PAR(  | 
| 
67774
 
5437491732d2
build_history_base as remote build on lxbroy10: thus self_update has already happened once, and thus avoids conflicts with parallel builds on shared home directory;
 
wenzelm 
parents: 
67772 
diff
changeset
 | 
532  | 
build_release ::  | 
| 
67766
 
603334230303
consolidated main cronjob server on virtual machine together with build_log database;
 
wenzelm 
parents: 
67763 
diff
changeset
 | 
533  | 
List(remote_builds1, remote_builds2).map(remote_builds =>  | 
| 
66898
 
8b7c4679c05b
parallel remote_builds2 for the sake of "AFP slow" (with theoretical data race on build_log_dirs);
 
wenzelm 
parents: 
66897 
diff
changeset
 | 
534  | 
SEQ(List(  | 
| 67080 | 535  | 
PAR(remote_builds.map(_.filter(_.active)).map(seq =>  | 
| 
66898
 
8b7c4679c05b
parallel remote_builds2 for the sake of "AFP slow" (with theoretical data race on build_log_dirs);
 
wenzelm 
parents: 
66897 
diff
changeset
 | 
536  | 
SEQ(  | 
| 
 
8b7c4679c05b
parallel remote_builds2 for the sake of "AFP slow" (with theoretical data race on build_log_dirs);
 
wenzelm 
parents: 
66897 
diff
changeset
 | 
537  | 
                    for {
 | 
| 
 
8b7c4679c05b
parallel remote_builds2 for the sake of "AFP slow" (with theoretical data race on build_log_dirs);
 
wenzelm 
parents: 
66897 
diff
changeset
 | 
538  | 
(r, i) <- (if (seq.length <= 1) seq.map((_, -1)) else seq.zipWithIndex)  | 
| 
67048
 
ec438988b65a
local user_home for improved performance, but only after given changeset for stability of measurement history;
 
wenzelm 
parents: 
67008 
diff
changeset
 | 
539  | 
(rev, afp_rev) <- r.pick(logger.options, hg.id(), history_base_filter(r))  | 
| 
67070
 
85e6c1ff5be3
removed pointless user_home: no measurable impact;
 
wenzelm 
parents: 
67049 
diff
changeset
 | 
540  | 
} yield remote_build_history(rev, afp_rev, i, r)))),  | 
| 67008 | 541  | 
                Logger_Task("jenkins_logs", _ =>
 | 
| 68209 | 542  | 
Jenkins.download_logs(logger.options, Jenkins.build_log_jobs, main_dir)),  | 
| 
66898
 
8b7c4679c05b
parallel remote_builds2 for the sake of "AFP slow" (with theoretical data race on build_log_dirs);
 
wenzelm 
parents: 
66897 
diff
changeset
 | 
543  | 
                Logger_Task("build_log_database",
 | 
| 
 
8b7c4679c05b
parallel remote_builds2 for the sake of "AFP slow" (with theoretical data race on build_log_dirs);
 
wenzelm 
parents: 
66897 
diff
changeset
 | 
544  | 
logger => Isabelle_Devel.build_log_database(logger.options, build_log_dirs)),  | 
| 
 
8b7c4679c05b
parallel remote_builds2 for the sake of "AFP slow" (with theoretical data race on build_log_dirs);
 
wenzelm 
parents: 
66897 
diff
changeset
 | 
545  | 
                Logger_Task("build_status",
 | 
| 
67766
 
603334230303
consolidated main cronjob server on virtual machine together with build_log database;
 
wenzelm 
parents: 
67763 
diff
changeset
 | 
546  | 
logger => Isabelle_Devel.build_status(logger.options)))))),  | 
| 
 
603334230303
consolidated main cronjob server on virtual machine together with build_log database;
 
wenzelm 
parents: 
67763 
diff
changeset
 | 
547  | 
exit)))))  | 
| 
64153
 
769791954872
some timing and logging, similar to old isatest.log;
 
wenzelm 
parents: 
64148 
diff
changeset
 | 
548  | 
|
| 64171 | 549  | 
log_service.shutdown()  | 
| 64170 | 550  | 
|
| 
64153
 
769791954872
some timing and logging, similar to old isatest.log;
 
wenzelm 
parents: 
64148 
diff
changeset
 | 
551  | 
main_state_file.file.delete  | 
| 
 
769791954872
some timing and logging, similar to old isatest.log;
 
wenzelm 
parents: 
64148 
diff
changeset
 | 
552  | 
}  | 
| 
 
769791954872
some timing and logging, similar to old isatest.log;
 
wenzelm 
parents: 
64148 
diff
changeset
 | 
553  | 
|
| 
 
769791954872
some timing and logging, similar to old isatest.log;
 
wenzelm 
parents: 
64148 
diff
changeset
 | 
554  | 
|
| 
 
769791954872
some timing and logging, similar to old isatest.log;
 
wenzelm 
parents: 
64148 
diff
changeset
 | 
555  | 
|
| 
 
769791954872
some timing and logging, similar to old isatest.log;
 
wenzelm 
parents: 
64148 
diff
changeset
 | 
556  | 
/** command line entry point **/  | 
| 
 
769791954872
some timing and logging, similar to old isatest.log;
 
wenzelm 
parents: 
64148 
diff
changeset
 | 
557  | 
|
| 64148 | 558  | 
def main(args: Array[String])  | 
559  | 
  {
 | 
|
560  | 
    Command_Line.tool0 {
 | 
|
561  | 
var force = false  | 
|
562  | 
var verbose = false  | 
|
| 64187 | 563  | 
var exclude_task = Set.empty[String]  | 
| 64148 | 564  | 
|
565  | 
      val getopts = Getopts("""
 | 
|
566  | 
Usage: Admin/cronjob/main [OPTIONS]  | 
|
567  | 
||
568  | 
Options are:  | 
|
569  | 
-f apply force to do anything  | 
|
570  | 
-v verbose  | 
|
| 64187 | 571  | 
-x NAME exclude tasks with this name  | 
| 64148 | 572  | 
""",  | 
573  | 
"f" -> (_ => force = true),  | 
|
| 64187 | 574  | 
"v" -> (_ => verbose = true),  | 
575  | 
"x:" -> (arg => exclude_task += arg))  | 
|
| 64148 | 576  | 
|
577  | 
val more_args = getopts(args)  | 
|
578  | 
if (more_args.nonEmpty) getopts.usage()  | 
|
579  | 
||
| 64909 | 580  | 
val progress = if (verbose) new Console_Progress() else No_Progress  | 
| 64148 | 581  | 
|
| 64187 | 582  | 
if (force) cronjob(progress, exclude_task)  | 
| 
64153
 
769791954872
some timing and logging, similar to old isatest.log;
 
wenzelm 
parents: 
64148 
diff
changeset
 | 
583  | 
      else error("Need to apply force to do anything")
 | 
| 64148 | 584  | 
}  | 
585  | 
}  | 
|
586  | 
}  |