Skip to content

Commit 0662683

Browse files
authored
Merge branch 'master' into feature/add_config
2 parents 6f8b34a + 5f869c1 commit 0662683

File tree

18 files changed

+639
-156
lines changed

18 files changed

+639
-156
lines changed

libioc/Config/Jail/BaseConfig.py

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,16 +79,16 @@ class BaseConfig(dict):
7979
8080
"""
8181

82-
data: libioc.Config.Data.Data
82+
_data: libioc.Config.Data.Data
8383
special_properties: 'libioc.Config.Jail.Properties.Properties'
8484

8585
def __init__(
8686
self,
8787
logger: typing.Optional['libioc.Logger.Logger']=None
8888
) -> None:
8989

90-
if self.data is None:
91-
self.data = libioc.Config.Data.Data()
90+
if hasattr(self, "_data") is False:
91+
self._data = libioc.Config.Data.Data()
9292
self.logger = libioc.helpers_object.init_logger(self, logger)
9393

9494
Properties = libioc.Config.Jail.Properties.JailConfigProperties
@@ -97,6 +97,34 @@ def __init__(
9797
logger=self.logger
9898
)
9999

100+
@property
101+
def data(self) -> libioc.Config.Data.Data:
102+
"""Return the data object."""
103+
return self._data
104+
105+
@data.setter
106+
def data(self, new_data: libioc.Config.Data.Data) -> None:
107+
"""Validate and set the data object."""
108+
if isinstance(new_data, libioc.Config.Data.Data) is False:
109+
raise TypeError("data needs to be a flat dict structure")
110+
new_data_keys = new_data.keys()
111+
old_data = self._data
112+
try:
113+
self._data = dict()
114+
identifier_keys = ["id", "name", "uuid"]
115+
for key in identifier_keys:
116+
if key in new_data_keys:
117+
self["id"] = new_data[key]
118+
break
119+
for key in new_data_keys:
120+
if key in identifier_keys:
121+
continue
122+
self[key] = new_data[key]
123+
except Exception:
124+
self.logger.verbose("Configuration was not modified")
125+
self._data = old_data
126+
raise
127+
100128
def clone(
101129
self,
102130
data: InputData,
@@ -142,7 +170,8 @@ def clone(
142170
new_data = libioc.Config.Data.Data(data)
143171
if current_id is not None:
144172
new_data["id"] = current_id
145-
self.data = new_data
173+
for key, value in new_data.items():
174+
self.data[key] = value
146175

147176
def read(self, data: dict, skip_on_error: bool=False) -> None:
148177
"""

libioc/Config/Jail/Defaults.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@
8080
"allow_quotas": 0,
8181
"allow_socket_af": 0,
8282
"allow_tun": 0,
83-
"allow_vmm": 0,
83+
"allow_vmm": False,
8484
"available": 0,
8585
"bpf": None,
8686
"comment": None,
@@ -129,7 +129,7 @@
129129
"jail_zfs": False,
130130
"jail_zfs_dataset": None,
131131
"jail_zfs_mountpoint": None,
132-
"provisioning": {
132+
"provision": {
133133
"method": None,
134134
"source": None,
135135
"rev": "master"

libioc/Config/Jail/File/Fstab.py

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -147,10 +147,7 @@ def __hash__(self) -> int:
147147
return hash(None)
148148

149149

150-
class Fstab(
151-
libioc.Config.Jail.File.ResourceConfig,
152-
collections.MutableSequence
153-
):
150+
class Fstab(collections.MutableSequence):
154151
"""
155152
Fstab configuration file wrapper.
156153
@@ -203,10 +200,7 @@ def path(self) -> str:
203200
path = self.file
204201
else:
205202
path = f"{self.jail.dataset.mountpoint}/{self.file}"
206-
self._require_path_relative_to_resource(
207-
filepath=path,
208-
resource=self.jail
209-
)
203+
self.jail._require_relative_path(path)
210204

211205
return path
212206

@@ -400,7 +394,16 @@ def add_line(
400394
401395
Use save() to write changes to the fstab file.
402396
"""
403-
if self.__contains__(line):
397+
if type(line) == FstabLine:
398+
if self.jail._is_path_relative(line["destination"]) is False:
399+
line = FstabLine(line) # clone to prevent mutation
400+
line["destination"] = libioc.Types.AbsolutePath("/".join([
401+
self.jail.root_path,
402+
line["destination"].lstrip("/")
403+
]))
404+
405+
line_already_exists = self.__contains__(line)
406+
if line_already_exists:
404407
destination = line["destination"]
405408
if replace is True:
406409
self.logger.verbose(
@@ -425,11 +428,13 @@ def add_line(
425428

426429
if type(line) == FstabLine:
427430
# destination is always relative to the jail resource
428-
if line["destination"].startswith(self.jail.root_path) is False:
429-
line["destination"] = libioc.Types.AbsolutePath("/".join([
431+
if self.jail._is_path_relative(line["destination"]) is False:
432+
_destination = libioc.Types.AbsolutePath("/".join([
430433
self.jail.root_path,
431434
line["destination"].strip("/")
432435
]))
436+
self.jail._require_relative_path(_destination)
437+
line["destination"] = _destination
433438

434439
libioc.helpers.require_no_symlink(str(line["destination"]))
435440

@@ -442,12 +447,17 @@ def add_line(
442447
os.makedirs(line["destination"], 0o700)
443448

444449
if (auto_mount_jail and self.jail.running) is True:
450+
destination = line["destination"]
451+
self.jail._require_relative_path(destination)
452+
self.logger.verbose(
453+
f"auto-mount {destination}"
454+
)
445455
mount_command = [
446456
"/sbin/mount",
447457
"-o", line["options"],
448458
"-t", line["type"],
449459
line["source"],
450-
line["destination"]
460+
destination
451461
]
452462
libioc.helpers.exec(mount_command, logger=self.logger)
453463
_source = line["source"]
@@ -632,7 +642,7 @@ def insert(
632642
# find FstabAutoPlaceholderLine instead
633643
line = list(filter(
634644
lambda x: isinstance(x, FstabAutoPlaceholderLine),
635-
self._line
645+
self._lines
636646
))[0]
637647
real_index = self._lines.index(line)
638648
else:

libioc/Config/Jail/File/__init__.py

Lines changed: 2 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -30,36 +30,6 @@
3030
import libioc.helpers_object
3131
import libioc.LaunchableResource
3232

33-
34-
class ResourceConfig:
35-
"""Shared abstract code between various config files in a resource."""
36-
37-
def _require_path_relative_to_resource(
38-
self,
39-
filepath: str,
40-
resource: 'libioc.LaunchableResource.LaunchableResource'
41-
) -> None:
42-
43-
if self._is_path_relative_to_resource(filepath, resource) is False:
44-
raise libioc.errors.SecurityViolationConfigJailEscape(
45-
file=filepath
46-
)
47-
48-
def _is_path_relative_to_resource(
49-
self,
50-
filepath: str,
51-
resource: 'libioc.LaunchableResource.LaunchableResource'
52-
) -> bool:
53-
54-
real_resource_path = self._resolve_path(resource.dataset.mountpoint)
55-
real_file_path = self._resolve_path(filepath)
56-
57-
return real_file_path.startswith(real_resource_path)
58-
59-
def _resolve_path(self, filepath: str) -> str:
60-
return os.path.realpath(os.path.abspath(filepath))
61-
62-
6333
class ConfigFile(dict):
6434
"""Abstraction of UCL file based config files in Resources."""
6535

@@ -221,7 +191,7 @@ def __getitem__(
221191
return None
222192

223193

224-
class ResourceConfigFile(ConfigFile, ResourceConfig):
194+
class ResourceConfigFile(ConfigFile):
225195
"""Abstraction of UCL file based config files in Resources."""
226196

227197
def __init__(
@@ -238,8 +208,5 @@ def __init__(
238208
def path(self) -> str:
239209
"""Absolute path to the file."""
240210
path = f"{self.resource.root_dataset.mountpoint}/{self.file}"
241-
self._require_path_relative_to_resource(
242-
filepath=path,
243-
resource=self.resource
244-
)
211+
self.resource._require_relative_path(path)
245212
return os.path.abspath(path)

libioc/Config/Jail/JailConfig.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ class JailConfig(libioc.Config.Jail.BaseConfig.BaseConfig):
4040

4141
legacy: bool = False
4242
jail: typing.Optional['libioc.Jail.JailGenerator']
43-
data: dict = {}
43+
data: dict
4444
ignore_source_config: bool
4545

4646
def __init__(

libioc/Config/Jail/Properties/Resolver.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ def set(
162162
)
163163
elif method == "skip":
164164
# directly set config property
165-
self.config.get_raw["resolver"] = None
165+
self.config.data["resolver"] = None
166166
else:
167167
if isinstance(value, str):
168168
self.append(str(value), notify=False)

libioc/Config/Type/JSON.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,6 @@ class DatasetConfigJSON(
5353
libioc.Config.Dataset.DatasetConfig,
5454
ConfigJSON
5555
):
56-
"""ResourceConfig in JSON format."""
56+
"""ConfigFile in JSON format."""
5757

5858
pass

libioc/Config/Type/UCL.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,6 @@ class DatasetConfigUCL(
5252
libioc.Config.Dataset.DatasetConfig,
5353
ConfigUCL
5454
):
55-
"""ResourceConfig in UCL format."""
55+
"""ConfigFile in UCL format."""
5656

5757
pass

libioc/Jail.py

Lines changed: 47 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -520,10 +520,7 @@ def start(
520520
exec_start.append("service ipfw onestop")
521521

522522
if self.config["jail_zfs"] is True:
523-
share_storage = libioc.ZFSShareStorage.QueuingZFSShareStorage(
524-
jail=self,
525-
logger=self.logger
526-
)
523+
share_storage = self._zfs_share_storage
527524
share_storage.mount_zfs_shares()
528525
exec_start += share_storage.read_commands("jail")
529526
exec_created += share_storage.read_commands()
@@ -615,6 +612,15 @@ def _stop_failed_jail(
615612

616613
yield jailLaunchEvent.end(stdout=stdout)
617614

615+
@property
616+
def _zfs_share_storage(
617+
self
618+
) -> libioc.ZFSShareStorage.QueuingZFSShareStorage:
619+
return libioc.ZFSShareStorage.QueuingZFSShareStorage(
620+
jail=self,
621+
logger=self.logger
622+
)
623+
618624
def _start_dependant_jails(
619625
self,
620626
terms: libioc.Filter.Terms,
@@ -726,7 +732,7 @@ def _wrap_hook_script_command(
726732
self,
727733
commands: typing.Optional[typing.Union[str, typing.List[str]]],
728734
ignore_errors: bool=True,
729-
jailed: bool=False,
735+
jailed: bool=False, # ToDo: remove unused argument
730736
write_env: bool=True
731737
) -> typing.List[str]:
732738

@@ -862,6 +868,7 @@ def _run_hook(self, hook_name: str) -> typing.Optional[
862868
raise NotImplementedError("_run_hook only supports start/stop")
863869

864870
def _ensure_script_dir(self) -> None:
871+
"""Ensure that the launch scripts dir exists."""
865872
realpath = os.path.realpath(self.launch_script_dir)
866873
if realpath.startswith(self.dataset.mountpoint) is False:
867874
raise libioc.errors.SecurityViolationConfigJailEscape(
@@ -1602,6 +1609,30 @@ def devfs_ruleset(self) -> libioc.DevfsRules.DevfsRuleset:
16021609
if self._allow_mount_zfs == "1":
16031610
devfs_ruleset.append("add path zfs unhide")
16041611

1612+
if self.config["jail_zfs"] is True:
1613+
unhidden_parents: typing.Set[str] = set()
1614+
shared_datasets = self._zfs_share_storage.get_zfs_datasets()
1615+
if len(shared_datasets) > 0:
1616+
devfs_ruleset.append("add path zvol unhide")
1617+
for shared_dataset in shared_datasets:
1618+
current_dataset_name = "zvol"
1619+
for fragment in shared_dataset.name.split("/"):
1620+
current_dataset_name += f"/{fragment}"
1621+
if current_dataset_name in unhidden_parents:
1622+
continue
1623+
unhidden_parents.add(current_dataset_name)
1624+
devfs_ruleset.append(
1625+
f"add path {current_dataset_name} unhide"
1626+
)
1627+
devfs_ruleset.append(
1628+
f"add path {current_dataset_name}/* unhide"
1629+
)
1630+
1631+
if self.config["allow_vmm"] is True:
1632+
devfs_ruleset.append("add path vmm unhide")
1633+
devfs_ruleset.append("add path vmm/* unhide")
1634+
devfs_ruleset.append("add path nmdm* unhide")
1635+
16051636
# create if the final rule combination does not exist as ruleset
16061637
if devfs_ruleset not in self.host.devfs:
16071638
self.logger.verbose("New devfs ruleset combination")
@@ -1680,6 +1711,9 @@ def _launch_command(self) -> typing.List[str]:
16801711
f"mount.devfs={self._get_value('mount_devfs')}"
16811712
]
16821713

1714+
if self.config["allow_vmm"] is True:
1715+
command.append("allow.vmm=1")
1716+
16831717
if self.host.userland_version > 9.3:
16841718
command += [
16851719
f"mount.fdescfs={self._get_value('mount_fdescfs')}",
@@ -2174,6 +2208,14 @@ def env(self) -> typing.Dict[str, str]:
21742208

21752209
jail_env["IOC_JAIL_PATH"] = self.root_dataset.mountpoint
21762210
jail_env["IOC_JID"] = str(self.jid)
2211+
jail_env["PATH"] = ":".join((
2212+
"/sbin",
2213+
"/bin",
2214+
"/usr/sbin",
2215+
"/usr/bin",
2216+
"/usr/local/sbin",
2217+
"/usr/local/bin",
2218+
))
21772219

21782220
return jail_env
21792221

0 commit comments

Comments
 (0)