| author | wenzelm | 
| Tue, 07 Apr 2020 21:49:36 +0200 | |
| changeset 71726 | a5fda30edae2 | 
| parent 71684 | 5036edb025b7 | 
| child 71761 | ad7ac7948d57 | 
| 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"  | 
| 71601 | 21  | 
  val main_dir: Path = Path.explode("~/cronjob")
 | 
22  | 
  val main_state_file: Path = main_dir + Path.explode("run/main.state")
 | 
|
23  | 
  val current_log: Path = main_dir + Path.explode("run/main.log")  // owned by log service
 | 
|
24  | 
  val cumulative_log: Path = 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"  | 
| 71601 | 27  | 
  val isabelle_repos: Path = main_dir + Path.explode("isabelle")
 | 
28  | 
  val afp_repos: Path = 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  | 
|
| 71601 | 45  | 
val init: Logger_Task =  | 
| 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  | 
|
| 71601 | 64  | 
val exit: Logger_Task =  | 
| 
67766
 
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  | 
||
| 71601 | 75  | 
val build_release: Logger_Task =  | 
| 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  | 
|
| 71601 | 84  | 
val build_history_base: Logger_Task =  | 
| 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 &&  | 
|
| 
71380
 
5965e6e3c3ec
proper comparison of Option values, following hint by IntelliJ;
 
wenzelm 
parents: 
70757 
diff
changeset
 | 
119  | 
(afp_rev.isEmpty || afp_rev.get != "" && afp_version == afp_rev)  | 
| 
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,  | 
| 
71564
 
03133befa33b
support actual_host for lrzcloud2: the proxy_host/sshd cannot resolve invented hostname (amending 1d8b6c2253e6);
 
wenzelm 
parents: 
71563 
diff
changeset
 | 
150  | 
actual_host: String = "",  | 
| 
64231
 
dbc8294c75d3
added remote_build_history tasks: parallel on several remote hosts;
 
wenzelm 
parents: 
64220 
diff
changeset
 | 
151  | 
user: String = "",  | 
| 65594 | 152  | 
port: Int = 0,  | 
| 67746 | 153  | 
proxy_host: String = "",  | 
154  | 
proxy_user: String = "",  | 
|
155  | 
proxy_port: Int = 0,  | 
|
| 67775 | 156  | 
self_update: Boolean = false,  | 
| 65820 | 157  | 
historic: Boolean = false,  | 
| 65789 | 158  | 
history: Int = 0,  | 
| 65820 | 159  | 
history_base: String = "build_history_base",  | 
| 
64231
 
dbc8294c75d3
added remote_build_history tasks: parallel on several remote hosts;
 
wenzelm 
parents: 
64220 
diff
changeset
 | 
160  | 
options: String = "",  | 
| 65732 | 161  | 
args: String = "",  | 
| 66864 | 162  | 
afp: Boolean = false,  | 
| 69693 | 163  | 
bulky: Boolean = false,  | 
| 
67075
 
eada9bd5fff2
avoid lxbroy7, which is presently inaccessible, but retain its build history in db queries;
 
wenzelm 
parents: 
67070 
diff
changeset
 | 
164  | 
more_hosts: List[String] = Nil,  | 
| 67080 | 165  | 
detect: SQL.Source = "",  | 
166  | 
active: Boolean = true)  | 
|
| 65732 | 167  | 
  {
 | 
| 67750 | 168  | 
def ssh_session(context: SSH.Context): SSH.Session =  | 
| 
71564
 
03133befa33b
support actual_host for lrzcloud2: the proxy_host/sshd cannot resolve invented hostname (amending 1d8b6c2253e6);
 
wenzelm 
parents: 
71563 
diff
changeset
 | 
169  | 
context.open_session(host = host, user = user, port = port, actual_host = actual_host,  | 
| 67772 | 170  | 
proxy_host = proxy_host, proxy_user = proxy_user, proxy_port = proxy_port,  | 
| 71554 | 171  | 
permissive = proxy_host.nonEmpty)  | 
| 67750 | 172  | 
|
| 
65783
 
d3d5cb2d6866
pick isabelle_version based on build_log database;
 
wenzelm 
parents: 
65771 
diff
changeset
 | 
173  | 
def sql: SQL.Source =  | 
| 
 
d3d5cb2d6866
pick isabelle_version based on build_log database;
 
wenzelm 
parents: 
65771 
diff
changeset
 | 
174  | 
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
 | 
175  | 
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
 | 
176  | 
(if (detect == "") "" else " AND " + SQL.enclose(detect))  | 
| 
 
d3d5cb2d6866
pick isabelle_version based on build_log database;
 
wenzelm 
parents: 
65771 
diff
changeset
 | 
177  | 
|
| 65747 | 178  | 
def profile: Build_Status.Profile =  | 
| 69693 | 179  | 
Build_Status.Profile(description, history = history, afp = afp, bulky = bulky, sql = sql)  | 
| 
65783
 
d3d5cb2d6866
pick isabelle_version based on build_log database;
 
wenzelm 
parents: 
65771 
diff
changeset
 | 
180  | 
|
| 66864 | 181  | 
def pick(  | 
182  | 
options: Options,  | 
|
183  | 
rev: String = "",  | 
|
| 66865 | 184  | 
filter: Item => Boolean = _ => true): Option[(String, Option[String])] =  | 
| 65747 | 185  | 
    {
 | 
| 
67753
 
f28aee3ad1e6
uniform setup_repository (pull/clone without update);
 
wenzelm 
parents: 
67752 
diff
changeset
 | 
186  | 
val afp_rev = if (afp) Some(get_afp_rev()) else None  | 
| 66864 | 187  | 
|
| 
65783
 
d3d5cb2d6866
pick isabelle_version based on build_log database;
 
wenzelm 
parents: 
65771 
diff
changeset
 | 
188  | 
val store = Build_Log.store(options)  | 
| 
 
d3d5cb2d6866
pick isabelle_version based on build_log database;
 
wenzelm 
parents: 
65771 
diff
changeset
 | 
189  | 
using(store.open_database())(db =>  | 
| 
 
d3d5cb2d6866
pick isabelle_version based on build_log database;
 
wenzelm 
parents: 
65771 
diff
changeset
 | 
190  | 
      {
 | 
| 66864 | 191  | 
def pick_days(days: Int, gap: Int): Option[(String, Option[String])] =  | 
| 65810 | 192  | 
        {
 | 
| 66865 | 193  | 
val items = recent_items(db, days, rev, afp_rev, sql).filter(filter)  | 
| 66007 | 194  | 
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
 | 
195  | 
|
| 66864 | 196  | 
          if (historic || items.exists(_.known_versions(rev, afp_rev))) {
 | 
| 65810 | 197  | 
val longest_run =  | 
198  | 
              (List.empty[Item] /: runs)({ case (item1, item2) =>
 | 
|
199  | 
if (item1.length >= item2.length) item1 else item2  | 
|
200  | 
})  | 
|
201  | 
if (longest_run.isEmpty) None  | 
|
| 66864 | 202  | 
else Some(longest_run(longest_run.length / 2).versions)  | 
| 65810 | 203  | 
}  | 
| 66864 | 204  | 
else if (rev != "") Some((rev, afp_rev))  | 
205  | 
else runs.flatten.headOption.map(_.versions)  | 
|
| 
65783
 
d3d5cb2d6866
pick isabelle_version based on build_log database;
 
wenzelm 
parents: 
65771 
diff
changeset
 | 
206  | 
}  | 
| 65810 | 207  | 
|
| 66007 | 208  | 
        pick_days(options.int("build_log_history") max history, 2) orElse
 | 
209  | 
pick_days(200, 5) orElse  | 
|
210  | 
pick_days(2000, 1)  | 
|
| 
65783
 
d3d5cb2d6866
pick isabelle_version based on build_log database;
 
wenzelm 
parents: 
65771 
diff
changeset
 | 
211  | 
})  | 
| 65747 | 212  | 
}  | 
| 65732 | 213  | 
}  | 
| 
64231
 
dbc8294c75d3
added remote_build_history tasks: parallel on several remote hosts;
 
wenzelm 
parents: 
64220 
diff
changeset
 | 
214  | 
|
| 65806 | 215  | 
val remote_builds_old: List[Remote_Build] =  | 
216  | 
List(  | 
|
| 70757 | 217  | 
      Remote_Build("AFP bulky", "lrzcloud1", self_update = true,
 | 
218  | 
proxy_host = "lxbroy10", proxy_user = "i21isatest",  | 
|
219  | 
options = "-m64 -M6 -U30000 -s10 -t AFP",  | 
|
220  | 
args = "-g large -g slow",  | 
|
221  | 
afp = true,  | 
|
222  | 
bulky = true,  | 
|
223  | 
        detect = Build_Log.Prop.build_tags + " = " + SQL.string("AFP")),
 | 
|
| 67608 | 224  | 
      Remote_Build("AFP", "lxbroy7",
 | 
| 69693 | 225  | 
args = "-N -X large -X slow",  | 
| 67608 | 226  | 
afp = true,  | 
227  | 
          detect = Build_Log.Prop.build_tags + " = " + SQL.string("AFP")),
 | 
|
| 66762 | 228  | 
      Remote_Build("Poly/ML 5.7 Linux", "lxbroy8",
 | 
229  | 
history_base = "37074e22e8be",  | 
|
230  | 
options = "-m32 -B -M1x2,2 -t polyml-5.7 -i 'init_component /home/isabelle/contrib/polyml-5.7'",  | 
|
231  | 
args = "-N -g timing",  | 
|
232  | 
        detect = Build_Log.Prop.build_tags + " = " + SQL.string("polyml-5.7") + " AND " +
 | 
|
233  | 
          Build_Log.Settings.ML_OPTIONS + " <> " + SQL.string("-H 500")),
 | 
|
| 66931 | 234  | 
      Remote_Build("Poly/ML 5.7.1 Linux", "lxbroy8",
 | 
235  | 
history_base = "a9d5b59c3e12",  | 
|
236  | 
options = "-m32 -B -M1x2,2 -t polyml-5.7.1-pre2 -i 'init_component /home/isabelle/contrib/polyml-test-905dae2ebfda'",  | 
|
237  | 
args = "-N -g timing",  | 
|
238  | 
detect =  | 
|
239  | 
          Build_Log.Prop.build_tags + " = " + SQL.string("polyml-5.7.1-pre1") + " OR " +
 | 
|
240  | 
          Build_Log.Prop.build_tags + " = " + SQL.string("polyml-5.7.1-pre2")),
 | 
|
| 66762 | 241  | 
      Remote_Build("Poly/ML 5.7 Mac OS X", "macbroy2",
 | 
242  | 
history_base = "37074e22e8be",  | 
|
243  | 
options = "-m32 -B -M1x4,4 -t polyml-5.7 -i 'init_component /home/isabelle/contrib/polyml-5.7'",  | 
|
244  | 
args = "-a",  | 
|
245  | 
        detect = Build_Log.Prop.build_tags + " = " + SQL.string("polyml-5.7")),
 | 
|
| 66931 | 246  | 
      Remote_Build("Poly/ML 5.7.1 Mac OS X", "macbroy2",
 | 
247  | 
history_base = "a9d5b59c3e12",  | 
|
248  | 
options = "-m32 -B -M1x4,4 -t polyml-5.7.1-pre2 -i 'init_component /home/isabelle/contrib/polyml-test-905dae2ebfda'",  | 
|
249  | 
args = "-a",  | 
|
250  | 
detect =  | 
|
251  | 
        Build_Log.Prop.build_tags + " = " + SQL.string("polyml-5.7.1-pre1") + " OR " +
 | 
|
252  | 
        Build_Log.Prop.build_tags + " = " + SQL.string("polyml-5.7.1-pre2")),
 | 
|
| 65806 | 253  | 
      Remote_Build("Poly/ML test", "lxbroy8",
 | 
| 
65843
 
d547173212d2
proper init_settings for init_component (before generated ML_OPTIONS etc.);
 
wenzelm 
parents: 
65840 
diff
changeset
 | 
254  | 
options = "-m32 -B -M1x2,2 -t polyml-test -i 'init_component /home/isabelle/contrib/polyml-5.7-20170217'",  | 
| 65806 | 255  | 
args = "-N -g timing",  | 
256  | 
        detect = Build_Log.Prop.build_tags + " = " + SQL.string("polyml-test")),
 | 
|
257  | 
      Remote_Build("Mac OS X 10.8 Mountain Lion", "macbroy30", options = "-m32 -M2", args = "-a",
 | 
|
258  | 
detect = Build_Log.Prop.build_start + " < date '2017-03-03'"))  | 
|
259  | 
||
| 
66898
 
8b7c4679c05b
parallel remote_builds2 for the sake of "AFP slow" (with theoretical data race on build_log_dirs);
 
wenzelm 
parents: 
66897 
diff
changeset
 | 
260  | 
val remote_builds1: List[List[Remote_Build]] =  | 
| 65732 | 261  | 
  {
 | 
| 
64231
 
dbc8294c75d3
added remote_build_history tasks: parallel on several remote hosts;
 
wenzelm 
parents: 
64220 
diff
changeset
 | 
262  | 
List(  | 
| 65764 | 263  | 
      List(Remote_Build("Linux A", "lxbroy9",
 | 
| 65732 | 264  | 
options = "-m32 -B -M1x2,2", args = "-N -g timing")),  | 
| 65820 | 265  | 
      List(Remote_Build("Linux B", "lxbroy10", historic = true, history = 90,
 | 
| 65732 | 266  | 
options = "-m32 -B -M1x4,2,4,6", args = "-N -g timing")),  | 
| 
68384
 
4a3fc3420747
full benchmarks, including all conditional theories;
 
wenzelm 
parents: 
68209 
diff
changeset
 | 
267  | 
      List(Remote_Build("Linux Benchmarks", "lxbroy5", historic = true, history = 90,
 | 
| 68385 | 268  | 
options = "-m32 -B -M1x2,2 -t Benchmarks" +  | 
| 
68384
 
4a3fc3420747
full benchmarks, including all conditional theories;
 
wenzelm 
parents: 
68209 
diff
changeset
 | 
269  | 
" -e ISABELLE_GHC=ghc -e ISABELLE_MLTON=mlton -e ISABELLE_OCAML=ocaml" +  | 
| 69952 | 270  | 
" -e ISABELLE_OCAMLC=ocamlc -e ISABELLE_OCAMLFIND=ocamlfind -e ISABELLE_SMLNJ=sml" +  | 
| 
69927
 
f387618d9053
updated settings: ISABELLE_OCAMLFIND, ISABELLE_OCAML_SETUP, but retain compatibility with historic versions that require ISABELLE_OCAMLC;
 
wenzelm 
parents: 
69694 
diff
changeset
 | 
271  | 
" -e ISABELLE_SWIPL=swipl",  | 
| 
68384
 
4a3fc3420747
full benchmarks, including all conditional theories;
 
wenzelm 
parents: 
68209 
diff
changeset
 | 
272  | 
args = "-N -a -d '~~/src/Benchmarks'",  | 
| 
 
4a3fc3420747
full benchmarks, including all conditional theories;
 
wenzelm 
parents: 
68209 
diff
changeset
 | 
273  | 
          detect = Build_Log.Prop.build_tags + " = " + SQL.string("Benchmarks"))),
 | 
| 64351 | 274  | 
List(  | 
| 
67103
 
39cc38a06610
clarified description for mixed Mavericks / El Capitan system;
 
wenzelm 
parents: 
67089 
diff
changeset
 | 
275  | 
        Remote_Build("Mac OS X", "macbroy2",
 | 
| 65906 | 276  | 
options = "-m32 -M8" +  | 
277  | 
" -e ISABELLE_GHC=ghc -e ISABELLE_MLTON=mlton -e ISABELLE_OCAML=ocaml" +  | 
|
| 
69927
 
f387618d9053
updated settings: ISABELLE_OCAMLFIND, ISABELLE_OCAML_SETUP, but retain compatibility with historic versions that require ISABELLE_OCAMLC;
 
wenzelm 
parents: 
69694 
diff
changeset
 | 
278  | 
" -e ISABELLE_OCAMLC=ocamlc -e ISABELLE_OCAML_SETUP=true" +  | 
| 
69955
 
160fcaf502d7
avoid global .opam directory: shared home leads to confusion about explicit vs. implicit ISABELLE_OCAMLFIND;
 
wenzelm 
parents: 
69952 
diff
changeset
 | 
279  | 
" -e ISABELLE_OPAM_ROOT=\"$ISABELLE_HOME/opam\"" +  | 
| 70241 | 280  | 
" -e ISABELLE_SMLNJ=/home/isabelle/smlnj/110.85/bin/sml",  | 
| 65902 | 281  | 
args = "-a",  | 
| 67080 | 282  | 
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
 | 
283  | 
history_base = "2c0f24e927dd"),  | 
| 
67103
 
39cc38a06610
clarified description for mixed Mavericks / El Capitan system;
 
wenzelm 
parents: 
67089 
diff
changeset
 | 
284  | 
        Remote_Build("Mac OS X, quick_and_dirty", "macbroy2",
 | 
| 65732 | 285  | 
options = "-m32 -M8 -t quick_and_dirty", args = "-a -o quick_and_dirty",  | 
| 67080 | 286  | 
          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
 | 
287  | 
history_base = "2c0f24e927dd"),  | 
| 
67103
 
39cc38a06610
clarified description for mixed Mavericks / El Capitan system;
 
wenzelm 
parents: 
67089 
diff
changeset
 | 
288  | 
        Remote_Build("Mac OS X, skip_proofs", "macbroy2",
 | 
| 65732 | 289  | 
options = "-m32 -M8 -t skip_proofs", args = "-a -o skip_proofs",  | 
| 67080 | 290  | 
          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
 | 
291  | 
history_base = "2c0f24e927dd")),  | 
| 65768 | 292  | 
List(  | 
| 
71565
 
24b68a932f26
back to old-style names for uniform sorting of build_status (amending 138e8226961e);
 
wenzelm 
parents: 
71564 
diff
changeset
 | 
293  | 
        Remote_Build("Mac OS X 10.12 Sierra", "macbroy30", options = "-m32 -M2", args = "-a",
 | 
| 65768 | 294  | 
detect = Build_Log.Prop.build_start + " > date '2017-03-03'")),  | 
295  | 
      List(Remote_Build("Mac OS X 10.10 Yosemite", "macbroy31", options = "-m32 -M2", args = "-a")),
 | 
|
| 
71565
 
24b68a932f26
back to old-style names for uniform sorting of build_status (amending 138e8226961e);
 
wenzelm 
parents: 
71564 
diff
changeset
 | 
296  | 
      List(Remote_Build("Mac OS X 10.13 High Sierra", "lapbroy68",
 | 
| 
69937
 
afbc075fd2da
less ambitious test: lapbroy68 lacks libgmp-dev that is required for ocaml setup of zarith;
 
wenzelm 
parents: 
69931 
diff
changeset
 | 
297  | 
options = "-m32 -M1,2,4 -e ISABELLE_GHC_SETUP=true",  | 
| 71538 | 298  | 
self_update = true, args = "-a -d '~~/src/Benchmarks'")),  | 
| 
71565
 
24b68a932f26
back to old-style names for uniform sorting of build_status (amending 138e8226961e);
 
wenzelm 
parents: 
71564 
diff
changeset
 | 
299  | 
      List(Remote_Build("Mac OS X 10.14 Mojave", "lapnipkow3",
 | 
| 
69937
 
afbc075fd2da
less ambitious test: lapbroy68 lacks libgmp-dev that is required for ocaml setup of zarith;
 
wenzelm 
parents: 
69931 
diff
changeset
 | 
300  | 
options = "-m32 -M1,2 -e ISABELLE_GHC_SETUP=true",  | 
| 71538 | 301  | 
self_update = true, args = "-a -d '~~/src/Benchmarks'")),  | 
| 
71565
 
24b68a932f26
back to old-style names for uniform sorting of build_status (amending 138e8226961e);
 
wenzelm 
parents: 
71564 
diff
changeset
 | 
302  | 
      List(Remote_Build("Mac OS X 10.15 Catalina", "laramac01", user = "makarius",
 | 
| 71537 | 303  | 
proxy_host = "laraserver", proxy_user = "makarius",  | 
| 71559 | 304  | 
self_update = true, options = "-m32 -M4 -e ISABELLE_GHC_SETUP=true",  | 
| 71537 | 305  | 
args = "-a -d '~~/src/Benchmarks'")),  | 
| 64351 | 306  | 
List(  | 
| 67775 | 307  | 
        Remote_Build("Windows", "vmnipkow9", historic = true, history = 90, self_update = true,
 | 
| 65906 | 308  | 
options = "-m32 -M4" +  | 
| 
69931
 
31ee094dea3d
prefer ISABELLE_OCAML_SETUP: Cygwin lacks libzarith;
 
wenzelm 
parents: 
69927 
diff
changeset
 | 
309  | 
" -e ISABELLE_OCAML=ocaml -e ISABELLE_OCAMLC=ocamlc -e ISABELLE_OCAML_SETUP=true" +  | 
| 69952 | 310  | 
" -e ISABELLE_GHC_SETUP=true" +  | 
| 65906 | 311  | 
" -e ISABELLE_SMLNJ=/usr/local/smlnj-110.81/bin/sml",  | 
| 65902 | 312  | 
args = "-a",  | 
| 65732 | 313  | 
          detect = Build_Log.Settings.ML_PLATFORM + " = " + SQL.string("x86-windows")),
 | 
| 67775 | 314  | 
        Remote_Build("Windows", "vmnipkow9", historic = true, history = 90, self_update = true,
 | 
| 65906 | 315  | 
options = "-m64 -M4" +  | 
| 
69931
 
31ee094dea3d
prefer ISABELLE_OCAML_SETUP: Cygwin lacks libzarith;
 
wenzelm 
parents: 
69927 
diff
changeset
 | 
316  | 
" -e ISABELLE_OCAML=ocaml -e ISABELLE_OCAMLC=ocamlc -e ISABELLE_OCAML_SETUP=true" +  | 
| 69952 | 317  | 
" -e ISABELLE_GHC_SETUP=true" +  | 
| 65906 | 318  | 
" -e ISABELLE_SMLNJ=/usr/local/smlnj-110.81/bin/sml",  | 
| 65902 | 319  | 
args = "-a",  | 
| 68530 | 320  | 
          detect = Build_Log.Settings.ML_PLATFORM + " = " + SQL.string("x86_64-windows")))
 | 
| 66864 | 321  | 
) :::  | 
322  | 
    {
 | 
|
| 67607 | 323  | 
      for { (n, hosts) <- List(1 -> List("lxbroy6"), 2 -> List("lxbroy8", "lxbroy5")) }
 | 
| 66864 | 324  | 
      yield {
 | 
| 
67075
 
eada9bd5fff2
avoid lxbroy7, which is presently inaccessible, but retain its build history in db queries;
 
wenzelm 
parents: 
67070 
diff
changeset
 | 
325  | 
        List(Remote_Build("AFP", host = hosts.head, more_hosts = hosts.tail,
 | 
| 67568 | 326  | 
options = "-m32 -M1x2 -t AFP -P" + n +  | 
327  | 
" -e ISABELLE_GHC=ghc" +  | 
|
328  | 
" -e ISABELLE_MLTON=mlton" +  | 
|
| 69952 | 329  | 
" -e ISABELLE_OCAML=ocaml -e ISABELLE_OCAMLC=ocamlc -e ISABELLE_OCAMLFIND=ocamlfind" +  | 
| 70241 | 330  | 
" -e ISABELLE_SMLNJ=sml",  | 
| 69693 | 331  | 
args = "-N -X large -X slow",  | 
| 66864 | 332  | 
afp = true,  | 
333  | 
          detect = Build_Log.Prop.build_tags + " = " + SQL.string("AFP")))
 | 
|
334  | 
}  | 
|
335  | 
}  | 
|
| 65732 | 336  | 
}  | 
| 
64231
 
dbc8294c75d3
added remote_build_history tasks: parallel on several remote hosts;
 
wenzelm 
parents: 
64220 
diff
changeset
 | 
337  | 
|
| 
66898
 
8b7c4679c05b
parallel remote_builds2 for the sake of "AFP slow" (with theoretical data race on build_log_dirs);
 
wenzelm 
parents: 
66897 
diff
changeset
 | 
338  | 
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
 | 
339  | 
List(  | 
| 
 
8b7c4679c05b
parallel remote_builds2 for the sake of "AFP slow" (with theoretical data race on build_log_dirs);
 
wenzelm 
parents: 
66897 
diff
changeset
 | 
340  | 
List(  | 
| 
71564
 
03133befa33b
support actual_host for lrzcloud2: the proxy_host/sshd cannot resolve invented hostname (amending 1d8b6c2253e6);
 
wenzelm 
parents: 
71563 
diff
changeset
 | 
341  | 
        Remote_Build("AFP2", "lrzcloud2", actual_host = "10.195.2.10", self_update = true,
 | 
| 70467 | 342  | 
proxy_host = "lxbroy10", proxy_user = "i21isatest",  | 
343  | 
options = "-m32 -M1x8 -t AFP" +  | 
|
344  | 
" -e ISABELLE_GHC=ghc" +  | 
|
345  | 
" -e ISABELLE_MLTON=mlton" +  | 
|
346  | 
" -e ISABELLE_OCAML=ocaml -e ISABELLE_OCAMLC=ocamlc -e ISABELLE_OCAMLFIND=ocamlfind" +  | 
|
347  | 
" -e ISABELLE_SMLNJ=sml",  | 
|
| 70477 | 348  | 
args = "-a -X large -X slow",  | 
| 70467 | 349  | 
afp = true,  | 
350  | 
          detect = Build_Log.Prop.build_tags + " = " + SQL.string("AFP")),
 | 
|
| 
71564
 
03133befa33b
support actual_host for lrzcloud2: the proxy_host/sshd cannot resolve invented hostname (amending 1d8b6c2253e6);
 
wenzelm 
parents: 
71563 
diff
changeset
 | 
351  | 
        Remote_Build("AFP bulky2", "lrzcloud2", actual_host = "10.195.2.10", self_update = true,
 | 
| 70467 | 352  | 
proxy_host = "lxbroy10", proxy_user = "i21isatest",  | 
353  | 
options = "-m64 -M8 -U30000 -s10 -t AFP",  | 
|
354  | 
args = "-g large -g slow",  | 
|
355  | 
afp = true,  | 
|
356  | 
bulky = 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
 | 
357  | 
          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
 | 
358  | 
|
| 
67752
 
636f633552a3
clarified signature: facilitate interactive experimentation;
 
wenzelm 
parents: 
67751 
diff
changeset
 | 
359  | 
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
 | 
360  | 
: Logger_Task =  | 
| 
64294
 
303976a45afe
shared_home is default for classic isatest home setup;
 
wenzelm 
parents: 
64277 
diff
changeset
 | 
361  | 
  {
 | 
| 
 
303976a45afe
shared_home is default for classic isatest home setup;
 
wenzelm 
parents: 
64277 
diff
changeset
 | 
362  | 
val task_name = "build_history-" + r.host  | 
| 
 
303976a45afe
shared_home is default for classic isatest home setup;
 
wenzelm 
parents: 
64277 
diff
changeset
 | 
363  | 
Logger_Task(task_name, logger =>  | 
| 
64231
 
dbc8294c75d3
added remote_build_history tasks: parallel on several remote hosts;
 
wenzelm 
parents: 
64220 
diff
changeset
 | 
364  | 
      {
 | 
| 67750 | 365  | 
using(r.ssh_session(logger.ssh_context))(ssh =>  | 
366  | 
          {
 | 
|
367  | 
val results =  | 
|
368  | 
Build_History.remote_build_history(ssh,  | 
|
369  | 
isabelle_repos,  | 
|
370  | 
isabelle_repos.ext(r.host),  | 
|
371  | 
isabelle_identifier = "cronjob_build_history",  | 
|
| 67775 | 372  | 
self_update = r.self_update,  | 
| 67750 | 373  | 
rev = rev,  | 
374  | 
afp_rev = afp_rev,  | 
|
375  | 
options =  | 
|
376  | 
" -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
 | 
377  | 
" -f -h " + Bash.string(r.host) + " " + r.options,  | 
| 67750 | 378  | 
args = "-o timeout=10800 " + r.args)  | 
| 64346 | 379  | 
|
| 67750 | 380  | 
            for ((log_name, bytes) <- results) {
 | 
381  | 
logger.log(Date.now(), log_name)  | 
|
382  | 
Bytes.write(logger.log_dir + Path.explode(log_name), bytes)  | 
|
383  | 
}  | 
|
384  | 
})  | 
|
| 
64231
 
dbc8294c75d3
added remote_build_history tasks: parallel on several remote hosts;
 
wenzelm 
parents: 
64220 
diff
changeset
 | 
385  | 
})  | 
| 
64294
 
303976a45afe
shared_home is default for classic isatest home setup;
 
wenzelm 
parents: 
64277 
diff
changeset
 | 
386  | 
}  | 
| 
64231
 
dbc8294c75d3
added remote_build_history tasks: parallel on several remote hosts;
 
wenzelm 
parents: 
64220 
diff
changeset
 | 
387  | 
|
| 65747 | 388  | 
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
 | 
389  | 
(remote_builds_old :: remote_builds1 ::: remote_builds2).flatten.map(_.profile)  | 
| 65747 | 390  | 
|
| 65746 | 391  | 
|
| 64192 | 392  | 
|
393  | 
/** task logging **/  | 
|
| 64171 | 394  | 
|
| 
67752
 
636f633552a3
clarified signature: facilitate interactive experimentation;
 
wenzelm 
parents: 
67751 
diff
changeset
 | 
395  | 
object Log_Service  | 
| 
 
636f633552a3
clarified signature: facilitate interactive experimentation;
 
wenzelm 
parents: 
67751 
diff
changeset
 | 
396  | 
  {
 | 
| 
71726
 
a5fda30edae2
clarified signature: more uniform treatment of stopped/interrupted state;
 
wenzelm 
parents: 
71684 
diff
changeset
 | 
397  | 
def apply(options: Options, progress: Progress = new Progress): Log_Service =  | 
| 
67752
 
636f633552a3
clarified signature: facilitate interactive experimentation;
 
wenzelm 
parents: 
67751 
diff
changeset
 | 
398  | 
new Log_Service(SSH.init_context(options), progress)  | 
| 
 
636f633552a3
clarified signature: facilitate interactive experimentation;
 
wenzelm 
parents: 
67751 
diff
changeset
 | 
399  | 
}  | 
| 64154 | 400  | 
|
| 
67752
 
636f633552a3
clarified signature: facilitate interactive experimentation;
 
wenzelm 
parents: 
67751 
diff
changeset
 | 
401  | 
class Log_Service private(val ssh_context: SSH.Context, progress: Progress)  | 
| 64171 | 402  | 
  {
 | 
| 64219 | 403  | 
current_log.file.delete  | 
404  | 
||
| 64171 | 405  | 
private val thread: Consumer_Thread[String] =  | 
406  | 
      Consumer_Thread.fork("cronjob: logger", daemon = true)(
 | 
|
407  | 
consume = (text: String) =>  | 
|
| 64219 | 408  | 
          { // critical
 | 
409  | 
File.append(current_log, text + "\n")  | 
|
410  | 
File.append(cumulative_log, text + "\n")  | 
|
| 64171 | 411  | 
progress.echo(text)  | 
412  | 
true  | 
|
413  | 
})  | 
|
414  | 
||
415  | 
    def shutdown() { thread.shutdown() }
 | 
|
416  | 
||
| 71601 | 417  | 
val hostname: String = Isabelle_System.hostname()  | 
| 64171 | 418  | 
|
419  | 
def log(date: Date, task_name: String, msg: String): Unit =  | 
|
| 64193 | 420  | 
if (task_name != "")  | 
421  | 
thread.send(  | 
|
422  | 
"[" + Build_Log.print_date(date) + ", " + hostname + ", " + task_name + "]: " + msg)  | 
|
| 64171 | 423  | 
|
424  | 
def start_logger(start_date: Date, task_name: String): Logger =  | 
|
425  | 
new Logger(this, start_date, task_name)  | 
|
| 64154 | 426  | 
|
| 64171 | 427  | 
def run_task(start_date: Date, task: Logger_Task)  | 
428  | 
    {
 | 
|
429  | 
val logger = start_logger(start_date, task.name)  | 
|
430  | 
      val res = Exn.capture { task.body(logger) }
 | 
|
431  | 
val end_date = Date.now()  | 
|
432  | 
val err =  | 
|
433  | 
        res match {
 | 
|
434  | 
case Exn.Res(_) => None  | 
|
| 64295 | 435  | 
case Exn.Exn(exn) =>  | 
| 67178 | 436  | 
            Output.writeln("Exception trace for " + quote(task.name) + ":")
 | 
| 64397 | 437  | 
exn.printStackTrace()  | 
| 66923 | 438  | 
val first_line = split_lines(Exn.message(exn)).headOption getOrElse "exception"  | 
| 64295 | 439  | 
Some(first_line)  | 
| 64171 | 440  | 
}  | 
441  | 
logger.log_end(end_date, err)  | 
|
442  | 
}  | 
|
443  | 
||
444  | 
def fork_task(start_date: Date, task: Logger_Task): Task =  | 
|
445  | 
new Task(task.name, run_task(start_date, task))  | 
|
446  | 
}  | 
|
447  | 
||
448  | 
class Logger private[Isabelle_Cronjob](  | 
|
449  | 
val log_service: Log_Service, val start_date: Date, val task_name: String)  | 
|
| 64162 | 450  | 
  {
 | 
| 64257 | 451  | 
def ssh_context: SSH.Context = log_service.ssh_context  | 
| 65640 | 452  | 
def options: Options = ssh_context.options  | 
| 
64231
 
dbc8294c75d3
added remote_build_history tasks: parallel on several remote hosts;
 
wenzelm 
parents: 
64220 
diff
changeset
 | 
453  | 
|
| 64171 | 454  | 
def log(date: Date, msg: String): Unit = log_service.log(date, task_name, msg)  | 
455  | 
||
456  | 
def log_end(end_date: Date, err: Option[String])  | 
|
457  | 
    {
 | 
|
458  | 
val elapsed_time = end_date.time - start_date.time  | 
|
459  | 
val msg =  | 
|
460  | 
(if (err.isEmpty) "finished" else "ERROR " + err.get) +  | 
|
| 64197 | 461  | 
        (if (elapsed_time.seconds < 3.0) "" else " (" + elapsed_time.message_hms + " elapsed time)")
 | 
| 64171 | 462  | 
log(end_date, msg)  | 
463  | 
}  | 
|
464  | 
||
| 64195 | 465  | 
val log_dir: Path = main_dir + Build_Log.log_subdir(start_date)  | 
466  | 
||
467  | 
Isabelle_System.mkdirs(log_dir)  | 
|
| 64171 | 468  | 
log(start_date, "started")  | 
469  | 
}  | 
|
470  | 
||
471  | 
class Task private[Isabelle_Cronjob](name: String, body: => Unit)  | 
|
472  | 
  {
 | 
|
473  | 
    private val future: Future[Unit] = Future.thread("cronjob: " + name) { body }
 | 
|
474  | 
def is_finished: Boolean = future.is_finished  | 
|
| 64162 | 475  | 
}  | 
| 
64153
 
769791954872
some timing and logging, similar to old isatest.log;
 
wenzelm 
parents: 
64148 
diff
changeset
 | 
476  | 
|
| 64170 | 477  | 
|
478  | 
||
| 
64153
 
769791954872
some timing and logging, similar to old isatest.log;
 
wenzelm 
parents: 
64148 
diff
changeset
 | 
479  | 
/** cronjob **/  | 
| 
 
769791954872
some timing and logging, similar to old isatest.log;
 
wenzelm 
parents: 
64148 
diff
changeset
 | 
480  | 
|
| 64187 | 481  | 
def cronjob(progress: Progress, exclude_task: Set[String])  | 
| 
64153
 
769791954872
some timing and logging, similar to old isatest.log;
 
wenzelm 
parents: 
64148 
diff
changeset
 | 
482  | 
  {
 | 
| 64171 | 483  | 
/* soft lock */  | 
| 
64153
 
769791954872
some timing and logging, similar to old isatest.log;
 
wenzelm 
parents: 
64148 
diff
changeset
 | 
484  | 
|
| 
 
769791954872
some timing and logging, similar to old isatest.log;
 
wenzelm 
parents: 
64148 
diff
changeset
 | 
485  | 
val still_running =  | 
| 
 
769791954872
some timing and logging, similar to old isatest.log;
 
wenzelm 
parents: 
64148 
diff
changeset
 | 
486  | 
      try { Some(File.read(main_state_file)) }
 | 
| 
 
769791954872
some timing and logging, similar to old isatest.log;
 
wenzelm 
parents: 
64148 
diff
changeset
 | 
487  | 
      catch { case ERROR(_) => None }
 | 
| 
 
769791954872
some timing and logging, similar to old isatest.log;
 
wenzelm 
parents: 
64148 
diff
changeset
 | 
488  | 
|
| 
 
769791954872
some timing and logging, similar to old isatest.log;
 
wenzelm 
parents: 
64148 
diff
changeset
 | 
489  | 
    still_running match {
 | 
| 64170 | 490  | 
      case None | Some("") =>
 | 
| 
64153
 
769791954872
some timing and logging, similar to old isatest.log;
 
wenzelm 
parents: 
64148 
diff
changeset
 | 
491  | 
case Some(running) =>  | 
| 
 
769791954872
some timing and logging, similar to old isatest.log;
 
wenzelm 
parents: 
64148 
diff
changeset
 | 
492  | 
        error("Isabelle cronjob appears to be still running: " + running)
 | 
| 
 
769791954872
some timing and logging, similar to old isatest.log;
 
wenzelm 
parents: 
64148 
diff
changeset
 | 
493  | 
}  | 
| 
 
769791954872
some timing and logging, similar to old isatest.log;
 
wenzelm 
parents: 
64148 
diff
changeset
 | 
494  | 
|
| 64199 | 495  | 
|
496  | 
/* log service */  | 
|
497  | 
||
| 
67752
 
636f633552a3
clarified signature: facilitate interactive experimentation;
 
wenzelm 
parents: 
67751 
diff
changeset
 | 
498  | 
val log_service = Log_Service(Options.init(), progress = progress)  | 
| 64154 | 499  | 
|
| 64199 | 500  | 
    def run(start_date: Date, task: Logger_Task) { log_service.run_task(start_date, task) }
 | 
501  | 
||
502  | 
    def run_now(task: Logger_Task) { run(Date.now(), task) }
 | 
|
| 64154 | 503  | 
|
504  | 
||
| 64199 | 505  | 
/* structured tasks */  | 
| 64184 | 506  | 
|
| 
64350
 
3af8566788e7
remote_builds has PAR-SEQ semantics of old isatest-makedist;
 
wenzelm 
parents: 
64348 
diff
changeset
 | 
507  | 
def SEQ(tasks: List[Logger_Task]): Logger_Task = Logger_Task(body = _ =>  | 
| 64193 | 508  | 
for (task <- tasks.iterator if !exclude_task(task.name) || task.name == "")  | 
| 64199 | 509  | 
run_now(task))  | 
| 
64153
 
769791954872
some timing and logging, similar to old isatest.log;
 
wenzelm 
parents: 
64148 
diff
changeset
 | 
510  | 
|
| 
64350
 
3af8566788e7
remote_builds has PAR-SEQ semantics of old isatest-makedist;
 
wenzelm 
parents: 
64348 
diff
changeset
 | 
511  | 
def PAR(tasks: List[Logger_Task]): Logger_Task = Logger_Task(body = _ =>  | 
| 64170 | 512  | 
      {
 | 
| 64199 | 513  | 
@tailrec def join(running: List[Task])  | 
514  | 
        {
 | 
|
515  | 
          running.partition(_.is_finished) match {
 | 
|
516  | 
case (Nil, Nil) =>  | 
|
| 71684 | 517  | 
case (Nil, _ :: _) => Time.seconds(0.5).sleep; join(running)  | 
| 64199 | 518  | 
case (_ :: _, remaining) => join(remaining)  | 
519  | 
}  | 
|
| 64170 | 520  | 
}  | 
| 64199 | 521  | 
val start_date = Date.now()  | 
522  | 
val running =  | 
|
| 
64350
 
3af8566788e7
remote_builds has PAR-SEQ semantics of old isatest-makedist;
 
wenzelm 
parents: 
64348 
diff
changeset
 | 
523  | 
for (task <- tasks if !exclude_task(task.name))  | 
| 64199 | 524  | 
yield log_service.fork_task(start_date, task)  | 
525  | 
join(running)  | 
|
526  | 
})  | 
|
| 64193 | 527  | 
|
| 64170 | 528  | 
|
| 66897 | 529  | 
/* repository structure */  | 
| 64199 | 530  | 
|
| 65820 | 531  | 
val hg = Mercurial.repository(isabelle_repos)  | 
| 66895 | 532  | 
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
 | 
533  | 
|
| 66895 | 534  | 
def history_base_filter(r: Remote_Build): Item => Boolean =  | 
535  | 
    {
 | 
|
536  | 
val base_rev = hg.id(r.history_base)  | 
|
537  | 
val nodes = hg_graph.all_succs(List(base_rev)).toSet  | 
|
538  | 
(item: Item) => nodes(item.isabelle_version)  | 
|
539  | 
}  | 
|
540  | 
||
| 66897 | 541  | 
|
542  | 
/* main */  | 
|
543  | 
||
544  | 
val main_start_date = Date.now()  | 
|
545  | 
File.write(main_state_file, main_start_date + " " + log_service.hostname)  | 
|
546  | 
||
| 64193 | 547  | 
run(main_start_date,  | 
| 
65783
 
d3d5cb2d6866
pick isabelle_version based on build_log database;
 
wenzelm 
parents: 
65771 
diff
changeset
 | 
548  | 
      Logger_Task("isabelle_cronjob", logger =>
 | 
| 
64231
 
dbc8294c75d3
added remote_build_history tasks: parallel on several remote hosts;
 
wenzelm 
parents: 
64220 
diff
changeset
 | 
549  | 
run_now(  | 
| 
67766
 
603334230303
consolidated main cronjob server on virtual machine together with build_log database;
 
wenzelm 
parents: 
67763 
diff
changeset
 | 
550  | 
SEQ(List(  | 
| 
 
603334230303
consolidated main cronjob server on virtual machine together with build_log database;
 
wenzelm 
parents: 
67763 
diff
changeset
 | 
551  | 
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
 | 
552  | 
build_history_base,  | 
| 
70195
 
e4abb5235c5e
sequential build_release: it uses some of the test machines for pre-built images;
 
wenzelm 
parents: 
69955 
diff
changeset
 | 
553  | 
build_release,  | 
| 
67766
 
603334230303
consolidated main cronjob server on virtual machine together with build_log database;
 
wenzelm 
parents: 
67763 
diff
changeset
 | 
554  | 
PAR(  | 
| 
 
603334230303
consolidated main cronjob server on virtual machine together with build_log database;
 
wenzelm 
parents: 
67763 
diff
changeset
 | 
555  | 
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
 | 
556  | 
SEQ(List(  | 
| 67080 | 557  | 
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
 | 
558  | 
SEQ(  | 
| 
 
8b7c4679c05b
parallel remote_builds2 for the sake of "AFP slow" (with theoretical data race on build_log_dirs);
 
wenzelm 
parents: 
66897 
diff
changeset
 | 
559  | 
                    for {
 | 
| 
 
8b7c4679c05b
parallel remote_builds2 for the sake of "AFP slow" (with theoretical data race on build_log_dirs);
 
wenzelm 
parents: 
66897 
diff
changeset
 | 
560  | 
(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
 | 
561  | 
(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
 | 
562  | 
} yield remote_build_history(rev, afp_rev, i, r)))),  | 
| 67008 | 563  | 
                Logger_Task("jenkins_logs", _ =>
 | 
| 68209 | 564  | 
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
 | 
565  | 
                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
 | 
566  | 
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
 | 
567  | 
                Logger_Task("build_status",
 | 
| 
67766
 
603334230303
consolidated main cronjob server on virtual machine together with build_log database;
 
wenzelm 
parents: 
67763 
diff
changeset
 | 
568  | 
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
 | 
569  | 
exit)))))  | 
| 
64153
 
769791954872
some timing and logging, similar to old isatest.log;
 
wenzelm 
parents: 
64148 
diff
changeset
 | 
570  | 
|
| 64171 | 571  | 
log_service.shutdown()  | 
| 64170 | 572  | 
|
| 
64153
 
769791954872
some timing and logging, similar to old isatest.log;
 
wenzelm 
parents: 
64148 
diff
changeset
 | 
573  | 
main_state_file.file.delete  | 
| 
 
769791954872
some timing and logging, similar to old isatest.log;
 
wenzelm 
parents: 
64148 
diff
changeset
 | 
574  | 
}  | 
| 
 
769791954872
some timing and logging, similar to old isatest.log;
 
wenzelm 
parents: 
64148 
diff
changeset
 | 
575  | 
|
| 
 
769791954872
some timing and logging, similar to old isatest.log;
 
wenzelm 
parents: 
64148 
diff
changeset
 | 
576  | 
|
| 
 
769791954872
some timing and logging, similar to old isatest.log;
 
wenzelm 
parents: 
64148 
diff
changeset
 | 
577  | 
|
| 
 
769791954872
some timing and logging, similar to old isatest.log;
 
wenzelm 
parents: 
64148 
diff
changeset
 | 
578  | 
/** command line entry point **/  | 
| 
 
769791954872
some timing and logging, similar to old isatest.log;
 
wenzelm 
parents: 
64148 
diff
changeset
 | 
579  | 
|
| 64148 | 580  | 
def main(args: Array[String])  | 
581  | 
  {
 | 
|
| 71632 | 582  | 
    Command_Line.tool {
 | 
| 64148 | 583  | 
var force = false  | 
584  | 
var verbose = false  | 
|
| 64187 | 585  | 
var exclude_task = Set.empty[String]  | 
| 64148 | 586  | 
|
587  | 
      val getopts = Getopts("""
 | 
|
588  | 
Usage: Admin/cronjob/main [OPTIONS]  | 
|
589  | 
||
590  | 
Options are:  | 
|
591  | 
-f apply force to do anything  | 
|
592  | 
-v verbose  | 
|
| 64187 | 593  | 
-x NAME exclude tasks with this name  | 
| 64148 | 594  | 
""",  | 
595  | 
"f" -> (_ => force = true),  | 
|
| 64187 | 596  | 
"v" -> (_ => verbose = true),  | 
597  | 
"x:" -> (arg => exclude_task += arg))  | 
|
| 64148 | 598  | 
|
599  | 
val more_args = getopts(args)  | 
|
600  | 
if (more_args.nonEmpty) getopts.usage()  | 
|
601  | 
||
| 
71726
 
a5fda30edae2
clarified signature: more uniform treatment of stopped/interrupted state;
 
wenzelm 
parents: 
71684 
diff
changeset
 | 
602  | 
val progress = if (verbose) new Console_Progress() else new Progress  | 
| 64148 | 603  | 
|
| 64187 | 604  | 
if (force) cronjob(progress, exclude_task)  | 
| 
64153
 
769791954872
some timing and logging, similar to old isatest.log;
 
wenzelm 
parents: 
64148 
diff
changeset
 | 
605  | 
      else error("Need to apply force to do anything")
 | 
| 64148 | 606  | 
}  | 
607  | 
}  | 
|
608  | 
}  |