dissect.target 3.20.dev43__py3-none-any.whl → 3.20.dev44__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.
- dissect/target/loader.py +1 -0
- dissect/target/loaders/proxmox.py +68 -0
- dissect/target/plugin.py +8 -7
- dissect/target/plugins/child/proxmox.py +23 -0
- dissect/target/plugins/os/unix/_os.py +12 -0
- dissect/target/plugins/os/unix/linux/debian/proxmox/__init__.py +0 -0
- dissect/target/plugins/os/unix/linux/debian/proxmox/_os.py +141 -0
- dissect/target/plugins/os/unix/linux/debian/proxmox/vm.py +29 -0
- {dissect.target-3.20.dev43.dist-info → dissect.target-3.20.dev44.dist-info}/METADATA +1 -1
- {dissect.target-3.20.dev43.dist-info → dissect.target-3.20.dev44.dist-info}/RECORD +15 -10
- {dissect.target-3.20.dev43.dist-info → dissect.target-3.20.dev44.dist-info}/COPYRIGHT +0 -0
- {dissect.target-3.20.dev43.dist-info → dissect.target-3.20.dev44.dist-info}/LICENSE +0 -0
- {dissect.target-3.20.dev43.dist-info → dissect.target-3.20.dev44.dist-info}/WHEEL +0 -0
- {dissect.target-3.20.dev43.dist-info → dissect.target-3.20.dev44.dist-info}/entry_points.txt +0 -0
- {dissect.target-3.20.dev43.dist-info → dissect.target-3.20.dev44.dist-info}/top_level.txt +0 -0
dissect/target/loader.py
CHANGED
@@ -0,0 +1,68 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
import re
|
4
|
+
from pathlib import Path
|
5
|
+
|
6
|
+
from dissect.target import container
|
7
|
+
from dissect.target.loader import Loader
|
8
|
+
from dissect.target.target import Target
|
9
|
+
|
10
|
+
RE_VOLUME_ID = re.compile(r"(?:file=)?([^:]+):([^,]+)")
|
11
|
+
|
12
|
+
|
13
|
+
class ProxmoxLoader(Loader):
|
14
|
+
"""Loader for Proxmox VM configuration files.
|
15
|
+
|
16
|
+
Proxmox uses volume identifiers in the format of ``storage_id:volume_id``. The ``storage_id`` maps to a
|
17
|
+
storage configuration in ``/etc/pve/storage.cfg``. The ``volume_id`` is the name of the volume within
|
18
|
+
that configuration.
|
19
|
+
|
20
|
+
This loader currently does not support parsing the storage configuration, so it will attempt to open the
|
21
|
+
volume directly from the same directory as the configuration file, or from ``/dev/pve/`` (default LVM config).
|
22
|
+
If the volume is not found, it will log a warning.
|
23
|
+
"""
|
24
|
+
|
25
|
+
def __init__(self, path: Path, **kwargs):
|
26
|
+
path = path.resolve()
|
27
|
+
super().__init__(path)
|
28
|
+
self.base_dir = path.parent
|
29
|
+
|
30
|
+
@staticmethod
|
31
|
+
def detect(path: Path) -> bool:
|
32
|
+
if path.suffix.lower() != ".conf":
|
33
|
+
return False
|
34
|
+
|
35
|
+
with path.open("rb") as fh:
|
36
|
+
lines = fh.read(512).split(b"\n")
|
37
|
+
needles = [b"cpu:", b"memory:", b"name:"]
|
38
|
+
return all(any(needle in line for line in lines) for needle in needles)
|
39
|
+
|
40
|
+
def map(self, target: Target) -> None:
|
41
|
+
with self.path.open("rt") as fh:
|
42
|
+
for line in fh:
|
43
|
+
if not (line := line.strip()):
|
44
|
+
continue
|
45
|
+
|
46
|
+
key, value = line.split(":", 1)
|
47
|
+
value = value.strip()
|
48
|
+
|
49
|
+
if key.startswith(("scsi", "sata", "ide", "virtio")) and key[-1].isdigit():
|
50
|
+
# https://pve.proxmox.com/wiki/Storage
|
51
|
+
if match := RE_VOLUME_ID.match(value):
|
52
|
+
storage_id, volume_id = match.groups()
|
53
|
+
|
54
|
+
# TODO: parse the storage information from /etc/pve/storage.cfg
|
55
|
+
# For now, let's try a few assumptions
|
56
|
+
disk_path = None
|
57
|
+
if (path := self.base_dir.joinpath(volume_id)).exists():
|
58
|
+
disk_path = path
|
59
|
+
elif (path := self.base_dir.joinpath("/dev/pve/").joinpath(volume_id)).exists():
|
60
|
+
disk_path = path
|
61
|
+
|
62
|
+
if disk_path:
|
63
|
+
try:
|
64
|
+
target.disks.add(container.open(disk_path))
|
65
|
+
except Exception:
|
66
|
+
target.log.exception("Failed to open disk: %s", disk_path)
|
67
|
+
else:
|
68
|
+
target.log.warning("Unable to find disk: %s:%s", storage_id, volume_id)
|
dissect/target/plugin.py
CHANGED
@@ -57,17 +57,18 @@ log = logging.getLogger(__name__)
|
|
57
57
|
|
58
58
|
|
59
59
|
class OperatingSystem(StrEnum):
|
60
|
-
|
61
|
-
WINDOWS = "windows"
|
62
|
-
ESXI = "esxi"
|
60
|
+
ANDROID = "android"
|
63
61
|
BSD = "bsd"
|
62
|
+
CITRIX = "citrix-netscaler"
|
63
|
+
ESXI = "esxi"
|
64
|
+
FORTIOS = "fortios"
|
65
|
+
IOS = "ios"
|
66
|
+
LINUX = "linux"
|
64
67
|
OSX = "osx"
|
68
|
+
PROXMOX = "proxmox"
|
65
69
|
UNIX = "unix"
|
66
|
-
ANDROID = "android"
|
67
70
|
VYOS = "vyos"
|
68
|
-
|
69
|
-
FORTIOS = "fortios"
|
70
|
-
CITRIX = "citrix-netscaler"
|
71
|
+
WINDOWS = "windows"
|
71
72
|
|
72
73
|
|
73
74
|
def export(*args, **kwargs) -> Callable:
|
@@ -0,0 +1,23 @@
|
|
1
|
+
from typing import Iterator
|
2
|
+
|
3
|
+
from dissect.target.exceptions import UnsupportedPluginError
|
4
|
+
from dissect.target.helpers.record import ChildTargetRecord
|
5
|
+
from dissect.target.plugin import ChildTargetPlugin
|
6
|
+
|
7
|
+
|
8
|
+
class ProxmoxChildTargetPlugin(ChildTargetPlugin):
|
9
|
+
"""Child target plugin that yields from the VM listing."""
|
10
|
+
|
11
|
+
__type__ = "proxmox"
|
12
|
+
|
13
|
+
def check_compatible(self) -> None:
|
14
|
+
if self.target.os != "proxmox":
|
15
|
+
raise UnsupportedPluginError("Not a Proxmox operating system")
|
16
|
+
|
17
|
+
def list_children(self) -> Iterator[ChildTargetRecord]:
|
18
|
+
for vm in self.target.vmlist():
|
19
|
+
yield ChildTargetRecord(
|
20
|
+
type=self.__type__,
|
21
|
+
path=vm.path,
|
22
|
+
_target=self.target,
|
23
|
+
)
|
@@ -23,6 +23,7 @@ class UnixPlugin(OSPlugin):
|
|
23
23
|
def __init__(self, target: Target):
|
24
24
|
super().__init__(target)
|
25
25
|
self._add_mounts()
|
26
|
+
self._add_devices()
|
26
27
|
self._hostname_dict = self._parse_hostname_string()
|
27
28
|
self._hosts_dict = self._parse_hosts_string()
|
28
29
|
self._os_release = self._parse_os_release()
|
@@ -247,6 +248,17 @@ class UnixPlugin(OSPlugin):
|
|
247
248
|
self.target.log.debug("Mounting %s (%s) at %s", fs, fs.volume, mount_point)
|
248
249
|
self.target.fs.mount(mount_point, fs)
|
249
250
|
|
251
|
+
def _add_devices(self) -> None:
|
252
|
+
"""Add some virtual block devices to the target.
|
253
|
+
|
254
|
+
Currently only adds LVM devices.
|
255
|
+
"""
|
256
|
+
vfs = self.target.fs.append_layer()
|
257
|
+
|
258
|
+
for volume in self.target.volumes:
|
259
|
+
if volume.vs and volume.vs.__type__ == "lvm":
|
260
|
+
vfs.map_file_fh(f"/dev/{volume.raw.vg.name}/{volume.raw.name}", volume)
|
261
|
+
|
250
262
|
def _parse_os_release(self, glob: str | None = None) -> dict[str, str]:
|
251
263
|
"""Parse files containing Unix version information.
|
252
264
|
|
File without changes
|
@@ -0,0 +1,141 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
import stat
|
4
|
+
from io import BytesIO
|
5
|
+
from typing import BinaryIO
|
6
|
+
|
7
|
+
from dissect.sql import sqlite3
|
8
|
+
from dissect.util.stream import BufferedStream
|
9
|
+
|
10
|
+
from dissect.target.filesystem import (
|
11
|
+
Filesystem,
|
12
|
+
VirtualDirectory,
|
13
|
+
VirtualFile,
|
14
|
+
VirtualFilesystem,
|
15
|
+
)
|
16
|
+
from dissect.target.helpers import fsutil
|
17
|
+
from dissect.target.plugins.os.unix._os import OperatingSystem, export
|
18
|
+
from dissect.target.plugins.os.unix.linux.debian._os import DebianPlugin
|
19
|
+
from dissect.target.target import Target
|
20
|
+
|
21
|
+
|
22
|
+
class ProxmoxPlugin(DebianPlugin):
|
23
|
+
@classmethod
|
24
|
+
def detect(cls, target: Target) -> Filesystem | None:
|
25
|
+
for fs in target.filesystems:
|
26
|
+
if fs.exists("/etc/pve") or fs.exists("/var/lib/pve"):
|
27
|
+
return fs
|
28
|
+
|
29
|
+
return None
|
30
|
+
|
31
|
+
@classmethod
|
32
|
+
def create(cls, target: Target, sysvol: Filesystem) -> ProxmoxPlugin:
|
33
|
+
obj = super().create(target, sysvol)
|
34
|
+
|
35
|
+
if (config_db := target.fs.path("/var/lib/pve-cluster/config.db")).exists():
|
36
|
+
with config_db.open("rb") as fh:
|
37
|
+
vfs = _create_pmxcfs(fh, obj.hostname)
|
38
|
+
|
39
|
+
target.fs.mount("/etc/pve", vfs)
|
40
|
+
|
41
|
+
return obj
|
42
|
+
|
43
|
+
@export(property=True)
|
44
|
+
def version(self) -> str:
|
45
|
+
"""Returns Proxmox VE version with underlying OS release."""
|
46
|
+
|
47
|
+
for pkg in self.target.dpkg.status():
|
48
|
+
if pkg.name == "proxmox-ve":
|
49
|
+
distro_name = self._os_release.get("PRETTY_NAME", "")
|
50
|
+
return f"{pkg.name} {pkg.version} ({distro_name})"
|
51
|
+
|
52
|
+
@export(property=True)
|
53
|
+
def os(self) -> str:
|
54
|
+
return OperatingSystem.PROXMOX.value
|
55
|
+
|
56
|
+
|
57
|
+
DT_DIR = 4
|
58
|
+
DT_REG = 8
|
59
|
+
|
60
|
+
|
61
|
+
def _create_pmxcfs(fh: BinaryIO, hostname: str | None = None) -> VirtualFilesystem:
|
62
|
+
# https://pve.proxmox.com/wiki/Proxmox_Cluster_File_System_(pmxcfs)
|
63
|
+
db = sqlite3.SQLite3(fh)
|
64
|
+
|
65
|
+
entries = {row.inode: row for row in db.table("tree")}
|
66
|
+
|
67
|
+
vfs = VirtualFilesystem()
|
68
|
+
for entry in entries.values():
|
69
|
+
if entry.type == DT_DIR:
|
70
|
+
cls = ProxmoxConfigDirectoryEntry
|
71
|
+
elif entry.type == DT_REG:
|
72
|
+
cls = ProxmoxConfigFileEntry
|
73
|
+
else:
|
74
|
+
raise ValueError(f"Unknown pmxcfs file type: {entry.type}")
|
75
|
+
|
76
|
+
parts = []
|
77
|
+
current = entry
|
78
|
+
while current.parent != 0:
|
79
|
+
parts.append(current.name)
|
80
|
+
current = entries[current.parent]
|
81
|
+
parts.append(current.name)
|
82
|
+
|
83
|
+
path = "/".join(parts[::-1])
|
84
|
+
vfs.map_file_entry(path, cls(vfs, path, entry))
|
85
|
+
|
86
|
+
if hostname:
|
87
|
+
node_root = vfs.path(f"nodes/{hostname}")
|
88
|
+
vfs.symlink(str(node_root), "local")
|
89
|
+
vfs.symlink(str(node_root / "lxc"), "lxc")
|
90
|
+
vfs.symlink(str(node_root / "openvz"), "openvz")
|
91
|
+
vfs.symlink(str(node_root / "qemu-server"), "qemu-server")
|
92
|
+
|
93
|
+
# TODO: .version, .members, .vmlist, maybe .clusterlog and .rrd?
|
94
|
+
|
95
|
+
return vfs
|
96
|
+
|
97
|
+
|
98
|
+
class ProxmoxConfigFileEntry(VirtualFile):
|
99
|
+
def open(self) -> BinaryIO:
|
100
|
+
return BufferedStream(BytesIO(self.entry.data or b""))
|
101
|
+
|
102
|
+
def lstat(self) -> fsutil.stat_result:
|
103
|
+
# ['mode', 'addr', 'dev', 'nlink', 'uid', 'gid', 'size', 'atime', 'mtime', 'ctime']
|
104
|
+
return fsutil.stat_result(
|
105
|
+
[
|
106
|
+
stat.S_IFREG | 0o640,
|
107
|
+
self.entry.inode,
|
108
|
+
id(self.fs),
|
109
|
+
1,
|
110
|
+
0,
|
111
|
+
0,
|
112
|
+
len(self.entry.data) if self.entry.data else 0,
|
113
|
+
0,
|
114
|
+
self.entry.mtime,
|
115
|
+
0,
|
116
|
+
]
|
117
|
+
)
|
118
|
+
|
119
|
+
|
120
|
+
class ProxmoxConfigDirectoryEntry(VirtualDirectory):
|
121
|
+
def __init__(self, fs: VirtualFilesystem, path: str, entry: sqlite3.Row):
|
122
|
+
super().__init__(fs, path)
|
123
|
+
self.entry = entry
|
124
|
+
|
125
|
+
def lstat(self) -> fsutil.stat_result:
|
126
|
+
"""Return the stat information of the given path, without resolving links."""
|
127
|
+
# ['mode', 'addr', 'dev', 'nlink', 'uid', 'gid', 'size', 'atime', 'mtime', 'ctime']
|
128
|
+
return fsutil.stat_result(
|
129
|
+
[
|
130
|
+
stat.S_IFDIR | 0o755,
|
131
|
+
self.entry.inode,
|
132
|
+
id(self.fs),
|
133
|
+
1,
|
134
|
+
0,
|
135
|
+
0,
|
136
|
+
0,
|
137
|
+
0,
|
138
|
+
self.entry.mtime,
|
139
|
+
0,
|
140
|
+
]
|
141
|
+
)
|
@@ -0,0 +1,29 @@
|
|
1
|
+
from typing import Iterator
|
2
|
+
|
3
|
+
from dissect.target.exceptions import UnsupportedPluginError
|
4
|
+
from dissect.target.helpers.record import TargetRecordDescriptor
|
5
|
+
from dissect.target.plugin import Plugin, export
|
6
|
+
|
7
|
+
VirtualMachineRecord = TargetRecordDescriptor(
|
8
|
+
"proxmox/vm",
|
9
|
+
[
|
10
|
+
("string", "path"),
|
11
|
+
],
|
12
|
+
)
|
13
|
+
|
14
|
+
|
15
|
+
class VirtualMachinePlugin(Plugin):
|
16
|
+
"""Plugin to list Proxmox virtual machines."""
|
17
|
+
|
18
|
+
def check_compatible(self) -> None:
|
19
|
+
if self.target.os != "proxmox":
|
20
|
+
raise UnsupportedPluginError("Not a Proxmox operating system")
|
21
|
+
|
22
|
+
@export(record=VirtualMachineRecord)
|
23
|
+
def vmlist(self) -> Iterator[VirtualMachineRecord]:
|
24
|
+
"""List Proxmox virtual machines on this node."""
|
25
|
+
for config in self.target.fs.path("/etc/pve/qemu-server").iterdir():
|
26
|
+
yield VirtualMachineRecord(
|
27
|
+
path=config,
|
28
|
+
_target=self.target,
|
29
|
+
)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: dissect.target
|
3
|
-
Version: 3.20.
|
3
|
+
Version: 3.20.dev44
|
4
4
|
Summary: This module ties all other Dissect modules together, it provides a programming API and command line tools which allow easy access to various data sources inside disk images or file collections (a.k.a. targets)
|
5
5
|
Author-email: Dissect Team <dissect@fox-it.com>
|
6
6
|
License: Affero General Public License v3
|
@@ -2,8 +2,8 @@ dissect/target/__init__.py,sha256=Oc7ounTgq2hE4nR6YcNabetc7SQA40ldSa35VEdZcQU,63
|
|
2
2
|
dissect/target/container.py,sha256=0YcwcGmfJjhPXUB6DEcjWEoSuAtTDxMDpoTviMrLsxM,9353
|
3
3
|
dissect/target/exceptions.py,sha256=ULi7NXlqju_d8KENEL3aimmfKTFfbNssfeWhAnOB654,2972
|
4
4
|
dissect/target/filesystem.py,sha256=__p2p72B6mKgIiAOj85EC3ESdZ8gjgkm2pt1KKym3h0,60743
|
5
|
-
dissect/target/loader.py,sha256=
|
6
|
-
dissect/target/plugin.py,sha256=
|
5
|
+
dissect/target/loader.py,sha256=ZlCI7ZyPpysuSKndOiRz_rrGb30_jLMdFD6qObY0Vzg,7374
|
6
|
+
dissect/target/plugin.py,sha256=iUc7OmQJ0wwYJeR7L4VBNJ0AjgYWV69FN0NHgWYaLYI,50682
|
7
7
|
dissect/target/report.py,sha256=06uiP4MbNI8cWMVrC1SasNS-Yg6ptjVjckwj8Yhe0Js,7958
|
8
8
|
dissect/target/target.py,sha256=-UoFO_fqS6XPf77RDHSV4gNRi95wwwpgWq7zIhNVUGk,32719
|
9
9
|
dissect/target/volume.py,sha256=aQZAJiny8jjwkc9UtwIRwy7nINXjCxwpO-_UDfh6-BA,15801
|
@@ -93,6 +93,7 @@ dissect/target/loaders/overlay.py,sha256=tj99HKvNG5_JbGfb1WCv4KNSbXXSnEcPQY5XT-J
|
|
93
93
|
dissect/target/loaders/ovf.py,sha256=ELMq6J2y6cPKbp7pjWAqMMnFYefWxXNqzIiAQdvGGXQ,1061
|
94
94
|
dissect/target/loaders/phobos.py,sha256=XtxF7FZXfZrXJruFUZUQzxlREyfc86dTxph7BNoNMvw,2277
|
95
95
|
dissect/target/loaders/profile.py,sha256=5ylgmzEEGyBFW3izvb-BZ7dGByXN9OFyRnnggR98P9w,1667
|
96
|
+
dissect/target/loaders/proxmox.py,sha256=HP7yCrXze1DmMud7730OPMIwUAEaeoXK0YO6i2XSunM,2778
|
96
97
|
dissect/target/loaders/pvm.py,sha256=b-PvHNTbRVdOnf7-OR5dbikbDTCFlW85b-9Z8PEL2Cs,406
|
97
98
|
dissect/target/loaders/pvs.py,sha256=dMqdYSBQtH9QLM3tdu0mokLBcn73edg_HUtYtqrdi6E,955
|
98
99
|
dissect/target/loaders/raw.py,sha256=tleNWoO0BkC32ExBIPVOpzrQHXXHChZXoZr02oYuC8A,674
|
@@ -163,6 +164,7 @@ dissect/target/plugins/child/docker.py,sha256=frBZ8UUzbtkT9VrK1fwUzXDAdkHESdPCb-
|
|
163
164
|
dissect/target/plugins/child/esxi.py,sha256=EHpBRv5dizvJVIhtVR7frkUnI9GR7lrbSWPGoOpKhRw,753
|
164
165
|
dissect/target/plugins/child/hyperv.py,sha256=R2qVeu4p_9V53jO-65znN0LwX9v3FVA-9jbbtOQcEz8,2236
|
165
166
|
dissect/target/plugins/child/parallels.py,sha256=jeBT_NvTQbQBaUjqGWTy2I5Q5OWlrogoyWHRXjOhLis,2255
|
167
|
+
dissect/target/plugins/child/proxmox.py,sha256=qjeact60fpUXsOciAIJ776fpcnkO6hTZjeUyx92I2HQ,755
|
166
168
|
dissect/target/plugins/child/qemu.py,sha256=vNzQwzFO964jYaI67MlX8vpWyHxpegjIU5F29zHKOGI,791
|
167
169
|
dissect/target/plugins/child/virtuozzo.py,sha256=raXaDTyGPY5JuNgyUOn_qzHaPa0sokG3nGZ5_7eDPyA,1303
|
168
170
|
dissect/target/plugins/child/vmware_workstation.py,sha256=eLvgi_aFUaMN1tC5X4RN85nKQdsuRQygrFYtNMAERTc,2030
|
@@ -194,7 +196,7 @@ dissect/target/plugins/general/scrape.py,sha256=Fz7BNXflvuxlnVulyyDhLpyU8D_hJdH6
|
|
194
196
|
dissect/target/plugins/general/users.py,sha256=yy9gvRXfN9BT71v4Xqo5hpwfgN9he9Otu8TBPZ_Tegs,3009
|
195
197
|
dissect/target/plugins/os/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
196
198
|
dissect/target/plugins/os/unix/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
197
|
-
dissect/target/plugins/os/unix/_os.py,sha256=
|
199
|
+
dissect/target/plugins/os/unix/_os.py,sha256=prvcuIkJ1jmbb_g1CtgHmmJUcGjFaZn3yU6VPNMJ27k,15061
|
198
200
|
dissect/target/plugins/os/unix/applications.py,sha256=AUgZRP35FzswGyFyChj2o4dfGO34Amc6nqHgiMEaqdI,3129
|
199
201
|
dissect/target/plugins/os/unix/cronjobs.py,sha256=tgWQ3BUZpfyvRzodMwGtwFUdPjZ17k7ZRbZ9Q8wmXPk,3393
|
200
202
|
dissect/target/plugins/os/unix/datetime.py,sha256=gKfBdPyUirt3qmVYfOJ1oZXRPn8wRzssbZxR_ARrtk8,1518
|
@@ -242,6 +244,9 @@ dissect/target/plugins/os/unix/linux/debian/_os.py,sha256=GI19ZqcyfZ1mUYg2NCx93H
|
|
242
244
|
dissect/target/plugins/os/unix/linux/debian/apt.py,sha256=uKfW77pbgxYSe9g6hpih19-xfgvCB954Ygx21j-ydzk,4388
|
243
245
|
dissect/target/plugins/os/unix/linux/debian/dpkg.py,sha256=6A3mb77NREdDWDTFrmcfCF_XxHMmD4_5eHqHEl_7Vqg,5816
|
244
246
|
dissect/target/plugins/os/unix/linux/debian/snap.py,sha256=YVz1N54eQsj2_22LUJIj6Gg-huwT4xDEcOAZn9Tvgw4,3023
|
247
|
+
dissect/target/plugins/os/unix/linux/debian/proxmox/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
248
|
+
dissect/target/plugins/os/unix/linux/debian/proxmox/_os.py,sha256=OrQsPcz3fERVnSJKRMXwWQCoVN6CFuC-pJIVHtU-g9M,4257
|
249
|
+
dissect/target/plugins/os/unix/linux/debian/proxmox/vm.py,sha256=Z5IDA5Oot4P2hh65n5cgUMUi_TMIgSexIO2ngOgxPo0,911
|
245
250
|
dissect/target/plugins/os/unix/linux/debian/vyos/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
246
251
|
dissect/target/plugins/os/unix/linux/debian/vyos/_os.py,sha256=TPjcfv1n68RCe3Er4aCVQwQDCZwJT-NLvje3kPjDfhk,1744
|
247
252
|
dissect/target/plugins/os/unix/linux/fortios/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -373,10 +378,10 @@ dissect/target/volumes/luks.py,sha256=OmCMsw6rCUXG1_plnLVLTpsvE1n_6WtoRUGQbpmu1z
|
|
373
378
|
dissect/target/volumes/lvm.py,sha256=wwQVR9I3G9YzmY6UxFsH2Y4MXGBcKL9aayWGCDTiWMU,2269
|
374
379
|
dissect/target/volumes/md.py,sha256=7ShPtusuLGaIv27SvEETtgsuoQyAa4iAAeOR1NEaajI,1689
|
375
380
|
dissect/target/volumes/vmfs.py,sha256=-LoUbn9WNwTtLi_4K34uV_-wDw2W5hgaqxZNj4UmqAQ,1730
|
376
|
-
dissect.target-3.20.
|
377
|
-
dissect.target-3.20.
|
378
|
-
dissect.target-3.20.
|
379
|
-
dissect.target-3.20.
|
380
|
-
dissect.target-3.20.
|
381
|
-
dissect.target-3.20.
|
382
|
-
dissect.target-3.20.
|
381
|
+
dissect.target-3.20.dev44.dist-info/COPYRIGHT,sha256=m-9ih2RVhMiXHI2bf_oNSSgHgkeIvaYRVfKTwFbnJPA,301
|
382
|
+
dissect.target-3.20.dev44.dist-info/LICENSE,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
|
383
|
+
dissect.target-3.20.dev44.dist-info/METADATA,sha256=Sgsho9JR5_66txpbY0u-KInNUTMmgflhCY23idL5Iuo,12897
|
384
|
+
dissect.target-3.20.dev44.dist-info/WHEEL,sha256=P9jw-gEje8ByB7_hXoICnHtVCrEwMQh-630tKvQWehc,91
|
385
|
+
dissect.target-3.20.dev44.dist-info/entry_points.txt,sha256=BWuxAb_6AvUAQpIQOQU0IMTlaF6TDht2AIZK8bHd-zE,492
|
386
|
+
dissect.target-3.20.dev44.dist-info/top_level.txt,sha256=Mn-CQzEYsAbkxrUI0TnplHuXnGVKzxpDw_po_sXpvv4,8
|
387
|
+
dissect.target-3.20.dev44.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
{dissect.target-3.20.dev43.dist-info → dissect.target-3.20.dev44.dist-info}/entry_points.txt
RENAMED
File without changes
|
File without changes
|