fm-weck 1.3.0__py3-none-any.whl → 1.4.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.
- fm_weck/__init__.py +1 -1
- fm_weck/cli.py +58 -10
- fm_weck/config.py +38 -13
- fm_weck/engine.py +49 -8
- fm_weck/image_mgr.py +9 -2
- fm_weck/resources/__init__.py +2 -2
- fm_weck/resources/run_with_overlay.sh +22 -4
- fm_weck/runexec_mode.py +52 -0
- fm_weck/serve.py +0 -27
- {fm_weck-1.3.0.dist-info → fm_weck-1.4.0.dist-info}/METADATA +1 -1
- {fm_weck-1.3.0.dist-info → fm_weck-1.4.0.dist-info}/RECORD +13 -12
- {fm_weck-1.3.0.dist-info → fm_weck-1.4.0.dist-info}/WHEEL +1 -1
- {fm_weck-1.3.0.dist-info → fm_weck-1.4.0.dist-info}/entry_points.txt +0 -0
fm_weck/__init__.py
CHANGED
fm_weck/cli.py
CHANGED
|
@@ -14,15 +14,29 @@ from functools import cache
|
|
|
14
14
|
from pathlib import Path
|
|
15
15
|
from typing import Any, Callable, Optional, Tuple, Union
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
try:
|
|
18
|
+
from fm_tools.benchexec_helper import DataModel
|
|
19
|
+
except ImportError:
|
|
20
|
+
from enum import Enum
|
|
21
|
+
|
|
22
|
+
class DataModel(Enum):
|
|
23
|
+
"""
|
|
24
|
+
Enum representing the data model of the tool.
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
LP64 = "LP64"
|
|
28
|
+
ILP32 = "ILP32"
|
|
29
|
+
|
|
30
|
+
def __str__(self):
|
|
31
|
+
return self.value
|
|
32
|
+
|
|
18
33
|
|
|
19
34
|
from fm_weck import Config
|
|
20
35
|
from fm_weck.config import _SEARCH_ORDER
|
|
21
36
|
from fm_weck.resources import iter_fm_data, iter_properties
|
|
22
37
|
|
|
23
38
|
from . import __version__
|
|
24
|
-
from .
|
|
25
|
-
from .serve import run_guided, run_manual, run_runexec, setup_fm_tool
|
|
39
|
+
from .exceptions import NoImageError
|
|
26
40
|
|
|
27
41
|
logger = logging.getLogger(__name__)
|
|
28
42
|
|
|
@@ -84,12 +98,22 @@ def parse(raw_args: list[str]) -> Tuple[Callable[[], None], Namespace]:
|
|
|
84
98
|
default=None,
|
|
85
99
|
)
|
|
86
100
|
|
|
101
|
+
loglevels_lower = ["debug", "info", "warning", "error", "critical"]
|
|
102
|
+
loglevels = loglevels_lower + [level.upper() for level in loglevels_lower]
|
|
87
103
|
parser.add_argument(
|
|
88
104
|
"--loglevel",
|
|
89
|
-
choices=
|
|
105
|
+
choices=loglevels,
|
|
106
|
+
metavar="LEVEL",
|
|
107
|
+
action="store",
|
|
108
|
+
default=None,
|
|
109
|
+
help="Set the log level. Valid values are: " + ", ".join(loglevels_lower),
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
parser.add_argument(
|
|
113
|
+
"--logfile",
|
|
90
114
|
action="store",
|
|
115
|
+
help="Path to the log file.",
|
|
91
116
|
default=None,
|
|
92
|
-
help="Set the log level.",
|
|
93
117
|
)
|
|
94
118
|
|
|
95
119
|
parser.add_argument(
|
|
@@ -204,6 +228,16 @@ def parse(raw_args: list[str]) -> Tuple[Callable[[], None], Namespace]:
|
|
|
204
228
|
default=None,
|
|
205
229
|
)
|
|
206
230
|
|
|
231
|
+
# Arguments passed though to the container manager (i.e., docker or podman)
|
|
232
|
+
runexec.add_argument(
|
|
233
|
+
"--container-long-opt",
|
|
234
|
+
dest="container_long_opts",
|
|
235
|
+
help="Arguments passed as long options (prepending --) directly to the container manager "
|
|
236
|
+
"(e.g., docker or podman). Each usage passes additional arguments to the container manager.",
|
|
237
|
+
action="append",
|
|
238
|
+
nargs="+",
|
|
239
|
+
)
|
|
240
|
+
|
|
207
241
|
runexec.add_argument("argument_list", metavar="args", nargs="*", help="Arguments for runexec.")
|
|
208
242
|
runexec.set_defaults(main=main_runexec)
|
|
209
243
|
|
|
@@ -264,14 +298,19 @@ def resolve_property(prop_name: str) -> Path:
|
|
|
264
298
|
return property_choice_map()[prop_name]
|
|
265
299
|
|
|
266
300
|
|
|
267
|
-
def
|
|
301
|
+
def set_log_options(loglevel: Optional[str], logfile: Optional[str], config: dict[str, Any]):
|
|
268
302
|
level = "WARNING"
|
|
269
303
|
level = loglevel.upper() if loglevel else config.get("logging", {}).get("level", level)
|
|
270
|
-
|
|
304
|
+
if logfile:
|
|
305
|
+
logging.basicConfig(level=level, filename=logfile)
|
|
306
|
+
else:
|
|
307
|
+
logging.basicConfig(level=level)
|
|
271
308
|
logging.getLogger("httpcore").setLevel("WARNING")
|
|
272
309
|
|
|
273
310
|
|
|
274
311
|
def main_run(args: argparse.Namespace):
|
|
312
|
+
from .serve import run_guided
|
|
313
|
+
|
|
275
314
|
if not args.TOOL:
|
|
276
315
|
logger.error("No fm-tool given. Aborting...")
|
|
277
316
|
return 1
|
|
@@ -300,15 +339,20 @@ def main_run(args: argparse.Namespace):
|
|
|
300
339
|
|
|
301
340
|
|
|
302
341
|
def main_runexec(args: argparse.Namespace):
|
|
342
|
+
from .runexec_mode import run_runexec
|
|
343
|
+
|
|
303
344
|
run_runexec(
|
|
304
345
|
benchexec_package=args.benchexec_package,
|
|
305
346
|
use_image=args.use_image,
|
|
306
347
|
configuration=Config(),
|
|
348
|
+
extra_container_args=args.container_long_opts or [],
|
|
307
349
|
command=args.argument_list,
|
|
308
350
|
)
|
|
309
351
|
|
|
310
352
|
|
|
311
353
|
def main_manual(args: argparse.Namespace):
|
|
354
|
+
from .serve import run_manual
|
|
355
|
+
|
|
312
356
|
if not args.TOOL:
|
|
313
357
|
logger.error("No fm-tool given. Aborting...")
|
|
314
358
|
return 1
|
|
@@ -328,6 +372,8 @@ def main_manual(args: argparse.Namespace):
|
|
|
328
372
|
|
|
329
373
|
|
|
330
374
|
def main_install(args: argparse.Namespace):
|
|
375
|
+
from .serve import setup_fm_tool
|
|
376
|
+
|
|
331
377
|
for tool in args.TOOL:
|
|
332
378
|
try:
|
|
333
379
|
fm_data = resolve_tool(tool)
|
|
@@ -343,6 +389,8 @@ def main_install(args: argparse.Namespace):
|
|
|
343
389
|
|
|
344
390
|
|
|
345
391
|
def main_shell(args: argparse.Namespace):
|
|
392
|
+
from .engine import Engine
|
|
393
|
+
|
|
346
394
|
if not args.TOOL:
|
|
347
395
|
engine = Engine.from_config(Config())
|
|
348
396
|
else:
|
|
@@ -378,7 +426,7 @@ Please specify an image in the fm-tool yml file or add a configuration.
|
|
|
378
426
|
|
|
379
427
|
To add a configuration you can do the following (on POSIX Terminals):
|
|
380
428
|
|
|
381
|
-
printf '[defaults]\\nimage = "<your_image>"' > .weck
|
|
429
|
+
printf '[defaults]\\nimage = "<your_image>"' > .fm-weck
|
|
382
430
|
|
|
383
431
|
Replace <your_image> with the image you want to use.
|
|
384
432
|
"""
|
|
@@ -393,7 +441,7 @@ To specify an image add
|
|
|
393
441
|
[defaults]
|
|
394
442
|
image = "your_image"
|
|
395
443
|
|
|
396
|
-
to your .weck file.
|
|
444
|
+
to your .fm-weck file.
|
|
397
445
|
"""
|
|
398
446
|
|
|
399
447
|
logger.error(text, tool, config)
|
|
@@ -402,7 +450,7 @@ to your .weck file.
|
|
|
402
450
|
def cli(raw_args: list[str]):
|
|
403
451
|
help_callback, args = parse(raw_args)
|
|
404
452
|
configuration = Config().load(args.config)
|
|
405
|
-
|
|
453
|
+
set_log_options(args.loglevel, args.logfile, configuration)
|
|
406
454
|
if args.dry_run:
|
|
407
455
|
Config().set_dry_run(True)
|
|
408
456
|
|
fm_weck/config.py
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
#
|
|
6
6
|
# SPDX-License-Identifier: Apache-2.0
|
|
7
7
|
|
|
8
|
+
import importlib.resources as pkg_resources
|
|
8
9
|
import logging
|
|
9
10
|
import os
|
|
10
11
|
import shutil
|
|
@@ -14,8 +15,20 @@ from functools import cache
|
|
|
14
15
|
from pathlib import Path
|
|
15
16
|
from typing import Any, Callable, Iterable, Optional, Tuple, TypeVar
|
|
16
17
|
|
|
17
|
-
|
|
18
|
-
from fm_tools.fmdata import FmData
|
|
18
|
+
try:
|
|
19
|
+
from fm_tools.fmdata import FmData
|
|
20
|
+
except ImportError:
|
|
21
|
+
|
|
22
|
+
class FmData:
|
|
23
|
+
def __init__(self, data, version):
|
|
24
|
+
raise ImportError("fm_tools is not imported.")
|
|
25
|
+
|
|
26
|
+
def get_actor_name(self):
|
|
27
|
+
raise ImportError("fm_tools is not imported.")
|
|
28
|
+
|
|
29
|
+
def get_version(self):
|
|
30
|
+
raise ImportError("fm_tools is not imported.")
|
|
31
|
+
|
|
19
32
|
|
|
20
33
|
from fm_weck.resources import RUN_WITH_OVERLAY, RUNEXEC_SCRIPT
|
|
21
34
|
|
|
@@ -167,21 +180,30 @@ class Config(object):
|
|
|
167
180
|
return not (sys.platform.startswith("linux") or sys.platform == "darwin")
|
|
168
181
|
|
|
169
182
|
def make_runexec_script_available(self) -> Path:
|
|
170
|
-
return self.make_script_available(RUNEXEC_SCRIPT
|
|
183
|
+
return self.make_script_available(RUNEXEC_SCRIPT)
|
|
171
184
|
|
|
172
|
-
def make_script_available(self,
|
|
185
|
+
def make_script_available(self, target_name: str = RUN_WITH_OVERLAY) -> Path:
|
|
173
186
|
script_dir = self.cache_location / ".scripts"
|
|
174
187
|
target = script_dir / target_name
|
|
188
|
+
|
|
175
189
|
if not (target.exists() and target.is_file()):
|
|
176
190
|
script_dir.mkdir(parents=True, exist_ok=True)
|
|
177
|
-
|
|
191
|
+
|
|
192
|
+
# Try to copy from package resources
|
|
193
|
+
try:
|
|
194
|
+
with pkg_resources.path("fm_weck.resources", target_name) as source_path:
|
|
195
|
+
shutil.copy(source_path, target)
|
|
196
|
+
except FileNotFoundError:
|
|
197
|
+
logging.error(f"Resource {target_name} not found in package.")
|
|
198
|
+
return None
|
|
178
199
|
else:
|
|
179
|
-
# Compare
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
200
|
+
# Compare modification time if the file exists
|
|
201
|
+
with pkg_resources.path("fm_weck.resources", target_name) as source_path:
|
|
202
|
+
if source_path.stat().st_mtime > target.stat().st_mtime:
|
|
203
|
+
shutil.copy(source_path, target)
|
|
204
|
+
else:
|
|
205
|
+
logging.debug(f"Using existing {target_name} script")
|
|
206
|
+
return target
|
|
185
207
|
|
|
186
208
|
if Config._system_is_not_posix():
|
|
187
209
|
return target
|
|
@@ -195,13 +217,16 @@ class Config(object):
|
|
|
195
217
|
except OSError as e:
|
|
196
218
|
logging.error(
|
|
197
219
|
f"Failed to set executable bit: {e}. "
|
|
198
|
-
"
|
|
199
|
-
"running the script inside of the container."
|
|
220
|
+
"This may lead to permission errors when running the script in the container."
|
|
200
221
|
)
|
|
201
222
|
|
|
223
|
+
return target
|
|
224
|
+
|
|
202
225
|
|
|
203
226
|
@cache
|
|
204
227
|
def parse_fm_data(fm_data: Path, version: Optional[str]) -> FmData:
|
|
228
|
+
import yaml
|
|
229
|
+
|
|
205
230
|
if not fm_data.exists() or not fm_data.is_file():
|
|
206
231
|
raise FileNotFoundError(f"fm data file {fm_data} does not exist")
|
|
207
232
|
|
fm_weck/engine.py
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
import logging
|
|
9
9
|
import shutil
|
|
10
|
+
import signal
|
|
10
11
|
import subprocess
|
|
11
12
|
from abc import ABC, abstractmethod
|
|
12
13
|
from functools import cached_property, singledispatchmethod
|
|
@@ -14,7 +15,17 @@ from pathlib import Path
|
|
|
14
15
|
from tempfile import mkdtemp
|
|
15
16
|
from typing import List, Optional, Union
|
|
16
17
|
|
|
17
|
-
|
|
18
|
+
try:
|
|
19
|
+
from fm_tools.fmdata import FmData, FmImageConfig
|
|
20
|
+
except ImportError:
|
|
21
|
+
# Mock the FmData and FmImageConfig class for type checking
|
|
22
|
+
class FmData:
|
|
23
|
+
def get_images(self):
|
|
24
|
+
pass
|
|
25
|
+
|
|
26
|
+
class FmImageConfig:
|
|
27
|
+
pass
|
|
28
|
+
|
|
18
29
|
|
|
19
30
|
from fm_weck.config import Config, parse_fm_data
|
|
20
31
|
from fm_weck.exceptions import NoImageError
|
|
@@ -66,6 +77,24 @@ class Engine(ABC):
|
|
|
66
77
|
f"{source}:{target}",
|
|
67
78
|
]
|
|
68
79
|
|
|
80
|
+
def add_container_long_opt(self, arg: list[str]):
|
|
81
|
+
"""
|
|
82
|
+
Add a long option to the container command.
|
|
83
|
+
If the first element of the list does not start with "--", it will be prepended.
|
|
84
|
+
Example:
|
|
85
|
+
add_container_long_opt(["--option", "value"]) -> --option value
|
|
86
|
+
add_container_long_opt(["option", "value"]) -> --option value
|
|
87
|
+
"""
|
|
88
|
+
|
|
89
|
+
if not arg:
|
|
90
|
+
raise ValueError("Argument must not be empty.")
|
|
91
|
+
|
|
92
|
+
base = arg[0]
|
|
93
|
+
if not base.startswith("--"):
|
|
94
|
+
base = f"--{base}"
|
|
95
|
+
|
|
96
|
+
self.extra_args["container_args"] = self.extra_args.get("container_args", []) + [base] + arg[1:]
|
|
97
|
+
|
|
69
98
|
@abstractmethod
|
|
70
99
|
def benchexec_capabilities(self):
|
|
71
100
|
raise NotImplementedError
|
|
@@ -261,15 +290,27 @@ class Engine(ABC):
|
|
|
261
290
|
return tag
|
|
262
291
|
|
|
263
292
|
def _run_process(self, command: tuple[str, ...] | list[str]):
|
|
293
|
+
process = None # To make sure process is defined if a signal is caught early
|
|
294
|
+
|
|
295
|
+
def terminate_process_group(signal_received, frame):
|
|
296
|
+
if process:
|
|
297
|
+
logging.info("Received signal %s. Terminating container process.", signal_received)
|
|
298
|
+
process.send_signal(signal.SIGTERM)
|
|
299
|
+
|
|
300
|
+
# Register signal handler
|
|
301
|
+
signal.signal(signal.SIGINT, terminate_process_group)
|
|
302
|
+
signal.signal(signal.SIGTERM, terminate_process_group)
|
|
303
|
+
|
|
304
|
+
logger.debug("\n\nRunning command:\n%s\n\n", " ".join(map(str, command)))
|
|
264
305
|
if self.log_file is None:
|
|
265
306
|
process = subprocess.Popen(command)
|
|
266
|
-
|
|
267
|
-
|
|
307
|
+
else:
|
|
308
|
+
self.log_file.parent.mkdir(parents=True, exist_ok=True)
|
|
309
|
+
with self.log_file.open("wb") as f:
|
|
310
|
+
process = subprocess.Popen(command, stdout=f, stderr=f)
|
|
268
311
|
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
process = subprocess.Popen(command, stdout=f, stderr=f)
|
|
272
|
-
process.wait()
|
|
312
|
+
assert process is not None, "Process should be defined at this point."
|
|
313
|
+
process.wait()
|
|
273
314
|
|
|
274
315
|
def run(self, *command: str) -> None:
|
|
275
316
|
if self.image is None:
|
|
@@ -279,7 +320,7 @@ class Engine(ABC):
|
|
|
279
320
|
logger.debug("Running: %s", command)
|
|
280
321
|
if self.dry_run:
|
|
281
322
|
print("Command to be executed:")
|
|
282
|
-
print(" ".join(command))
|
|
323
|
+
print(" ".join(map(str, command)))
|
|
283
324
|
return
|
|
284
325
|
|
|
285
326
|
self._run_process(command)
|
fm_weck/image_mgr.py
CHANGED
|
@@ -9,8 +9,14 @@ import logging
|
|
|
9
9
|
from pathlib import Path
|
|
10
10
|
from typing import TYPE_CHECKING
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
from
|
|
12
|
+
try:
|
|
13
|
+
from fm_tools.fmdata import FmImageConfig
|
|
14
|
+
except ImportError:
|
|
15
|
+
|
|
16
|
+
class FmImageConfig:
|
|
17
|
+
def __init__(self, full_images, base_images, required_packages):
|
|
18
|
+
raise ImportError("fm_tools is not imported.")
|
|
19
|
+
|
|
14
20
|
|
|
15
21
|
from fm_weck.exceptions import NoImageError
|
|
16
22
|
|
|
@@ -48,6 +54,7 @@ class ImageMgr(object):
|
|
|
48
54
|
image_cmd = engine.image_from(CONTAINERFILE)
|
|
49
55
|
image_cmd.base_image(image.base_images[0])
|
|
50
56
|
image_cmd.packages(image.required_packages)
|
|
57
|
+
from yaspin import yaspin
|
|
51
58
|
|
|
52
59
|
with yaspin(text="Building image", color="cyan") as spinner:
|
|
53
60
|
tag = image_cmd.build()
|
fm_weck/resources/__init__.py
CHANGED
|
@@ -15,9 +15,9 @@ CONTAINERFILE = resource_dir / "Containerfile"
|
|
|
15
15
|
# to the wheel file under fm_weck/resources/fm_tools
|
|
16
16
|
FM_DATA_LOCATION = resource_dir / "fm_tools"
|
|
17
17
|
PROPERTY_LOCATION = resource_dir / "properties"
|
|
18
|
-
RUN_WITH_OVERLAY =
|
|
18
|
+
RUN_WITH_OVERLAY = "run_with_overlay.sh"
|
|
19
19
|
BENCHEXEC_WHL = resource_dir / "BenchExec-3.25-py3-none-any.whl"
|
|
20
|
-
RUNEXEC_SCRIPT =
|
|
20
|
+
RUNEXEC_SCRIPT = "runexec"
|
|
21
21
|
|
|
22
22
|
|
|
23
23
|
def iter_fm_data():
|
|
@@ -20,10 +20,28 @@ cp -r "/home/fm-weck_cache/$TOOL_DIR" /tmp/overlay/
|
|
|
20
20
|
# Assume the user $PWD is mounted to home/cwd
|
|
21
21
|
#Mount the overlay
|
|
22
22
|
mount -t overlay overlay -o lowerdir=/home/cwd:/tmp/overlay/"$TOOL_DIR",upperdir=/tmp/overlay/upper,workdir=/tmp/overlay/work /home/_cwd
|
|
23
|
-
cd /home/_cwd && "$@"
|
|
24
23
|
|
|
25
|
-
#
|
|
26
|
-
|
|
27
|
-
|
|
24
|
+
# Change directory and execute the command
|
|
25
|
+
cd /home/_cwd || exit 1
|
|
26
|
+
|
|
27
|
+
"$@" &
|
|
28
|
+
PID=$!
|
|
29
|
+
|
|
30
|
+
# Handle signals and delegate to the process
|
|
31
|
+
trap 'kill -TERM $PID' INT TERM
|
|
32
|
+
|
|
33
|
+
# Wait for the process and handle its termination correctly
|
|
34
|
+
wait $PID
|
|
35
|
+
trap - TERM INT
|
|
36
|
+
wait $PID # wait for JVM to exit after signal delegation
|
|
37
|
+
EXIT_STATUS=$?
|
|
38
|
+
|
|
39
|
+
# Check if upper directory has data to copy to output
|
|
40
|
+
if [ -n "$(ls -A /tmp/overlay/upper)" ]; then
|
|
28
41
|
cp -r /tmp/overlay/upper/* /home/output
|
|
29
42
|
fi
|
|
43
|
+
|
|
44
|
+
# Clean up mounted filesystems
|
|
45
|
+
umount /tmp/overlay
|
|
46
|
+
|
|
47
|
+
exit $EXIT_STATUS
|
fm_weck/runexec_mode.py
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# This file is part of fm-weck: executing fm-tools in containerized environments.
|
|
2
|
+
# https://gitlab.com/sosy-lab/software/fm-weck
|
|
3
|
+
#
|
|
4
|
+
# SPDX-FileCopyrightText: 2024 Dirk Beyer <https://www.sosy-lab.org>
|
|
5
|
+
#
|
|
6
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
7
|
+
|
|
8
|
+
import logging
|
|
9
|
+
import shutil
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
from typing import Optional
|
|
12
|
+
|
|
13
|
+
from fm_weck.resources import BENCHEXEC_WHL
|
|
14
|
+
from fm_weck.runexec_util import mountable_absolute_paths_of_command
|
|
15
|
+
|
|
16
|
+
from .config import Config
|
|
17
|
+
from .engine import CACHE_MOUNT_LOCATION, Engine
|
|
18
|
+
|
|
19
|
+
logger = logging.getLogger(__name__)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def run_runexec(
|
|
23
|
+
benchexec_package: Optional[Path],
|
|
24
|
+
use_image: Optional[str],
|
|
25
|
+
configuration: Config,
|
|
26
|
+
extra_container_args: list[list[str]],
|
|
27
|
+
command: list[str],
|
|
28
|
+
):
|
|
29
|
+
if use_image is not None:
|
|
30
|
+
configuration.set_default_image(use_image)
|
|
31
|
+
|
|
32
|
+
engine = Engine.from_config(configuration)
|
|
33
|
+
engine.add_benchexec_capabilities = True
|
|
34
|
+
|
|
35
|
+
if benchexec_package is not None:
|
|
36
|
+
engine.mount(benchexec_package.parent.absolute(), "/home/__fm_weck_benchexec")
|
|
37
|
+
engine.env["PYTHONPATH"] = f"/home/__fm_weck_benchexec/{benchexec_package.name}"
|
|
38
|
+
else:
|
|
39
|
+
# Default to the bundled benchexec package
|
|
40
|
+
benchexec_package = configuration.get_shelve_path_for_benchexec()
|
|
41
|
+
shutil.copyfile(BENCHEXEC_WHL, benchexec_package)
|
|
42
|
+
engine.env["PYTHONPATH"] = f"{CACHE_MOUNT_LOCATION}/.lib/benchexec.whl"
|
|
43
|
+
|
|
44
|
+
for path in mountable_absolute_paths_of_command(command):
|
|
45
|
+
engine.mount(path, path)
|
|
46
|
+
|
|
47
|
+
for arg in extra_container_args:
|
|
48
|
+
engine.add_container_long_opt(arg)
|
|
49
|
+
|
|
50
|
+
configuration.make_runexec_script_available()
|
|
51
|
+
|
|
52
|
+
engine.run(f"{CACHE_MOUNT_LOCATION}/.scripts/runexec", *command)
|
fm_weck/serve.py
CHANGED
|
@@ -16,9 +16,6 @@ from typing import Optional, Tuple, Union
|
|
|
16
16
|
from fm_tools import FmData
|
|
17
17
|
from fm_tools.benchexec_helper import DataModel
|
|
18
18
|
|
|
19
|
-
from fm_weck.resources import BENCHEXEC_WHL
|
|
20
|
-
from fm_weck.runexec_util import mountable_absolute_paths_of_command
|
|
21
|
-
|
|
22
19
|
from .config import Config, parse_fm_data
|
|
23
20
|
from .engine import CACHE_MOUNT_LOCATION, Engine
|
|
24
21
|
|
|
@@ -149,27 +146,3 @@ def run_manual(
|
|
|
149
146
|
logger.debug("Using executable %s", executable)
|
|
150
147
|
logger.debug("Assembled command %s", [executable, *command])
|
|
151
148
|
engine.run(executable, *command)
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
def run_runexec(benchexec_package: Optional[Path], use_image: Optional[str], configuration: Config, command: list[str]):
|
|
155
|
-
if use_image is not None:
|
|
156
|
-
configuration.set_default_image(use_image)
|
|
157
|
-
|
|
158
|
-
engine = Engine.from_config(configuration)
|
|
159
|
-
engine.add_benchexec_capabilities = True
|
|
160
|
-
|
|
161
|
-
if benchexec_package is not None:
|
|
162
|
-
engine.mount(benchexec_package, "/home/__fm_weck_benchexec")
|
|
163
|
-
engine.env["PYTHONPATH"] = "/home/__fm_weck_benchexec"
|
|
164
|
-
else:
|
|
165
|
-
# Default to the bundled benchexec package
|
|
166
|
-
benchexec_package = configuration.get_shelve_path_for_benchexec()
|
|
167
|
-
shutil.copyfile(BENCHEXEC_WHL, benchexec_package)
|
|
168
|
-
engine.env["PYTHONPATH"] = f"{CACHE_MOUNT_LOCATION}/.lib/benchexec.whl"
|
|
169
|
-
|
|
170
|
-
for path in mountable_absolute_paths_of_command(command):
|
|
171
|
-
engine.mount(path, path)
|
|
172
|
-
|
|
173
|
-
configuration.make_runexec_script_available()
|
|
174
|
-
|
|
175
|
-
engine.run(f"{CACHE_MOUNT_LOCATION}/.scripts/runexec", *command)
|
|
@@ -1,17 +1,18 @@
|
|
|
1
|
-
fm_weck/__init__.py,sha256=
|
|
1
|
+
fm_weck/__init__.py,sha256=fhbHcAv5kJ0_nbClYRr0E5_e6Ok5w9IOIYrtlbRYEDQ,351
|
|
2
2
|
fm_weck/__main__.py,sha256=E7z4-9t6To3hbIPjRPu6iW17YCrtqpDSbFSpd9pX4NA,350
|
|
3
|
-
fm_weck/cli.py,sha256=
|
|
4
|
-
fm_weck/config.py,sha256=
|
|
5
|
-
fm_weck/engine.py,sha256=
|
|
3
|
+
fm_weck/cli.py,sha256=THirNpxB3jKDlKIb1Hpo3upOnsjGY7edTfqbVq7Gp1Y,13277
|
|
4
|
+
fm_weck/config.py,sha256=AAp5qPZfx2Gh-43jySzfHzHOEmbduHJalA7guV9SIzI,7340
|
|
5
|
+
fm_weck/engine.py,sha256=uaUiH1Wu7QnBwh4CEw1cdy6FtlyCfPMyU9X2m8gQWnE,13664
|
|
6
6
|
fm_weck/exceptions.py,sha256=D_3xPdWkmsY4Dn7k4oGHEAZc2Ner2p3sw2t8lhEHrGI,281
|
|
7
|
-
fm_weck/image_mgr.py,sha256=
|
|
7
|
+
fm_weck/image_mgr.py,sha256=f1RlmQPBiMrsqPyH1Rtfb8WMp2YBq-7z-Rto_kCfS7U,1861
|
|
8
|
+
fm_weck/runexec_mode.py,sha256=JWddzH_33O-hzjVkSVQ9-YUhEVFm23AXBBoSGmj-mvg,1697
|
|
8
9
|
fm_weck/runexec_util.py,sha256=l6_3aeHg4WV6fPpRNPMzb5dGrw9aau4bDQDPi2AfLTQ,1006
|
|
9
|
-
fm_weck/serve.py,sha256=
|
|
10
|
+
fm_weck/serve.py,sha256=YGGT6ULClC1vifARr5Jl0LZgS72il7nMeoo6tf76sL4,5195
|
|
10
11
|
fm_weck/resources/BenchExec-3.25-py3-none-any.whl,sha256=87QrHJum5CHhpTrQlQpamHMnlkMzJE5lM4SlJg-Y9jk,718841
|
|
11
12
|
fm_weck/resources/BenchExec-3.25-py3-none-any.whl.license,sha256=Nq2Mwgn_pyr6ZZrTT095QPtFP3hr15ZeIRIaY0B7eC8,201
|
|
12
13
|
fm_weck/resources/Containerfile,sha256=MltxP1of9klsQFNR8WyngRTJrPwxQTF4C9ennRxVqSo,391
|
|
13
|
-
fm_weck/resources/__init__.py,sha256=
|
|
14
|
-
fm_weck/resources/run_with_overlay.sh,sha256=
|
|
14
|
+
fm_weck/resources/__init__.py,sha256=FiA_c0huVEKM0EKHFqzMNjq0qAYTRXvfcnHraTzj0QQ,1023
|
|
15
|
+
fm_weck/resources/run_with_overlay.sh,sha256=v1gV_6kMQ0v9BQ3chgDqI1MAOLHbPWeeTC52aCqVpEM,1162
|
|
15
16
|
fm_weck/resources/runexec,sha256=ogIBO38HLu9C9kDTTANBgAqVnH-UIF1bSJ9d3DSjyF4,462
|
|
16
17
|
fm_weck/resources/properties/coverage-branches.prp,sha256=Gl2r1cgBFoh4M2laa8dVGhteHkL04oiBRLzxz_hbkEU,56
|
|
17
18
|
fm_weck/resources/properties/coverage-branches.prp.license,sha256=KzWZF1bpljIbdvwfzfWoP4DLMq6W1jXNN6WXWF0fxY0,214
|
|
@@ -129,7 +130,7 @@ fm_weck/resources/fm_tools/wasp-c.yml,sha256=NWEb2vpIBu75kZJdEq0am8Mpi2HFu5nhDI1
|
|
|
129
130
|
fm_weck/resources/fm_tools/wit4java.yml,sha256=SukwwE46DsDmZouAwHhr_aaOjxIaeOrIS7o7P4eDWX0,1243
|
|
130
131
|
fm_weck/resources/fm_tools/witch.yml,sha256=5d5aYmkrlG78M-RLdDbdi6EJWOfD0CskWtJWGXtwEyI,1152
|
|
131
132
|
fm_weck/resources/fm_tools/witnesslint.yml,sha256=Y6A2TXPyjVxZ9Fhmyd7GOKY7x1_jXjshvmrIM4uW96A,3085
|
|
132
|
-
fm_weck-1.
|
|
133
|
-
fm_weck-1.
|
|
134
|
-
fm_weck-1.
|
|
135
|
-
fm_weck-1.
|
|
133
|
+
fm_weck-1.4.0.dist-info/METADATA,sha256=Xs9-dvBYxTnLw0EmCUAkgXPO_WwK-gustbuCAhJpe_g,2771
|
|
134
|
+
fm_weck-1.4.0.dist-info/WHEEL,sha256=C2FUgwZgiLbznR-k0b_5k3Ai_1aASOXDss3lzCUsUug,87
|
|
135
|
+
fm_weck-1.4.0.dist-info/entry_points.txt,sha256=toWpKCSY1u593MPnI_xW5gnwlnkerP4AvmPQ1s2nPgY,50
|
|
136
|
+
fm_weck-1.4.0.dist-info/RECORD,,
|
|
File without changes
|