Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion dissect/target/plugins/os/unix/esxi/_os.py
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,7 @@ def _link_log_dir(target: Target, cfg: dict[str, str], plugin_obj: ESXiPlugin) -
log_dir = None
if version and version[0] == "7":
try:
log_dir = plugin_obj._configstore["esx"]["syslog"]["global_settings"][""]["user_value"]["log_dir"]
log_dir = target.configstore._configstore["esx"]["syslog"]["global_settings"][""]["user_value"]["log_dir"]
except KeyError:
target.log.warning("Failed to read log_dir from configstore, falling back to /scratch/log")
log_dir = "/scratch/log"
Expand Down
6 changes: 2 additions & 4 deletions dissect/target/plugins/os/unix/esxi/configstore.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class ConfigstorePlugin(Plugin):

def __init__(self, target: Target):
super().__init__(target)
self._configstore = None
self._configstore = {}

# ESXi 7 introduced the configstore
# It's made available at /etc/vmware/configstore/current-store-1 during boot, but stored at
Expand All @@ -30,9 +30,7 @@ def __init__(self, target: Target):
self._configstore = parse_config_store(path)

def check_compatible(self) -> None:
if self.target.os != "esxi":
raise UnsupportedPluginError("ESXi specific plugin loaded on non-ESXi target")

# NOTE: Unable to use OS specific functions here, as this method can be called in ESXiPlugin.create
if not self._configstore:
raise UnsupportedPluginError("ESXi configstore not found on target")

Expand Down
3 changes: 3 additions & 0 deletions tests/_data/plugins/os/unix/esxi/current-store-1
Git LFS file not shown
29 changes: 28 additions & 1 deletion tests/plugins/os/unix/esxi/test__os.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
from __future__ import annotations

from io import BytesIO
from typing import TYPE_CHECKING
from unittest.mock import patch

from dissect.target.filesystem import VirtualFilesystem
from dissect.target.plugin import OperatingSystem
from dissect.target.plugins.os.unix.esxi._os import ESXiPlugin, _create_local_fs, _decrypt_crypto_util
from tests._utils import absolute_path

if TYPE_CHECKING:
from dissect.target.filesystem import VirtualFilesystem
from dissect.target.target import Target


Expand Down Expand Up @@ -73,3 +75,28 @@ def test_esxi_os_detection(target_bare: Target, fs_esxi: VirtualFilesystem) -> N
assert target_bare.hostname == "localhost"
assert target_bare.version == "6.7.0"
assert target_bare.ips == ["192.168.56.101"]


def test_esxi_os_creation_version_7(target_bare: Target) -> None:
"""Test handling of ``ESXiPlugin.create`` for ESXi 7 with separate partitions.

Indirectly tests the ESXi configstore plugin.
"""

fs1 = VirtualFilesystem()
fs1.map_file_fh("boot.cfg", BytesIO(b"build=7.13.37-1.2.3.4\nmodules=example.v00 --- example.tgz\n"))
fs1.map_file_fh("example.v00", BytesIO(b""))
target_bare.filesystems.add(fs1)

fs2 = VirtualFilesystem()
fs2.map_file_fh("/etc/vmware/esx.conf", BytesIO(b'/resourceGroups/version = "7.13.37"\n'))
fs2.map_file(
"/var/lib/vmware/configstore/backup/current-store-1",
absolute_path("_data/plugins/os/unix/esxi/current-store-1"),
)
target_bare.filesystems.add(fs2)

target_bare.apply()

assert ESXiPlugin.detect(target_bare)
assert ESXiPlugin.create(target_bare, fs1)
Loading