Skip to content

Commit 068efa2

Browse files
committed
Problem: As a user we cannot create a confidential VM using the SDK.
Solution: Implement new confidential VM fields.
1 parent 94fb089 commit 068efa2

File tree

2 files changed

+48
-1
lines changed

2 files changed

+48
-1
lines changed

src/aleph/sdk/client/authenticated_http.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,11 @@
2929
from aleph_message.models.execution.base import Encoding, Payment, PaymentType
3030
from aleph_message.models.execution.environment import (
3131
FunctionEnvironment,
32+
HostRequirements,
3233
HypervisorType,
3334
InstanceEnvironment,
3435
MachineResources,
36+
TrustedExecutionEnvironment,
3537
)
3638
from aleph_message.models.execution.instance import RootfsVolume
3739
from aleph_message.models.execution.program import CodeContent, FunctionRuntime
@@ -522,10 +524,13 @@ async def create_instance(
522524
internet: bool = True,
523525
aleph_api: bool = True,
524526
hypervisor: Optional[HypervisorType] = None,
527+
confidential_firmware: Optional[ItemHash] = None,
528+
confidential_policy: Optional[int] = None,
525529
volumes: Optional[List[Mapping]] = None,
526530
volume_persistence: str = "host",
527531
ssh_keys: Optional[List[str]] = None,
528532
metadata: Optional[Mapping[str, Any]] = None,
533+
requirements: Optional[HostRequirements] = None,
529534
) -> Tuple[InstanceMessage, MessageStatus]:
530535
address = address or settings.ADDRESS_TO_USE or self.account.get_address()
531536

@@ -536,6 +541,14 @@ async def create_instance(
536541

537542
payment = payment or Payment(chain=Chain.ETH, type=PaymentType.hold)
538543

544+
if confidential_firmware or confidential_policy:
545+
confidential_options = TrustedExecutionEnvironment(
546+
firmware=confidential_firmware,
547+
policy=confidential_policy,
548+
)
549+
else:
550+
confidential_options = None
551+
539552
# Default to the QEMU hypervisor for instances.
540553
selected_hypervisor: HypervisorType = hypervisor or HypervisorType.qemu
541554

@@ -546,6 +559,7 @@ async def create_instance(
546559
internet=internet,
547560
aleph_api=aleph_api,
548561
hypervisor=selected_hypervisor,
562+
trusted_execution=confidential_options,
549563
),
550564
variables=environment_variables,
551565
resources=MachineResources(
@@ -563,6 +577,7 @@ async def create_instance(
563577
use_latest=True,
564578
),
565579
volumes=[parse_volume(volume) for volume in volumes],
580+
requirements=requirements,
566581
time=time.time(),
567582
authorized_keys=ssh_keys,
568583
metadata=metadata,

tests/unit/test_asynchronous.py

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,12 @@
1414
ProgramMessage,
1515
StoreMessage,
1616
)
17-
from aleph_message.models.execution.environment import HypervisorType, MachineResources
17+
from aleph_message.models.execution.environment import (
18+
HostRequirements,
19+
HypervisorType,
20+
MachineResources,
21+
NodeRequirements,
22+
)
1823
from aleph_message.status import MessageStatus
1924

2025
from aleph.sdk.exceptions import InsufficientFundsError
@@ -163,6 +168,33 @@ async def test_create_instance_no_hypervisor(mock_session_with_post_success):
163168
assert isinstance(instance_message, InstanceMessage)
164169

165170

171+
@pytest.mark.asyncio
172+
async def test_create_confidential_instance(mock_session_with_post_success):
173+
async with mock_session_with_post_success as session:
174+
confidential_instance_message, message_status = await session.create_instance(
175+
rootfs="cafecafecafecafecafecafecafecafecafecafecafecafecafecafecafecafe",
176+
rootfs_size=1,
177+
channel="TEST",
178+
metadata={"tags": ["test"]},
179+
payment=Payment(
180+
chain=Chain.AVAX,
181+
receiver="0x4145f182EF2F06b45E50468519C1B92C60FBd4A0",
182+
type=PaymentType.superfluid,
183+
),
184+
hypervisor=HypervisorType.qemu,
185+
confidential_firmware="cafecafecafecafecafecafecafecafecafecafecafecafecafecafecafecafe",
186+
confidential_policy=0b1,
187+
requirements=HostRequirements(
188+
node=NodeRequirements(
189+
node_hash="cafecafecafecafecafecafecafecafecafecafecafecafecafecafecafecafe",
190+
)
191+
),
192+
)
193+
194+
assert mock_session_with_post_success.http_session.post.assert_called_once
195+
assert isinstance(confidential_instance_message, InstanceMessage)
196+
197+
166198
@pytest.mark.asyncio
167199
async def test_forget(mock_session_with_post_success):
168200
async with mock_session_with_post_success as session:

0 commit comments

Comments
 (0)