Skip to content

Commit 70d7ac6

Browse files
committed
add add_runtime_files function
1 parent 67ec3ae commit 70d7ac6

File tree

8 files changed

+79
-18
lines changed

8 files changed

+79
-18
lines changed

src/ibek/globals.py

+6-1
Original file line numberDiff line numberDiff line change
@@ -124,9 +124,14 @@ def IOC_LIBS(self):
124124

125125
@property
126126
def RUNTIME_DEBS(self):
127-
"""ibek-support list of declared libs"""
127+
"""ibek-support list of declared deb packages to install in runtime stage"""
128128
return self.SUPPORT / "configure" / "runtime_debs"
129129

130+
@property
131+
def RUNTIME_FILES(self):
132+
"""ibek-support list of files to copy to the runtime stage"""
133+
return self.SUPPORT / "configure" / "runtime_files_list"
134+
130135

131136
# Folder containing templates for IOC src etc.
132137
TEMPLATES = Path(__file__).parent / "templates"

src/ibek/ioc_cmds/assets.py

+11-9
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,11 @@ def extract_assets(
4747
"""
4848

4949
if GLOBALS.STATIC_BUILD:
50-
# static builds only need database files from support modules
51-
asset_matches = "db"
50+
# static builds only need database and .proto files from support modules
51+
asset_matches = "db|*/protocol"
5252
else:
53-
# dynamically linked builds need binaries
54-
asset_matches = "bin|db|lib"
53+
# dynamically linked builds need binaries and protocol files
54+
asset_matches = "bin|db|lib|*/protocol"
5555

5656
# chdir out of the folders we will move
5757
os.chdir(source)
@@ -66,18 +66,20 @@ def extract_assets(
6666
Path.readlink(
6767
GLOBALS.IOC_FOLDER
6868
).parent, # get contents of IOC folder and its source (parent)
69-
Path("/venv"), # get the virtualenv
70-
] + list(
71-
source.glob("ibek*")
72-
) # get ibek-support and related folders
69+
GLOBALS.EPICS_ROOT.parent / "venv", # virtualenv is a peer to /epics
70+
]
7371
else:
7472
default_assets = []
7573

7674
# folder names with binary files in them
7775
binary = ["bin", "lib"]
7876

77+
# get the list of additional files supplied by add_runtime_files
78+
with GLOBALS.RUNTIME_FILES.open("r") as f:
79+
runtime_files = [Path(line.strip()) for line in f.readlines()]
80+
7981
# move the default assets and extras in their entirety
80-
extra_files = default_assets + extras
82+
extra_files = default_assets + extras + runtime_files
8183
for asset in extra_files:
8284
src = source / asset
8385
if src.exists():

src/ibek/support_cmds/commands.py

+14
Original file line numberDiff line numberDiff line change
@@ -340,3 +340,17 @@ def generate_schema(
340340
typer.echo(Support.get_schema())
341341
else:
342342
output.write_text(Support.get_schema())
343+
344+
345+
@support_cli.command()
346+
def add_runtime_files(
347+
files: List[str] = typer.Argument(
348+
None, help="list of file or folders to add to the runtime image"
349+
),
350+
):
351+
"""
352+
Adds to the list of folders or filesthat are copied over to the runtime
353+
stage of the container build.
354+
"""
355+
files = files or []
356+
add_list_to_file(GLOBALS.RUNTIME_FILES, files)

tests/conftest.py

+19-8
Original file line numberDiff line numberDiff line change
@@ -63,15 +63,26 @@ def entity_factory():
6363
def tmp_epics_root(samples: Path, tmp_path: Path, mocker: MockerFixture):
6464
# create an partially populated epics_root structure in a temporary folder
6565
epics = tmp_path / "epics"
66+
epics_source = samples / "epics"
6667
epics.mkdir()
67-
shutil.copytree(samples / "epics" / "pvi-defs", epics / "pvi-defs")
68-
shutil.copytree(samples / "epics" / "support", epics / "support")
69-
Path.mkdir(epics / "opi")
70-
Path.mkdir(epics / "epics-base")
71-
Path.mkdir(epics / "ioc/config", parents=True)
72-
Path.mkdir(epics / "ibek-defs")
73-
Path.mkdir(epics / "runtime")
74-
68+
# a dummy venv for testing extract_assets
69+
Path.mkdir(tmp_path / "venv")
70+
71+
# create the minimal structure under epics root
72+
files = epics_source.glob("*")
73+
for f in files:
74+
if f.is_dir():
75+
shutil.copytree(f, epics / f.name)
76+
else:
77+
shutil.copy(f, epics / f.name)
78+
Path.mkdir(epics / "opi", exist_ok=True)
79+
Path.mkdir(epics / "epics-base", exist_ok=True)
80+
Path.mkdir(epics / "generic-source" / "ioc" / "config", parents=True)
81+
(epics / "ioc").symlink_to(epics / "generic-source" / "ioc")
82+
Path.mkdir(epics / "ibek-defs", exist_ok=True)
83+
Path.mkdir(epics / "runtime", exist_ok=True)
84+
85+
# patch the global EPICS_ROOT to point to this temporary folder
7586
mocker.patch.object(GLOBALS, "_EPICS_ROOT", epics)
7687

7788
# this should not be needed - what gives?

tests/samples/epics/runtime_file

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
dummy file for testing add_runtime_files
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
dummy file for testing add_runtime_files
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
dummy file for testing add_runtime_files

tests/test_unit.py

+26
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,19 @@
33
"""
44

55
import dataclasses
6+
import shutil
7+
from pathlib import Path
68

79
import jinja2
810
import pytest
911

1012
from ibek.commands import semver_compare
1113
from ibek.ioc import id_to_entity
14+
from ibek.ioc_cmds.assets import extract_assets
1215
from ibek.ioc_factory import IocFactory
1316
from ibek.parameters import IdParam, ObjectParam
1417
from ibek.support import EntityModel, Support
18+
from ibek.support_cmds.commands import add_runtime_files
1519
from ibek.utils import UTILS
1620

1721

@@ -89,3 +93,25 @@ def test_strict():
8993
my_template = "{{ person.name ~ ' of age ' ~ person.height }}"
9094
with pytest.raises(jinja2.exceptions.UndefinedError):
9195
text = UTILS.render({"person": p}, my_template)
96+
97+
98+
def test_extract_assets(tmp_epics_root: Path, samples: Path):
99+
"""
100+
Test the extract_assets function
101+
"""
102+
runtime_files = [
103+
str(tmp_epics_root / "runtime_file"),
104+
str(tmp_epics_root / "runtime_folder"),
105+
]
106+
add_runtime_files(runtime_files)
107+
108+
dest = Path("/tmp/ibek_test_assests")
109+
shutil.rmtree(dest, ignore_errors=True)
110+
dest.mkdir()
111+
112+
extract_assets(dest, tmp_epics_root, [], True)
113+
new_epics_root = list(dest.glob("tmp/*/*/*/epics"))[0]
114+
115+
assert Path.exists(new_epics_root / "runtime_file")
116+
assert Path.exists(new_epics_root / "runtime_folder/text1.txt")
117+
assert Path.exists(new_epics_root / "runtime_folder/text2.txt")

0 commit comments

Comments
 (0)