squidient 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- squidient/__init__.py +1 -0
- squidient/builds/benchmarkbuild.py +58 -0
- squidient/builds/benchmarkbuilder.py +61 -0
- squidient/builds/build.py +195 -0
- squidient/builds/builder.py +339 -0
- squidient/builds/executablebuild.py +463 -0
- squidient/builds/predefinedbuild.py +52 -0
- squidient/cli.py +94 -0
- squidient/codecoverage/codecoverage.py +108 -0
- squidient/codecoverage/gcovrcodecoverage.py +131 -0
- squidient/codecoverage/intelcodecoverage.py +251 -0
- squidient/compilation/cmakeoptions.py +102 -0
- squidient/compilation/configgenerator.py +153 -0
- squidient/configure.py +802 -0
- squidient/connection/buildlock.py +39 -0
- squidient/connection/job.py +315 -0
- squidient/connection/ssh.py +277 -0
- squidient/connection/sshconfigchecker.py +57 -0
- squidient/data/.squidient-initialized +0 -0
- squidient/data/__init__.py +0 -0
- squidient/data/alya-config/cmake-alamak.json +16 -0
- squidient/data/alya-config/cmake-chemint.json +47 -0
- squidient/data/alya-config/cmake-clang.json +27 -0
- squidient/data/alya-config/cmake-commdom.json +9 -0
- squidient/data/alya-config/cmake-gnu.json +113 -0
- squidient/data/alya-config/cmake-intel-mn4.json +141 -0
- squidient/data/alya-config/cmake-intel.json +109 -0
- squidient/data/alya-config/cmake-mumps.json +14 -0
- squidient/data/alya-config/cmake-nvhpc.json +51 -0
- squidient/data/alya-config/cmake-pgi.json +47 -0
- squidient/data/alya-config/cmake-talp.json +35 -0
- squidient/data/alya-config/cmake-tubes.json +10 -0
- squidient/data/alya-config/cmake-xl.json +25 -0
- squidient/data/alya-config/gnu.json +136 -0
- squidient/data/alya-config/intel.json +83 -0
- squidient/data/alya-config/pgi.json +50 -0
- squidient/data/alya-config/ple.json +24 -0
- squidient/data/alya-config/xl.json +46 -0
- squidient/data/benchmarks/benchmarks.json +92 -0
- squidient/data/builds/builds-old.json +791 -0
- squidient/data/builds/builds.json +630 -0
- squidient/data/builds/cc.json +27 -0
- squidient/data/builds/defaults.json +5 -0
- squidient/data/builds/predefined-old.json +52 -0
- squidient/data/builds/predefined.json +74 -0
- squidient/data/configurations/projects.json +32 -0
- squidient/data/configurations/systems.json +333 -0
- squidient/data/configurations/tests.json +6 -0
- squidient/data/email/report.html +87 -0
- squidient/data/icons/big.png +0 -0
- squidient/data/icons/small.png +0 -0
- squidient/data/src-remote/__init__.py +0 -0
- squidient/data/src-remote/validate.py +182 -0
- squidient/data/terraform/.gitignore +1 -0
- squidient/data/terraform/aws-ec2-t3.small/.gitignore +1 -0
- squidient/data/terraform/aws-ec2-t3.small/t3.small/cloud-init-slurm-fedora.sh +171 -0
- squidient/data/terraform/aws-ec2-t3.small/t3.small/t3.small.tf +113 -0
- squidient/data/terraform/aws-ec2-t3.small/t3.small/terraform.tfvars +2 -0
- squidient/data/terraform/aws-ec2-t3.small-x2/t3.small/.gitignore +2 -0
- squidient/data/terraform/aws-ec2-t3.small-x2/t3.small/cloud-init-slurm-fedora.sh +315 -0
- squidient/data/terraform/aws-ec2-t3.small-x2/t3.small/replace-var.sh +4 -0
- squidient/data/terraform/aws-ec2-t3.small-x2/t3.small/t3.small.tf +171 -0
- squidient/data/terraform/aws-ec2-t3.small-x2/t3.small/terraform.tfvars +2 -0
- squidient/data/terraform/aws-ec2-t3.small-x3/t3.small/.gitignore +2 -0
- squidient/data/terraform/aws-ec2-t3.small-x3/t3.small/cloud-init-slurm-fedora.sh +315 -0
- squidient/data/terraform/aws-ec2-t3.small-x3/t3.small/t3.small.tf +171 -0
- squidient/data/terraform/aws-ec2-t3.small-x3/t3.small/terraform.tfvars +2 -0
- squidient/data/version/version.json +4 -0
- squidient/data/web/bb.html +104 -0
- squidient/data/web/benchmarks.html +93 -0
- squidient/data/web/btest.html +142 -0
- squidient/data/web/btests.html +125 -0
- squidient/data/web/builds.html +104 -0
- squidient/data/web/cc-gcovr.html +12 -0
- squidient/data/web/cc-intel.html +166 -0
- squidient/data/web/files.html +109 -0
- squidient/data/web/img/png/canceled.png +0 -0
- squidient/data/web/img/png/created.png +0 -0
- squidient/data/web/img/png/failed.png +0 -0
- squidient/data/web/img/png/failed_black.png +0 -0
- squidient/data/web/img/png/failed_green.png +0 -0
- squidient/data/web/img/png/file_cloud.png +0 -0
- squidient/data/web/img/png/file_config.png +0 -0
- squidient/data/web/img/png/file_ko.png +0 -0
- squidient/data/web/img/png/file_ok.png +0 -0
- squidient/data/web/img/png/skipped.png +0 -0
- squidient/data/web/img/png/squidient_logo.png +0 -0
- squidient/data/web/img/png/success.png +0 -0
- squidient/data/web/img/png/success_black.png +0 -0
- squidient/data/web/img/png/timeout.png +0 -0
- squidient/data/web/img/png/tolerance.png +0 -0
- squidient/data/web/img/png/warning.png +0 -0
- squidient/data/web/img/png/warning_black.png +0 -0
- squidient/data/web/img/png/warning_green.png +0 -0
- squidient/data/web/img/svg/canceled.svg +1 -0
- squidient/data/web/img/svg/created.svg +1 -0
- squidient/data/web/img/svg/failed.svg +54 -0
- squidient/data/web/img/svg/failed_black.svg +1 -0
- squidient/data/web/img/svg/failed_green.svg +54 -0
- squidient/data/web/img/svg/manual.svg +52 -0
- squidient/data/web/img/svg/running.svg +1 -0
- squidient/data/web/img/svg/skipped.svg +49 -0
- squidient/data/web/img/svg/success.svg +54 -0
- squidient/data/web/img/svg/success_black.svg +54 -0
- squidient/data/web/img/svg/warning.svg +54 -0
- squidient/data/web/img/svg/warning_black.svg +54 -0
- squidient/data/web/img/svg/warning_green.svg +54 -0
- squidient/data/web/index.html +146 -0
- squidient/data/web/jquery.dynatable.css +99 -0
- squidient/data/web/jquery.dynatable.js +1734 -0
- squidient/data/web/perf.html +104 -0
- squidient/data/web/test.html +143 -0
- squidient/data/web/tests.html +125 -0
- squidient/data/web/testsuite.css +68 -0
- squidient/data/web/testsuite.js +158 -0
- squidient/definitions.py +68 -0
- squidient/deployment/modulegenerator.py +53 -0
- squidient/git.py +314 -0
- squidient/init.py +63 -0
- squidient/monitor/monitor.py +204 -0
- squidient/monitor/monitordb.py +337 -0
- squidient/reports/monitorreport.py +38 -0
- squidient/reports/report.py +107 -0
- squidient/squidient.py +236 -0
- squidient/squidientmonitor.py +173 -0
- squidient/staging/staging.py +506 -0
- squidient/systems/partition.py +31 -0
- squidient/systems/platform.py +234 -0
- squidient/systems/qos.py +57 -0
- squidient/systems/queuetester.py +139 -0
- squidient/systems/reservation.py +42 -0
- squidient/systems/system.py +53 -0
- squidient/systems/systemmanager.py +47 -0
- squidient/terraform/terraform.py +442 -0
- squidient/testing/benchmarkinstance.py +73 -0
- squidient/testing/benchmarktest.py +86 -0
- squidient/testing/benchmarktester.py +165 -0
- squidient/testing/instance.py +620 -0
- squidient/testing/instancemerger.py +190 -0
- squidient/testing/test.py +269 -0
- squidient/testing/tester.py +333 -0
- squidient/utils/arguments.py +206 -0
- squidient/utils/compare.py +239 -0
- squidient/utils/lock.py +73 -0
- squidient/utils/log.py +57 -0
- squidient/utils/message.py +64 -0
- squidient/utils/package.py +85 -0
- squidient/utils/utils.py +342 -0
- squidient/utils/watchdog.py +82 -0
- squidient-1.0.0.dist-info/METADATA +22 -0
- squidient-1.0.0.dist-info/RECORD +154 -0
- squidient-1.0.0.dist-info/WHEEL +4 -0
- squidient-1.0.0.dist-info/entry_points.txt +2 -0
- squidient-1.0.0.dist-info/licenses/LICENSE.txt +674 -0
squidient/__init__.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__all__ = []
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
#########################################################################
|
|
2
|
+
# #
|
|
3
|
+
# This file is part of squidient. #
|
|
4
|
+
# #
|
|
5
|
+
# squidient is free software: you can redistribute it and/or modify #
|
|
6
|
+
# it under the terms of the GNU General Public License as published by #
|
|
7
|
+
# the Free Software Foundation, either version 3 of the License, or #
|
|
8
|
+
# (at your option) any later version. #
|
|
9
|
+
# #
|
|
10
|
+
# squidient is distributed in the hope that it will be useful, #
|
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
|
13
|
+
# GNU General Public License for more details. #
|
|
14
|
+
# #
|
|
15
|
+
# You should have received a copy of the GNU General Public License #
|
|
16
|
+
# along with squidient. If not, see <https://www.gnu.org/licenses/>. #
|
|
17
|
+
# #
|
|
18
|
+
#########################################################################
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
# -*- coding: utf-8 -*-
|
|
23
|
+
|
|
24
|
+
from .executablebuild import *
|
|
25
|
+
from ..utils.log import *
|
|
26
|
+
|
|
27
|
+
logger = logging.getLogger(logging_context)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class BenchmarkBuild(ExecutableBuild):
|
|
31
|
+
|
|
32
|
+
def __init__(self, systemManager, hash, build_id, job, ssh, config, report_directory, db):
|
|
33
|
+
super().__init__(systemManager, hash, build_id, job, ssh, config, report_directory)
|
|
34
|
+
self._queue_type = "benchmarks"
|
|
35
|
+
self._db = db
|
|
36
|
+
self._max_jobs = max_jobs_monitor
|
|
37
|
+
|
|
38
|
+
def add_to_db(self):
|
|
39
|
+
db_build = {}
|
|
40
|
+
db_build["modules"] = self._modules
|
|
41
|
+
db_build["environment"] = self._env
|
|
42
|
+
db_build["preExec"] = self._pre_exec
|
|
43
|
+
db_build["preModules"] = self._pre_modules
|
|
44
|
+
db_build["postModules"] = self._post_modules
|
|
45
|
+
db_build["tags"] = self._tags
|
|
46
|
+
db_build["codeCoverage"] = self._code_coverage
|
|
47
|
+
db_build["system"] = self._system
|
|
48
|
+
db_build["platform"] = self._platform
|
|
49
|
+
db_build["type"] = self._type
|
|
50
|
+
db_build["ctest"] = self._ctest
|
|
51
|
+
db_configuration = self._options.get_configuration()
|
|
52
|
+
self._db.add_build(name=self._build_id, compiler=self._compiler, version=self._version,
|
|
53
|
+
system=self._system, platform=self._platform, build=db_build, configuration=db_configuration)
|
|
54
|
+
|
|
55
|
+
def launch_job(self):
|
|
56
|
+
self.add_to_db()
|
|
57
|
+
return super().launch_job()
|
|
58
|
+
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
#########################################################################
|
|
2
|
+
# #
|
|
3
|
+
# This file is part of squidient. #
|
|
4
|
+
# #
|
|
5
|
+
# squidient is free software: you can redistribute it and/or modify #
|
|
6
|
+
# it under the terms of the GNU General Public License as published by #
|
|
7
|
+
# the Free Software Foundation, either version 3 of the License, or #
|
|
8
|
+
# (at your option) any later version. #
|
|
9
|
+
# #
|
|
10
|
+
# squidient is distributed in the hope that it will be useful, #
|
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
|
13
|
+
# GNU General Public License for more details. #
|
|
14
|
+
# #
|
|
15
|
+
# You should have received a copy of the GNU General Public License #
|
|
16
|
+
# along with squidient. If not, see <https://www.gnu.org/licenses/>. #
|
|
17
|
+
# #
|
|
18
|
+
#########################################################################
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
from .builder import *
|
|
23
|
+
from .benchmarkbuild import BenchmarkBuild
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class BenchmarkBuilder(Builder):
|
|
27
|
+
|
|
28
|
+
def __init__(self, systemManager, hash, job, ssh, config, db, password=""):
|
|
29
|
+
super().__init__(systemManager, hash, job, ssh, config, password)
|
|
30
|
+
self._db = db
|
|
31
|
+
|
|
32
|
+
def set_build_list(self):
|
|
33
|
+
self._build_list = self._config["benchmarks"]["builds"]
|
|
34
|
+
|
|
35
|
+
def set_report_dir(self):
|
|
36
|
+
self._report_dir = benchmark_build_report_dir
|
|
37
|
+
|
|
38
|
+
def clean_builds(self):
|
|
39
|
+
command("rm -fr " + benchmark_build_report_dir)
|
|
40
|
+
|
|
41
|
+
def create_build(self, build):
|
|
42
|
+
return BenchmarkBuild(systemManager=self._systemManager,
|
|
43
|
+
hash=self._hash,
|
|
44
|
+
build_id=build,
|
|
45
|
+
job=self._job,
|
|
46
|
+
ssh=self._ssh,
|
|
47
|
+
config=self._config,
|
|
48
|
+
report_directory=self._report_dir,
|
|
49
|
+
db=self._db)
|
|
50
|
+
|
|
51
|
+
def build_report(self):
|
|
52
|
+
jump()
|
|
53
|
+
print("Building monitor build report")
|
|
54
|
+
print_line()
|
|
55
|
+
report = {}
|
|
56
|
+
for b in self._builds:
|
|
57
|
+
self._builds[b].build_report()
|
|
58
|
+
report[b] = self._builds[b].get_report()
|
|
59
|
+
f = self._report_dir+"/benchmark_builds.json"
|
|
60
|
+
save_json(report, f)
|
|
61
|
+
json2js("benchmark_builds", f)
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
#########################################################################
|
|
2
|
+
# #
|
|
3
|
+
# This file is part of squidient. #
|
|
4
|
+
# #
|
|
5
|
+
# squidient is free software: you can redistribute it and/or modify #
|
|
6
|
+
# it under the terms of the GNU General Public License as published by #
|
|
7
|
+
# the Free Software Foundation, either version 3 of the License, or #
|
|
8
|
+
# (at your option) any later version. #
|
|
9
|
+
# #
|
|
10
|
+
# squidient is distributed in the hope that it will be useful, #
|
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
|
13
|
+
# GNU General Public License for more details. #
|
|
14
|
+
# #
|
|
15
|
+
# You should have received a copy of the GNU General Public License #
|
|
16
|
+
# along with squidient. If not, see <https://www.gnu.org/licenses/>. #
|
|
17
|
+
# #
|
|
18
|
+
#########################################################################
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
# -*- coding: utf-8 -*-
|
|
23
|
+
|
|
24
|
+
from ..utils.utils import open_critical_json
|
|
25
|
+
from ..definitions import build_file
|
|
26
|
+
from ..utils.log import *
|
|
27
|
+
|
|
28
|
+
logger = logging.getLogger(logging_context)
|
|
29
|
+
|
|
30
|
+
class Build:
|
|
31
|
+
|
|
32
|
+
def __init__(self, build_id):
|
|
33
|
+
|
|
34
|
+
self._build_id = build_id
|
|
35
|
+
|
|
36
|
+
#These variables propagates
|
|
37
|
+
|
|
38
|
+
self._pre_modules = []
|
|
39
|
+
self._modules = []
|
|
40
|
+
self._post_modules = []
|
|
41
|
+
self._pre_exec = []
|
|
42
|
+
self._env = []
|
|
43
|
+
self._tags = []
|
|
44
|
+
self._compiler = ""
|
|
45
|
+
self._code_coverage = ""
|
|
46
|
+
self._configuration = ""
|
|
47
|
+
self._exclusive_tests = ""
|
|
48
|
+
self._flex = ""
|
|
49
|
+
self._file = ""
|
|
50
|
+
self._job = ""
|
|
51
|
+
self._platform = ""
|
|
52
|
+
self._lock = ""
|
|
53
|
+
self._runnable = ""
|
|
54
|
+
self._timeout = ""
|
|
55
|
+
self._timeoffset = ""
|
|
56
|
+
self._type = ""
|
|
57
|
+
self._ctest = ""
|
|
58
|
+
self._threads = ""
|
|
59
|
+
self._version = ""
|
|
60
|
+
self._system = ""
|
|
61
|
+
self._cc_tool = ""
|
|
62
|
+
self._sbatch = {}
|
|
63
|
+
|
|
64
|
+
#these variables don't propagate
|
|
65
|
+
self._installable = ""
|
|
66
|
+
self._alias = ""
|
|
67
|
+
|
|
68
|
+
#Configure build
|
|
69
|
+
self._builds = open_critical_json(build_file)
|
|
70
|
+
self.fill(build_id)
|
|
71
|
+
|
|
72
|
+
if self._timeout == "":
|
|
73
|
+
self._timeout = "02:00:00"
|
|
74
|
+
|
|
75
|
+
if self._timeoffset == "":
|
|
76
|
+
self._timeoffset = "00:00:00"
|
|
77
|
+
|
|
78
|
+
if type(self._ctest) != bool:
|
|
79
|
+
self._ctest = True
|
|
80
|
+
if type(self._exclusive_tests) != bool:
|
|
81
|
+
self._exclusive_tests = False
|
|
82
|
+
|
|
83
|
+
def fill(self, build_id):
|
|
84
|
+
build = self._builds[build_id]
|
|
85
|
+
if len(self._modules) == 0 and "modules" in build:
|
|
86
|
+
self._modules = build["modules"]
|
|
87
|
+
if len(self._env) == 0 and "environment" in build:
|
|
88
|
+
self._env = build["environment"]
|
|
89
|
+
if len(self._pre_exec) == 0 and "preExec" in build:
|
|
90
|
+
self._pre_exec = build["preExec"]
|
|
91
|
+
if len(self._pre_modules) == 0 and "preModules" in build:
|
|
92
|
+
self._pre_modules = build["preModules"]
|
|
93
|
+
if len(self._post_modules) == 0 and "postModules" in build:
|
|
94
|
+
self._post_modules = build["postModules"]
|
|
95
|
+
if len(self._tags) == 0 and "tags" in build:
|
|
96
|
+
self._tags = build["tags"]
|
|
97
|
+
if len(self._sbatch) == 0 and "sbatch" in build:
|
|
98
|
+
self._sbatch = build["sbatch"]
|
|
99
|
+
if self._cc_tool == "" and "cc_tool" in build:
|
|
100
|
+
self._cc_tool = build["cc_tool"]
|
|
101
|
+
if self._compiler == "" and "compiler" in build:
|
|
102
|
+
self._compiler = build["compiler"]
|
|
103
|
+
if self._code_coverage == "" and "codeCoverage" in build:
|
|
104
|
+
self._code_coverage = build["codeCoverage"]
|
|
105
|
+
if self._exclusive_tests == "" and "exclusive" in build:
|
|
106
|
+
self._exclusive_tests = build["exclusive"]
|
|
107
|
+
if self._configuration == "" and "configuration" in build:
|
|
108
|
+
self._configuration = build["configuration"]
|
|
109
|
+
if self._file == "" and "file" in build:
|
|
110
|
+
self._file = build["file"]
|
|
111
|
+
if self._flex == "" and "flex" in build:
|
|
112
|
+
self._flex = build["flex"]
|
|
113
|
+
if self._job == "" and "job" in build:
|
|
114
|
+
self._job = build["job"]
|
|
115
|
+
if self._system == "" and "system" in build:
|
|
116
|
+
self._system = build["system"]
|
|
117
|
+
if self._platform == "" and "platform" in build:
|
|
118
|
+
self._platform = build["platform"]
|
|
119
|
+
if self._lock == "" and "lock" in build:
|
|
120
|
+
self._lock = build["lock"]
|
|
121
|
+
if self._runnable == "" and "runnable" in build:
|
|
122
|
+
self._runnable = build["runnable"]
|
|
123
|
+
if self._threads == "" and "threads" in build:
|
|
124
|
+
self._threads = build["threads"]
|
|
125
|
+
if self._type == "" and "type" in build:
|
|
126
|
+
self._type = build["type"]
|
|
127
|
+
if self._ctest == "" and "ctest" in build:
|
|
128
|
+
self._ctest = build["ctest"]
|
|
129
|
+
if self._timeout == "" and "timeout" in build:
|
|
130
|
+
self._timeout = build["timeout"]
|
|
131
|
+
if self._timeoffset == "" and "timeOffset" in build:
|
|
132
|
+
self._timeoffset = build["timeOffset"]
|
|
133
|
+
if self._version == "" and "version" in build:
|
|
134
|
+
self._version = build["version"]
|
|
135
|
+
if self._alias == "":
|
|
136
|
+
if "alias" in build:
|
|
137
|
+
self._alias = build["alias"]
|
|
138
|
+
else:
|
|
139
|
+
self._alias = self._build_id
|
|
140
|
+
if self._installable == "":
|
|
141
|
+
if "installable" in build:
|
|
142
|
+
self._installable = build["installable"]
|
|
143
|
+
else:
|
|
144
|
+
self._installable = False
|
|
145
|
+
if "from" in build:
|
|
146
|
+
self.fill(build["from"])
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
def get_tags(self):
|
|
150
|
+
return self._tags
|
|
151
|
+
|
|
152
|
+
def get_modules(self):
|
|
153
|
+
return self._modules
|
|
154
|
+
|
|
155
|
+
def get_pre_modules(self):
|
|
156
|
+
return self._pre_modules
|
|
157
|
+
|
|
158
|
+
def get_post_modules(self):
|
|
159
|
+
return self._post_modules
|
|
160
|
+
|
|
161
|
+
def get_pre_exec(self):
|
|
162
|
+
return self._pre_exec
|
|
163
|
+
|
|
164
|
+
def get_env(self):
|
|
165
|
+
return self._env
|
|
166
|
+
|
|
167
|
+
def get_compiler(self):
|
|
168
|
+
return self._compiler
|
|
169
|
+
|
|
170
|
+
def get_runnable(self):
|
|
171
|
+
return self._runnable
|
|
172
|
+
|
|
173
|
+
def get_version(self):
|
|
174
|
+
return self._version
|
|
175
|
+
|
|
176
|
+
def get_system(self):
|
|
177
|
+
return self._system
|
|
178
|
+
|
|
179
|
+
def get_platform(self):
|
|
180
|
+
return self._platform
|
|
181
|
+
|
|
182
|
+
def get_build_id(self):
|
|
183
|
+
return self._build_id
|
|
184
|
+
|
|
185
|
+
def get_code_coverage(self):
|
|
186
|
+
return self._code_coverage
|
|
187
|
+
|
|
188
|
+
def get_exclusive_tests(self):
|
|
189
|
+
return self._exclusive_tests
|
|
190
|
+
|
|
191
|
+
def get_cc_tool(self):
|
|
192
|
+
return self._cc_tool
|
|
193
|
+
|
|
194
|
+
def get_timeoffset(self):
|
|
195
|
+
return self._timeoffset
|
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
#########################################################################
|
|
2
|
+
# #
|
|
3
|
+
# This file is part of squidient. #
|
|
4
|
+
# #
|
|
5
|
+
# squidient is free software: you can redistribute it and/or modify #
|
|
6
|
+
# it under the terms of the GNU General Public License as published by #
|
|
7
|
+
# the Free Software Foundation, either version 3 of the License, or #
|
|
8
|
+
# (at your option) any later version. #
|
|
9
|
+
# #
|
|
10
|
+
# squidient is distributed in the hope that it will be useful, #
|
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
|
13
|
+
# GNU General Public License for more details. #
|
|
14
|
+
# #
|
|
15
|
+
# You should have received a copy of the GNU General Public License #
|
|
16
|
+
# along with squidient. If not, see <https://www.gnu.org/licenses/>. #
|
|
17
|
+
# #
|
|
18
|
+
#########################################################################
|
|
19
|
+
import sys
|
|
20
|
+
|
|
21
|
+
from ..utils.utils import *
|
|
22
|
+
from ..terraform.terraform import *
|
|
23
|
+
from ..git import Git
|
|
24
|
+
from .executablebuild import ExecutableBuild
|
|
25
|
+
import time
|
|
26
|
+
|
|
27
|
+
from ..definitions import *
|
|
28
|
+
|
|
29
|
+
logger = logging.getLogger(logging_context)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class Builder:
|
|
33
|
+
|
|
34
|
+
def __init__(self, systemManager, hash, job, ssh, config, password=""):
|
|
35
|
+
self._systemManager = systemManager
|
|
36
|
+
self._hash = hash
|
|
37
|
+
self._alya_repository = None
|
|
38
|
+
self._config = config
|
|
39
|
+
self._builds = {}
|
|
40
|
+
self._start_time = time.time()
|
|
41
|
+
self._finished_builds = {}
|
|
42
|
+
self._pending_builds = {}
|
|
43
|
+
self._gotten_builds = {}
|
|
44
|
+
self._unlaunched_builds = {}
|
|
45
|
+
self._platform_ready = {}
|
|
46
|
+
self._ssh = ssh
|
|
47
|
+
self._job = job
|
|
48
|
+
self._password = password
|
|
49
|
+
self._build_list = {}
|
|
50
|
+
self.set_build_list()
|
|
51
|
+
self._report_dir = ""
|
|
52
|
+
self.set_report_dir()
|
|
53
|
+
self._p = ""
|
|
54
|
+
|
|
55
|
+
def cd_push(self, path):
|
|
56
|
+
"""
|
|
57
|
+
Switch to git repository
|
|
58
|
+
"""
|
|
59
|
+
self._p = os.getcwd()
|
|
60
|
+
|
|
61
|
+
if not os.path.isdir(path):
|
|
62
|
+
logger.error(path + " does not exist")
|
|
63
|
+
return False
|
|
64
|
+
try:
|
|
65
|
+
os.chdir(path)
|
|
66
|
+
except:
|
|
67
|
+
logger.error("Changing directory to " + path + " failed")
|
|
68
|
+
return False
|
|
69
|
+
return True
|
|
70
|
+
|
|
71
|
+
def cd_pop(self):
|
|
72
|
+
try:
|
|
73
|
+
os.chdir(self._p)
|
|
74
|
+
except:
|
|
75
|
+
logger.error("Changing directory back failed")
|
|
76
|
+
raise RuntimeError("An internal error happened...")
|
|
77
|
+
|
|
78
|
+
def set_build_list(self):
|
|
79
|
+
self._build_list = self._config["staging"]["builds"]
|
|
80
|
+
|
|
81
|
+
def set_report_dir(self):
|
|
82
|
+
self._report_dir = build_report_dir
|
|
83
|
+
|
|
84
|
+
def clean_builds(self):
|
|
85
|
+
command("rm -fr " + build_report_dir)
|
|
86
|
+
|
|
87
|
+
def run_builds(self, terraform):
|
|
88
|
+
self.send_alya()
|
|
89
|
+
self.clean_builds()
|
|
90
|
+
sorted_builds = {}
|
|
91
|
+
for system in self._systemManager.get_systems():
|
|
92
|
+
sorted_builds[system] = {}
|
|
93
|
+
for platform in self._systemManager.get_platforms(system):
|
|
94
|
+
sorted_builds[system][platform] = []
|
|
95
|
+
for b in self._build_list:
|
|
96
|
+
bui = self.init_build(b)
|
|
97
|
+
self._unlaunched_builds[b] = bui
|
|
98
|
+
sorted_builds[bui.get_system()][bui.get_platform()].append(b)
|
|
99
|
+
while len(self._unlaunched_builds) > 0:
|
|
100
|
+
for system in self._systemManager.get_systems():
|
|
101
|
+
for platform in self._systemManager.get_platforms(system):
|
|
102
|
+
if terraform.get_platform_state(self._ssh, system, platform):
|
|
103
|
+
for b in sorted_builds[system][platform]:
|
|
104
|
+
self.run_build(self._unlaunched_builds[b])
|
|
105
|
+
if self._unlaunched_builds[b].get_job_id() != -1:
|
|
106
|
+
self._builds[b] = self._unlaunched_builds[b]
|
|
107
|
+
del self._unlaunched_builds[b]
|
|
108
|
+
else:
|
|
109
|
+
raise Exception
|
|
110
|
+
sorted_builds[system][platform] = []
|
|
111
|
+
time.sleep(60)
|
|
112
|
+
print_line()
|
|
113
|
+
|
|
114
|
+
def terminate_builds(self):
|
|
115
|
+
finished = False
|
|
116
|
+
jump()
|
|
117
|
+
print("Waiting for builds to finish:")
|
|
118
|
+
print_line()
|
|
119
|
+
while not finished:
|
|
120
|
+
finished = self.check_builds()
|
|
121
|
+
return self.get_status()
|
|
122
|
+
|
|
123
|
+
def get_status(self):
|
|
124
|
+
for b in self._finished_builds:
|
|
125
|
+
if not self._finished_builds[b]:
|
|
126
|
+
return False
|
|
127
|
+
return True
|
|
128
|
+
|
|
129
|
+
def get_failed(self):
|
|
130
|
+
failed = 0
|
|
131
|
+
for b in self._finished_builds:
|
|
132
|
+
if not self._finished_builds[b]:
|
|
133
|
+
failed += 1
|
|
134
|
+
return failed
|
|
135
|
+
|
|
136
|
+
def get_total(self):
|
|
137
|
+
return len(self._builds)
|
|
138
|
+
|
|
139
|
+
def next_valid_build(self, _print=True, oneprint=False, stop_on_error=False):
|
|
140
|
+
__print = _print
|
|
141
|
+
while len(self._pending_builds) == 0:
|
|
142
|
+
if self.check_builds(__print, __print, False):
|
|
143
|
+
if self.get_failed() > 1 and stop_on_error:
|
|
144
|
+
return None
|
|
145
|
+
break
|
|
146
|
+
__print = __print and not oneprint
|
|
147
|
+
build = None
|
|
148
|
+
for b in self._pending_builds:
|
|
149
|
+
build = b
|
|
150
|
+
break
|
|
151
|
+
if build is not None:
|
|
152
|
+
self._pending_builds.pop(build)
|
|
153
|
+
return self._builds[build]
|
|
154
|
+
else:
|
|
155
|
+
return None
|
|
156
|
+
|
|
157
|
+
def get_build(self):
|
|
158
|
+
self.check_builds(False, False, False)
|
|
159
|
+
if len(self._pending_builds) > 0:
|
|
160
|
+
for build in self._pending_builds:
|
|
161
|
+
if build not in self._gotten_builds:
|
|
162
|
+
self._gotten_builds[build] = self._pending_builds[build]
|
|
163
|
+
return self._builds[build]
|
|
164
|
+
for build in self._builds:
|
|
165
|
+
if build not in self._gotten_builds:
|
|
166
|
+
self._gotten_builds[build] = True
|
|
167
|
+
return self._builds[build]
|
|
168
|
+
return None
|
|
169
|
+
|
|
170
|
+
def ready(self, build):
|
|
171
|
+
self.check_builds(False, False, False)
|
|
172
|
+
if build.get_build_id() in self._pending_builds:
|
|
173
|
+
self._pending_builds.pop(build.get_build_id())
|
|
174
|
+
return True
|
|
175
|
+
return False
|
|
176
|
+
|
|
177
|
+
def build_report(self):
|
|
178
|
+
jump()
|
|
179
|
+
print("Building build report")
|
|
180
|
+
print_line()
|
|
181
|
+
report = {}
|
|
182
|
+
for b in self._builds:
|
|
183
|
+
if b in self._finished_builds:
|
|
184
|
+
self._builds[b].build_report()
|
|
185
|
+
report[b] = self._builds[b].get_report()
|
|
186
|
+
f = self._report_dir+"/builds.json"
|
|
187
|
+
save_json(report, f)
|
|
188
|
+
json2js("builds", f)
|
|
189
|
+
|
|
190
|
+
def check_build_job_status(self, build):
|
|
191
|
+
status = self._builds[build].check_job_status()
|
|
192
|
+
if "Finished" in status:
|
|
193
|
+
finished = True
|
|
194
|
+
else:
|
|
195
|
+
finished = False
|
|
196
|
+
return {"finished": finished, "status": status}
|
|
197
|
+
|
|
198
|
+
def check_build_status(self, build):
|
|
199
|
+
status = self._builds[build].check_build_status()
|
|
200
|
+
return status
|
|
201
|
+
|
|
202
|
+
def check_builds(self, _print=True, minutes=True, back=True):
|
|
203
|
+
count = len(self._builds) + 1
|
|
204
|
+
if not minutes:
|
|
205
|
+
count -= 1
|
|
206
|
+
count = str(count)
|
|
207
|
+
check = True
|
|
208
|
+
time.sleep(1)
|
|
209
|
+
status = {}
|
|
210
|
+
one_success = False
|
|
211
|
+
for b in self._builds:
|
|
212
|
+
if b in self._finished_builds:
|
|
213
|
+
status["finished"] = True
|
|
214
|
+
test = True
|
|
215
|
+
if self._finished_builds[b]:
|
|
216
|
+
status["status"] = "Success"
|
|
217
|
+
else:
|
|
218
|
+
status["status"] = "Failed"
|
|
219
|
+
else:
|
|
220
|
+
status = self.check_build_job_status(b)
|
|
221
|
+
if status["finished"]:
|
|
222
|
+
test = True
|
|
223
|
+
if self.check_build_status(b):
|
|
224
|
+
status["status"] = "Success"
|
|
225
|
+
self._finished_builds[b] = True
|
|
226
|
+
self._pending_builds[b] = True
|
|
227
|
+
one_success = not back
|
|
228
|
+
else:
|
|
229
|
+
status["status"] = "Failed"
|
|
230
|
+
self._finished_builds[b] = False
|
|
231
|
+
self._builds[b].build_report()
|
|
232
|
+
else:
|
|
233
|
+
test = False
|
|
234
|
+
check = check and test
|
|
235
|
+
if _print:
|
|
236
|
+
print('{:<35}{:>16}'.format("- " + b[:31] + ": ", status["status"]))
|
|
237
|
+
if _print and minutes:
|
|
238
|
+
print("Elapsed time: ", int((time.time() - self._start_time) / 60), "minutes")
|
|
239
|
+
if (not check) and _print and not one_success:
|
|
240
|
+
print("\033[" + count + "A", end='')
|
|
241
|
+
time.sleep(1)
|
|
242
|
+
return check
|
|
243
|
+
|
|
244
|
+
def get_alya(self, fetch=True, force_https=False):
|
|
245
|
+
jump()
|
|
246
|
+
self._alya_repository = Git(git_ssh=self._config["alyaGitRepository"]["ssh"],
|
|
247
|
+
git_https=self._config["alyaGitRepository"]["https"],
|
|
248
|
+
user=self._config["alyaGitRepository"]["user"],
|
|
249
|
+
branch=self._config["alyaGitRepository"]["branch"],
|
|
250
|
+
dir="alya",
|
|
251
|
+
password=self._password,
|
|
252
|
+
force_https=force_https)
|
|
253
|
+
if fetch:
|
|
254
|
+
print("Cloning/Updating the alya git repository...")
|
|
255
|
+
self._alya_repository.clone_or_update_tests()
|
|
256
|
+
print_line()
|
|
257
|
+
self._revision = self._alya_repository.revision_short()
|
|
258
|
+
self._revision_long = self._alya_repository.revision_long()
|
|
259
|
+
return self._alya_repository
|
|
260
|
+
|
|
261
|
+
def download_alamak(self, user="", token=""):
|
|
262
|
+
jump()
|
|
263
|
+
if self._config["alamak"]["enable"]:
|
|
264
|
+
print("Cloning alamak")
|
|
265
|
+
self.cd_push(self._config["alamak"]["path"])
|
|
266
|
+
critical_command("./alamak.sh --clean")
|
|
267
|
+
if self._config["alamak"]["revision"] is not None:
|
|
268
|
+
ref = "--revision " + self._config["alamak"]["revision"]
|
|
269
|
+
else:
|
|
270
|
+
ref = "--branch " + self._config["alamak"]["branch"]
|
|
271
|
+
alamak_command = ""
|
|
272
|
+
if user != "" and token != "":
|
|
273
|
+
alamak_command = "./alamak.sh --https " + ref + " --user " + user + " --token " + token
|
|
274
|
+
else:
|
|
275
|
+
alamak_command = "./alamak.sh --ssh " + ref
|
|
276
|
+
try:
|
|
277
|
+
critical_command(alamak_command, silent=True)
|
|
278
|
+
except:
|
|
279
|
+
print("The cloning of alamak has failed. Showing the error and terminating...")
|
|
280
|
+
command("./alamak.sh --clean")
|
|
281
|
+
print(command(alamak_command, output=True, silent=True))
|
|
282
|
+
raise Exception
|
|
283
|
+
self.cd_pop()
|
|
284
|
+
print_line()
|
|
285
|
+
|
|
286
|
+
def get_alya_repository(self):
|
|
287
|
+
return self._alya_repository
|
|
288
|
+
|
|
289
|
+
def send_alya(self):
|
|
290
|
+
jump()
|
|
291
|
+
for system in self._systemManager.get_systems():
|
|
292
|
+
print("System: " + system)
|
|
293
|
+
print("Cleaning the remote build directory...")
|
|
294
|
+
self._ssh.rmdir(system=system, path=remote_bin_dir, server_path=True)
|
|
295
|
+
if self._config["clean"]:
|
|
296
|
+
self._ssh.rmdir(system=system, path=remote_build_dir, server_path=True)
|
|
297
|
+
self._ssh.rmdir(system=system, path=remote_cc_dir, server_path=True)
|
|
298
|
+
#self._ssh.ssh(system=system, cmd="rm " + remote_cc_dir + "/*/*.dyn", server_path=True)
|
|
299
|
+
print("Creating the remote build directory infrastructure...")
|
|
300
|
+
self._ssh.mkdir(system=system, path=remote_bin_dir, server_path=True)
|
|
301
|
+
self._ssh.mkdir(system=system, path=remote_build_dir, server_path=True)
|
|
302
|
+
self._ssh.mkdir(system=system, path=remote_cc_dir, server_path=True)
|
|
303
|
+
print("Uploading alya...")
|
|
304
|
+
self._ssh.rsync_send(system=system, local=alya_dir, options="--exclude .git/", delete=True, server_path=True, critical=True)
|
|
305
|
+
print_line()
|
|
306
|
+
|
|
307
|
+
def create_build(self, build):
|
|
308
|
+
return ExecutableBuild(systemManager=self._systemManager, hash=self._hash, build_id=build, job=self._job, ssh=self._ssh,
|
|
309
|
+
config=self._config, report_directory=self._report_dir)
|
|
310
|
+
|
|
311
|
+
def init_build(self, build):
|
|
312
|
+
jump()
|
|
313
|
+
print("Build: " + build)
|
|
314
|
+
b = self.create_build(build)
|
|
315
|
+
print("\tGenerating alya configuration file...")
|
|
316
|
+
b.generate_configuration()
|
|
317
|
+
print("\tGenerating job file...")
|
|
318
|
+
b.generate_job()
|
|
319
|
+
print("\tUploading files...")
|
|
320
|
+
b.send_files()
|
|
321
|
+
return b
|
|
322
|
+
|
|
323
|
+
def run_build(self, b):
|
|
324
|
+
time.sleep(5)
|
|
325
|
+
print("\tSubmitting job...")
|
|
326
|
+
job_id = b.launch_job()
|
|
327
|
+
if job_id == -1:
|
|
328
|
+
print("\tJob submission has failed!")
|
|
329
|
+
else:
|
|
330
|
+
print("\tJob id: " + str(job_id))
|
|
331
|
+
|
|
332
|
+
def get_builds(self):
|
|
333
|
+
return self._builds
|
|
334
|
+
|
|
335
|
+
def get_alya_revision(self):
|
|
336
|
+
return self._revision
|
|
337
|
+
|
|
338
|
+
def get_alya_revision_long(self):
|
|
339
|
+
return self._revision_long
|