Skip to content

Commit 47a24dc

Browse files
Make nightly infrastructure git (#115)
* initial attempt at git * working nightly script * add github generate nightly cron * tweaks * lint * edit file name * default path * add rose-stem to path * add fcm to fcm cron file
1 parent 6c14b76 commit 47a24dc

3 files changed

Lines changed: 503 additions & 109 deletions

File tree

nightly_testing/example_meto_configs.yaml

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ lfric_apps_excd_heads_nightly:
4444
vars:
4545
- HOUSEKEEPING=false
4646
- USE_EXCD=true
47-
time_launch: 04:45
47+
time_launch: 04:30
4848
time_clean: 04:50
4949
period: nightly_all
5050

@@ -154,13 +154,25 @@ um_heads_weekly-portio2b:
154154
groups: fcm_make_portio2b,compiler_warning_check
155155
revisions: set
156156
vars:
157-
- USE_EXAB=true
158157
- HOUSEKEEPING=false
159158
- PREBUILDS=false
160-
time_launch: 05:30
159+
time_launch: 06:00
161160
time_clean: 05:45
162161
period: weekly
163162

163+
164+
um_exz_heads_weekly:
165+
repo: um
166+
groups: ex1a_cce_n48_ga8_amip_2day
167+
revisions: heads
168+
vars:
169+
- HOUSEKEEPING=false
170+
- PREBUILDS=false
171+
- USE_EXZ=true
172+
time_launch: 03:10
173+
time_clean: 05:20
174+
period: weekly
175+
164176
###################
165177
# Nightly Testing #
166178
###################
@@ -225,7 +237,7 @@ um_set-revisions_next-cylc_nightly:
225237

226238
jules_nightly:
227239
repo: jules
228-
groups: all
240+
groups: all,fab
229241
vars:
230242
- USE_EXAB=true
231243
- HOUSEKEEPING=false
@@ -240,6 +252,6 @@ jules_excd_nightly:
240252
vars:
241253
- HOUSEKEEPING=false
242254
- USE_EXCD=true
243-
time_launch: 05:55
255+
time_launch: 06:00
244256
time_clean: 06:30
245257
period: nightly_all

nightly_testing/generate_test_suite_cron.py

Lines changed: 31 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -27,47 +27,35 @@
2727
* revisions: heads to use the HoT for sub-repos, set to use the set revisions
2828
* vars: strings that follow the -S command on the command line
2929
* monitoring: Boolean, whether to run the monitoring script on this suite
30-
* cylc_version: Can be any string beginning 7 or 8 that is a valid cylc install
30+
* cylc_version: Can be any string beginning 8 that is a valid cylc install
3131
at the site, such that `export CYLC_VERSION=<cylc_version>`
3232
works.
3333
"""
3434

3535
import argparse
3636
import os
37-
import re
3837
import subprocess
3938
import sys
40-
4139
import yaml
4240

43-
DEFAULT_CYLC_VERSION = "8"
4441
DEPENDENCIES = {
4542
"lfric_apps": [
4643
"casim",
4744
"jules",
48-
"lfric",
45+
"lfric_core",
4946
"shumlib",
5047
"socrates",
5148
"ukca",
5249
"um",
5350
],
5451
"um": ["casim", "jules", "mule", "shumlib", "socrates", "ukca"],
55-
"lfric": [],
52+
"lfric_core": [],
5653
"jules": [],
5754
"ukca": [],
5855
}
59-
CYLC_DIFFS = {
60-
"7": {
61-
"name": "--name=",
62-
"clean": "rose suite-clean",
63-
},
64-
"8": {
65-
"name": "--workflow-name=",
66-
"clean": "cylc clean --timeout=7200",
67-
},
68-
}
6956

70-
WC_DIR = os.path.join(os.environ["TMPDIR"], os.environ["USER"])
57+
CLONE_DIR = os.path.join(os.environ["TMPDIR"], os.environ["USER"])
58+
MIRROR_PATH = "/data/users/gitassist/git_mirrors/"
7159
UMDIR = os.environ["UMDIR"]
7260
PROFILE = ". /etc/profile"
7361
DATE_BASE = "date +\\%Y-\\%m-\\%d"
@@ -83,63 +71,23 @@ def run_command(command):
8371
)
8472

8573

86-
def major_cylc_version(cylc_version):
87-
"""
88-
Return the major version of cylc being requested by cylc_version
89-
Expected to be 7 or 8
90-
"""
91-
return re.split("[._-]", cylc_version)[0]
92-
93-
94-
def join_checkout_commands(repos, dir_wc):
74+
def create_git_clone_cron(repo):
9575
"""
96-
Join commands that checkout new repos
76+
Return a string of cron commands to get a git clone from the gitassist mirror
77+
Runs at 23:30 each day before all other tasks
9778
"""
9879

99-
command = ""
100-
for repo in repos:
101-
wc_path = os.path.join(dir_wc, "wc_" + repo)
102-
command += f"fcm co -q --force fcm:{repo}.xm_tr@HEAD {wc_path} ; "
103-
return command
104-
105-
106-
def fetch_working_copy_cron():
107-
"""
108-
Cleanup and then re-checkout working copies for each of the repos used
109-
Create an lfric_apps heads working copy
110-
Runs at 23:30, before all other tasks
111-
"""
112-
113-
command = "# Checkout Working Copies - every day at 23:30 #"
114-
l = len(command)
115-
command = f"{l*'#'}\n{command}\n{l*'#'}\n30 23 * * * {PROFILE} ; "
116-
command += f"rm -rf {os.path.join(WC_DIR, 'wc_*')} ; "
117-
command += join_checkout_commands(DEPENDENCIES.keys(), WC_DIR)
118-
command += lfric_heads_sed(os.path.join(WC_DIR, "wc_lfric_apps"))
80+
clone_path = os.path.join(CLONE_DIR, f"clone_{repo}")
81+
repo_mirror = os.path.join(MIRROR_PATH, "MetOffice", f"{repo}.git")
11982

83+
command = f"# Clone {repo} - every day at 23:30 #"
84+
length = len(command)
85+
command = f"{length*'#'}\n{command}\n{length*'#'}\n30 23 * * * {PROFILE} ; "
86+
command += f"rm -rf {clone_path} ; "
87+
command += f"git clone {repo_mirror} {clone_path}"
12088
return command + "\n\n\n"
12189

12290

123-
def lfric_heads_sed(wc_path):
124-
"""
125-
Add 2 sed commands to setup dependencies.sh for heads testing
126-
One command replaces all revisions with HEAD
127-
The other removes all sources - in the event a branch/working copy is left in at
128-
commit, this means that the Heads testing should still run. The set-revisions
129-
testing would show the wrong source.
130-
As this edits the working copy it copies the original copy with _heads added
131-
and returns this new wc path
132-
"""
133-
134-
wc_path_new = wc_path + "_heads"
135-
dep_path = os.path.join(wc_path_new, "dependencies.sh")
136-
137-
rstr = f"cp -rf {wc_path} {wc_path_new} ; "
138-
rstr += f'sed -i -e "s/^\\(export .*_rev=\\).*/\\1HEAD/" {dep_path} ; '
139-
rstr += f'sed -i -e "s/^\\(export .*_sources=\\).*/\\1/" {dep_path} ; '
140-
return rstr
141-
142-
14391
def generate_cron_timing_str(suite, mode):
14492
"""
14593
Return a string with the cron timing info included but no commands
@@ -229,7 +177,7 @@ def generate_clean_commands(cylc_version, name, log_file):
229177
f"{PROFILE} ; "
230178
f"export CYLC_VERSION={cylc_version} ; "
231179
f"cylc stop '{name}' >/dev/null 2>&1 ; sleep 10 ; "
232-
f"{CYLC_DIFFS[major_cylc_version(cylc_version)]['clean']} -y -q {name} "
180+
f"cylc clean --timeout=7200 -y -q {name} "
233181
f">> {log_file} 2>&1\n"
234182
)
235183

@@ -252,38 +200,22 @@ def generate_clean_cron(suite_name, suite, log_file, cylc_version):
252200
return clean_cron
253201

254202

255-
def generate_rose_stem_command(suite, wc_path, cylc_version, name):
203+
def generate_cylc_command(suite, wc_path, cylc_version, name):
256204
"""
257205
Return a string with the rose-stem command
258206
Ignores any additional source arguments
259207
"""
260208

261-
return (
209+
command = (
262210
f"export CYLC_VERSION={cylc_version} ; "
263-
+ f"rose stem --group={suite['groups']} "
264-
+ f"{CYLC_DIFFS[major_cylc_version(cylc_version)]['name']}{name} "
265-
+ f"--source={wc_path} "
211+
f"cylc vip -z g={suite['groups']} "
212+
f"-n {name} "
213+
f"-S USE_MIRRORS=true "
266214
)
267-
268-
269-
def populate_heads_sources(suite):
270-
"""
271-
Append all required dependency sources when using heads testing
272-
"""
273-
274-
heads = ""
275-
276-
if (
277-
"revisions" not in suite
278-
or suite["revisions"] != "heads"
279-
or suite["repo"] == "lfric_apps"
280-
or suite["repo"] not in DEPENDENCIES
281-
):
282-
return heads
283-
284-
for item in sorted(DEPENDENCIES[suite["repo"]]):
285-
heads += f"--source=fcm:{item}.xm_tr@HEAD "
286-
return heads
215+
if "revisions" in suite and suite["revisions"] == "heads":
216+
command += "-S USE_HEADS=true "
217+
command += f"{os.path.join(wc_path, "rose-stem")} "
218+
return command
287219

288220

289221
def populate_cl_variables(suite):
@@ -317,19 +249,13 @@ def generate_main_job(name, suite, log_file, wc_path, cylc_version):
317249
wc_path = wc_path + "_heads"
318250

319251
# Begin rose-stem command
320-
job_command += generate_rose_stem_command(suite, wc_path, cylc_version, name)
321-
322-
# Add Heads Sources if required
323-
job_command += populate_heads_sources(suite)
252+
job_command += generate_cylc_command(suite, wc_path, cylc_version, name)
324253

325254
# Add any -S vars defined
326255
job_command += populate_cl_variables(suite)
327256

328257
job_command += f">> {log_file} 2>&1"
329258

330-
if major_cylc_version(cylc_version) == "8":
331-
job_command += f" ; cylc play {name} >> {log_file} 2>&1"
332-
333259
# If this is a cylc-8-next job, check that the 8-next symlink in metomi points
334260
# elsewhere than the cylc-8 symlink
335261
if cylc_version == "8-next":
@@ -351,12 +277,12 @@ def generate_cron_job(suite_name, suite, log_file):
351277
rose-stem task and for the suite-clean task
352278
"""
353279

354-
cylc_version = suite.get("cylc_version", DEFAULT_CYLC_VERSION)
280+
cylc_version = suite.get("cylc_version", "8")
355281
cylc_version = str(cylc_version)
356282

357283
date_str = f"_$({DATE_BASE})"
358284
name = suite_name + date_str
359-
wc_path = os.path.join(WC_DIR, "wc_" + suite["repo"])
285+
wc_path = os.path.join(CLONE_DIR, "wc_" + suite["repo"])
360286

361287
header = generate_header(suite_name, suite)
362288
cron_job = generate_main_job(name, suite, log_file, wc_path, cylc_version)
@@ -381,7 +307,7 @@ def parse_cl_args():
381307
parser.add_argument(
382308
"-f",
383309
"--cron_file",
384-
default="~/Crontabs/auto-gen_testing.cron",
310+
default="~/Crontabs/auto-gen_testing_git.cron",
385311
help="The file the cronjobs will be written to."
386312
"Installation assumes this ends with '.cron'",
387313
)
@@ -422,7 +348,8 @@ def parse_cl_args():
422348
"'generate_test-suite_cron.py' file.\n# Use that script and associated "
423349
"config file to modify these cron jobs.\n\n"
424350
)
425-
main_crontab += fetch_working_copy_cron()
351+
for repo in DEPENDENCIES:
352+
main_crontab += create_git_clone_cron(repo)
426353

427354
last_repo = None
428355
for suite_name in sorted(suites.keys()):

0 commit comments

Comments
 (0)