Skip to content

Commit 16c13ee

Browse files
committed
revert reverted dbus stuff
1 parent c928c5e commit 16c13ee

File tree

7 files changed

+46
-202
lines changed

7 files changed

+46
-202
lines changed

packaging/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ debian-package-code:
1515
cp ../examples/instance_message_from_aleph.json ./aleph-vm/opt/aleph-vm/examples/instance_message_from_aleph.json
1616
cp -r ../examples/data ./aleph-vm/opt/aleph-vm/examples/data
1717
mkdir -p ./aleph-vm/opt/aleph-vm/examples/volumes
18-
pip3 install --target ./aleph-vm/opt/aleph-vm/ 'aleph-message==0.4.4' 'jwskate==0.8.0' 'eth-account==0.9.0' 'sentry-sdk==1.31.0' 'qmp==1.1.0' 'superfluid==0.2.1' 'sqlalchemy[asyncio]' 'aiosqlite==0.19.0' 'alembic==1.13.1' 'aiohttp_cors==0.7.0' 'pyroute2==0.7.12' 'dbus-fast==1.90.1'
18+
pip3 install --target ./aleph-vm/opt/aleph-vm/ 'aleph-message==0.4.4' 'jwskate==0.8.0' 'eth-account==0.9.0' 'sentry-sdk==1.31.0' 'qmp==1.1.0' 'superfluid==0.2.1' 'sqlalchemy[asyncio]' 'aiosqlite==0.19.0' 'alembic==1.13.1' 'aiohttp_cors==0.7.0' 'pyroute2==0.7.12'
1919
python3 -m compileall ./aleph-vm/opt/aleph-vm/
2020

2121
debian-package-resources: firecracker-bins vmlinux download-ipfs-kubo

packaging/aleph-vm/DEBIAN/control

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@ Version: 0.1.8
33
Architecture: all
44
Maintainer: Aleph.im
55
Description: Aleph.im VM execution engine
6-
Depends: python3,python3-pip,python3-aiohttp,python3-msgpack,python3-aiodns,python3-alembic,python3-sqlalchemy,python3-setproctitle,redis,python3-aioredis,python3-psutil,sudo,acl,curl,systemd-container,squashfs-tools,debootstrap,python3-packaging,python3-cpuinfo,python3-nftables,python3-jsonschema,cloud-image-utils,ndppd,python3-yaml,python3-dotenv,python3-schedule,qemu-system-x86,qemu-utils,python3-systemd,btrfs-progs,nftables,python3-jwcrypto
6+
Depends: python3,python3-pip,python3-aiohttp,python3-msgpack,python3-aiodns,python3-alembic,python3-sqlalchemy,python3-setproctitle,redis,python3-aioredis,python3-psutil,sudo,acl,curl,systemd-container,squashfs-tools,debootstrap,python3-packaging,python3-cpuinfo,python3-nftables,python3-jsonschema,cloud-image-utils,ndppd,python3-yaml,python3-dotenv,python3-schedule,qemu-system-x86,qemu-utils,python3-systemd,python3-dbus,btrfs-progs,nftables,python3-jwcrypto
77
Section: aleph-im
88
Priority: Extra

pyproject.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ dependencies = [
4141
"packaging==23.2",
4242
"jsonschema==4.19.1",
4343
"qmp==0.0.1",
44-
"dbus-fast==1.90.1",
44+
"dbus-python==1.3.2",
45+
"systemd-python==235",
4546
"systemd-python==235",
4647
"superfluid~=0.2.1",
4748
"sqlalchemy[asyncio]>=2.0",

src/aleph/vm/orchestrator/supervisor.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -103,10 +103,6 @@ async def http_not_found(request: web.Request):
103103
web.post("/control/machine/{ref}/stop", operate_stop),
104104
web.post("/control/machine/{ref}/erase", operate_erase),
105105
web.post("/control/machine/{ref}/reboot", operate_reboot),
106-
# web.options(
107-
# "/control/machine/{ref}/{view:.*}",
108-
# allow_cors_on_endpoint,
109-
# ),
110106
# /status APIs are used to check that the VM Orchestrator is running properly
111107
web.get("/status/check/fastapi", status_check_fastapi),
112108
web.get("/status/check/fastapi/legacy", status_check_fastapi_legacy),

src/aleph/vm/orchestrator/views/operator.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
1-
"""Endpoint defined here allow for the user launching the VM
2-
3-
they allow rebooting, stopping, erasing and streaming it's log via websocket"""
4-
51
import logging
62
from datetime import timedelta
73

src/aleph/vm/pool.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ async def create_a_vm(
124124

125125
# Start VM and snapshots automatically
126126
if execution.persistent:
127-
await self.systemd_manager.enable_and_start(execution.controller_service)
127+
self.systemd_manager.enable_and_start(execution.controller_service)
128128
await execution.wait_for_init()
129129
if execution.is_program and execution.vm:
130130
await execution.vm.load_configuration()
@@ -191,7 +191,7 @@ async def stop_vm(self, vm_hash: ItemHash) -> Optional[VmExecution]:
191191
async def stop_persistent_execution(self, execution: VmExecution):
192192
"""Stop persistent VMs in the pool."""
193193
assert execution.persistent, "Execution isn't persistent"
194-
await self.systemd_manager.stop_and_disable(execution.controller_service)
194+
self.systemd_manager.stop_and_disable(execution.controller_service)
195195
await execution.stop()
196196

197197
def forget_vm(self, vm_hash: ItemHash) -> None:

src/aleph/vm/systemd.py

Lines changed: 40 additions & 189 deletions
Original file line numberDiff line numberDiff line change
@@ -2,224 +2,75 @@
22
async SystemD Manager implementation.
33
"""
44

5-
import enum
65
import logging
7-
from typing import Literal, Optional, Protocol, runtime_checkable
86

9-
from dbus_fast import BusType, DBusError
10-
from dbus_fast.aio import MessageBus, ProxyObject
7+
import dbus
8+
from dbus import DBusException, SystemBus
9+
from dbus.proxies import Interface
1110

1211
logger = logging.getLogger(__name__)
1312

1413

15-
class UnitFileState(str, enum.Enum):
16-
"""This StrEnum class represents the different possible states of a unit file."""
17-
18-
ENABLED = "enabled"
19-
"""Indicates that a unit file is permanently enabled."""
20-
21-
ENABLED_RUNTIME = "enabled-runtime"
22-
"""Indicates the unit file is only temporarily enabled and will no longer be enabled after a reboot
23-
(that means, it is enabled via /run/ symlinks, rather than /etc/)."""
24-
25-
LINKED = "linked"
26-
"""Indicates that a unit is linked into /etc/ permanently."""
27-
28-
LINKED_RUNTIME = "linked-runtime"
29-
"""Indicates that a unit is linked into /run/ temporarily (until the next reboot)."""
30-
31-
MASKED = "masked"
32-
"""Indicates that the unit file is masked permanently."""
33-
34-
MASKED_RUNTIME = "masked-runtime"
35-
"""Indicates that it is masked in /run/ temporarily (until the next reboot)."""
36-
37-
STATIC = "static"
38-
"""Indicates that the unit is statically enabled, i.e. always enabled and doesn't need to be enabled explicitly."""
39-
40-
DISABLED = "disabled"
41-
"""Indicates that the unit file is not enabled."""
42-
43-
INVALID = "invalid"
44-
"""Indicates that it could not be determined whether the unit file is enabled."""
45-
46-
47-
UnitFileStateLiteral = Literal[
48-
"enabled",
49-
"enabled-runtime",
50-
"linked",
51-
"linked-runtime",
52-
"masked",
53-
"masked-runtime",
54-
"static",
55-
"disabled",
56-
"invalid",
57-
]
58-
59-
60-
class Mode(str, enum.Enum):
61-
REPLACE = "replace"
62-
FAIL = "fail"
63-
ISOLATE = "isolate"
64-
IGNORE_DEPENDENCIES = "ignore-dependencies"
65-
IGNORE_REQUIREMENTS = "ignore-requirements"
66-
67-
68-
class ActiveState(str, enum.Enum):
69-
"""
70-
ActiveState contains a state value that reflects the unit's current status.
71-
"""
72-
73-
ACTIVE = "active"
74-
"""
75-
The unit is active.
76-
"""
77-
78-
RELOADING = "reloading"
79-
"""
80-
The unit is active and reloading its configuration.
81-
"""
82-
83-
INACTIVE = "inactive"
84-
"""
85-
The unit is inactive, previous run was successful or hasn't yet occurred.
86-
"""
87-
88-
FAILED = "failed"
89-
"""
90-
The unit is inactive, previous run was unsuccessful.
91-
"""
92-
93-
ACTIVATING = "activating"
94-
"""
95-
The unit is transitioning from inactive to active state.
96-
"""
97-
98-
DEACTIVATING = "deactivating"
99-
"""
100-
The unit is in the process of deactivation.
101-
"""
102-
103-
104-
ActiveStateLiteral = Literal["active", "reloading", "inactive", "failed", "activating", "deactivating"]
105-
106-
107-
@runtime_checkable
108-
class SystemdProxy(Protocol):
109-
"""ABC for typing.
110-
111-
for description of methodsp
112-
see https://www.freedesktop.org/software/systemd/man/latest/org.freedesktop.systemd1.html#The%20Manager%20Object"""
113-
114-
async def call_enable_unit_files(self, files: list[str], runtime: bool, force: bool): ...
115-
116-
async def call_get_unit_file_state(self, service) -> UnitFileStateLiteral: ...
117-
118-
async def call_start_unit(self, name, mode):
119-
pass
120-
121-
async def call_stop_unit(self, name, mode): ...
122-
123-
async def call_restart_unit(self, name, mode): ...
124-
125-
async def call_disable_unit_files(self, files: list[str], runtime: bool): ...
126-
127-
async def call_get_unit(self, name: str) -> str: ...
128-
129-
130-
@runtime_checkable
131-
class UnitProxy(Protocol):
132-
"""for typing.
133-
134-
for description of methods see
135-
https://www.freedesktop.org/software/systemd/man/latest/org.freedesktop.systemd1.html#Service%20Unit%20Objects"""
136-
137-
async def get_active_state(self) -> ActiveStateLiteral: ...
138-
139-
14014
class SystemDManager:
14115
"""SystemD Manager class.
14216
14317
Used to manage the systemd services on the host on Linux.
14418
"""
14519

146-
bus: Optional[MessageBus]
147-
manager: Optional[SystemdProxy]
20+
bus: SystemBus
21+
manager: Interface
14822

14923
def __init__(self):
150-
pass
151-
152-
async def connect(self):
153-
self.bus = MessageBus(bus_type=BusType.SYSTEM)
154-
await self.bus.connect()
155-
path = "/org/freedesktop/systemd1"
156-
bus_name = "org.freedesktop.systemd1"
157-
introspect = await self.bus.introspect(bus_name, path)
158-
systemd_proxy: ProxyObject = self.bus.get_proxy_object(bus_name, path, introspection=introspect)
159-
interface = systemd_proxy.get_interface("org.freedesktop.systemd1.Manager")
160-
# Check required method are implemented
161-
assert isinstance(interface, SystemdProxy)
162-
self.manager = interface
163-
164-
async def enable(self, service: str) -> None:
165-
assert self.manager, "connect() not called"
166-
await self.manager.call_enable_unit_files([service], False, True)
24+
self.bus = dbus.SystemBus()
25+
systemd = self.bus.get_object("org.freedesktop.systemd1", "/org/freedesktop/systemd1")
26+
self.manager = dbus.Interface(systemd, "org.freedesktop.systemd1.Manager")
27+
28+
def stop_and_disable(self, service: str) -> None:
29+
if self.is_service_active(service):
30+
self.stop(service)
31+
if self.is_service_enabled(service):
32+
self.disable(service)
33+
34+
def enable(self, service: str) -> None:
35+
self.manager.EnableUnitFiles([service], False, True)
16736
logger.debug(f"Enabled {service} service")
16837

169-
async def start(self, service: str) -> None:
170-
assert self.manager, "connect() not called"
171-
await self.manager.call_start_unit(service, Mode.REPLACE)
38+
def start(self, service: str) -> None:
39+
self.manager.StartUnit(service, "replace")
17240
logger.debug(f"Started {service} service")
17341

174-
async def stop(self, service: str) -> None:
175-
assert self.manager, "connect() not called"
176-
await self.manager.call_stop_unit(service, Mode.REPLACE)
42+
def stop(self, service: str) -> None:
43+
self.manager.StopUnit(service, "replace")
17744
logger.debug(f"Stopped {service} service")
17845

179-
async def restart(self, service: str) -> None:
180-
assert self.manager, "connect() not called"
181-
await self.manager.call_restart_unit(service, Mode.REPLACE)
46+
def restart(self, service: str) -> None:
47+
self.manager.RestartUnit(service, "replace")
18248
logger.debug(f"Restarted {service} service")
18349

184-
async def disable(self, service: str) -> None:
185-
assert self.manager, "connect() not called"
186-
await self.manager.call_disable_unit_files([service], False)
50+
def disable(self, service: str) -> None:
51+
self.manager.DisableUnitFiles([service], False)
18752
logger.debug(f"Disabled {service} service")
18853

189-
async def is_service_enabled(self, service: str) -> bool:
190-
assert self.manager, "connect() not called"
54+
def is_service_enabled(self, service: str) -> bool:
19155
try:
192-
state = await self.manager.call_get_unit_file_state(service)
193-
return state == UnitFileState.ENABLED
194-
except DBusError as error:
56+
return self.manager.GetUnitFileState(service) == "enabled"
57+
except DBusException as error:
19558
logger.error(error)
19659
return False
19760

198-
async def is_service_active(self, service: str) -> bool:
199-
assert self.manager, "connect() not called"
200-
assert self.bus, "connect() not called"
61+
def is_service_active(self, service: str) -> bool:
20162
try:
202-
path = await self.manager.call_get_unit(service)
203-
bus_name = "org.freedesktop.systemd1"
204-
introspect = await self.bus.introspect(bus_name, path)
205-
systemd_service = self.bus.get_proxy_object(bus_name, path, introspection=introspect)
206-
unit = systemd_service.get_interface("org.freedesktop.systemd1.Unit")
207-
# Check required method are implemented
208-
assert isinstance(unit, UnitProxy)
209-
active_state = await unit.get_active_state()
210-
return active_state == ActiveState.ACTIVE
211-
except DBusError as error:
63+
systemd_service = self.bus.get_object("org.freedesktop.systemd1", object_path=self.manager.GetUnit(service))
64+
unit = dbus.Interface(systemd_service, "org.freedesktop.systemd1.Unit")
65+
unit_properties = dbus.Interface(unit, "org.freedesktop.DBus.Properties")
66+
active_state = unit_properties.Get("org.freedesktop.systemd1.Unit", "ActiveState")
67+
return active_state == "active"
68+
except DBusException as error:
21269
logger.error(error)
21370
return False
21471

215-
async def enable_and_start(self, service: str) -> None:
216-
if not await self.is_service_enabled(service):
217-
await self.enable(service)
218-
if not await self.is_service_active(service):
219-
await self.start(service)
220-
221-
async def stop_and_disable(self, service: str) -> None:
222-
if await self.is_service_active(service):
223-
await self.stop(service)
224-
if await self.is_service_enabled(service):
225-
await self.disable(service)
72+
def enable_and_start(self, service: str) -> None:
73+
if not self.is_service_enabled(service):
74+
self.enable(service)
75+
if not self.is_service_active(service):
76+
self.start(service)

0 commit comments

Comments
 (0)