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
11 changes: 10 additions & 1 deletion src/aleph/sdk/client/abstract.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,11 @@
PostMessage,
parse_message,
)
from aleph_message.models.execution.environment import HypervisorType
from aleph_message.models.execution.environment import (
HostRequirements,
HypervisorType,
TrustedExecutionEnvironment,
)
from aleph_message.models.execution.program import Encoding
from aleph_message.status import MessageStatus

Expand Down Expand Up @@ -395,10 +399,12 @@ async def create_instance(
internet: bool = True,
aleph_api: bool = True,
hypervisor: Optional[HypervisorType] = None,
trusted_execution: Optional[TrustedExecutionEnvironment] = None,
volumes: Optional[List[Mapping]] = None,
volume_persistence: str = "host",
ssh_keys: Optional[List[str]] = None,
metadata: Optional[Mapping[str, Any]] = None,
requirements: Optional[HostRequirements] = None,
) -> Tuple[AlephMessage, MessageStatus]:
"""
Post a (create) INSTANCE message.
Expand All @@ -417,11 +423,14 @@ async def create_instance(
:param allow_amend: Whether the deployed VM image may be changed (Default: False)
:param internet: Whether the VM should have internet connectivity. (Default: True)
:param aleph_api: Whether the VM needs access to Aleph messages API (Default: True)
:param hypervisor: Whether the VM should use as Hypervisor, like QEmu or Firecracker (Default: Qemu)
:param trusted_execution: Whether the VM configuration (firmware and policy) to use for Confidential computing (Default: None)
:param encoding: Encoding to use (Default: Encoding.zip)
:param volumes: Volumes to mount
:param volume_persistence: Where volumes are persisted, can be "host" or "store", meaning distributed across Aleph.im (Default: "host")
:param ssh_keys: SSH keys to authorize access to the VM
:param metadata: Metadata to attach to the message
:param requirements: CRN Requirements needed for the VM execution
"""
raise NotImplementedError(
"Did you mean to import `AuthenticatedAlephHttpClient`?"
Expand Down
6 changes: 6 additions & 0 deletions src/aleph/sdk/client/authenticated_http.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,11 @@
from aleph_message.models.execution.base import Encoding, Payment, PaymentType
from aleph_message.models.execution.environment import (
FunctionEnvironment,
HostRequirements,
HypervisorType,
InstanceEnvironment,
MachineResources,
TrustedExecutionEnvironment,
)
from aleph_message.models.execution.instance import RootfsVolume
from aleph_message.models.execution.program import CodeContent, FunctionRuntime
Expand Down Expand Up @@ -522,10 +524,12 @@ async def create_instance(
internet: bool = True,
aleph_api: bool = True,
hypervisor: Optional[HypervisorType] = None,
trusted_execution: Optional[TrustedExecutionEnvironment] = None,
volumes: Optional[List[Mapping]] = None,
volume_persistence: str = "host",
ssh_keys: Optional[List[str]] = None,
metadata: Optional[Mapping[str, Any]] = None,
requirements: Optional[HostRequirements] = None,
) -> Tuple[InstanceMessage, MessageStatus]:
address = address or settings.ADDRESS_TO_USE or self.account.get_address()

Expand All @@ -546,6 +550,7 @@ async def create_instance(
internet=internet,
aleph_api=aleph_api,
hypervisor=selected_hypervisor,
trusted_execution=trusted_execution,
),
variables=environment_variables,
resources=MachineResources(
Expand All @@ -563,6 +568,7 @@ async def create_instance(
use_latest=True,
),
volumes=[parse_volume(volume) for volume in volumes],
requirements=requirements,
time=time.time(),
authorized_keys=ssh_keys,
metadata=metadata,
Expand Down
37 changes: 36 additions & 1 deletion tests/unit/test_asynchronous.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,13 @@
ProgramMessage,
StoreMessage,
)
from aleph_message.models.execution.environment import HypervisorType, MachineResources
from aleph_message.models.execution.environment import (
HostRequirements,
HypervisorType,
MachineResources,
NodeRequirements,
TrustedExecutionEnvironment,
)
from aleph_message.status import MessageStatus

from aleph.sdk.exceptions import InsufficientFundsError
Expand Down Expand Up @@ -163,6 +169,35 @@ async def test_create_instance_no_hypervisor(mock_session_with_post_success):
assert isinstance(instance_message, InstanceMessage)


@pytest.mark.asyncio
async def test_create_confidential_instance(mock_session_with_post_success):
async with mock_session_with_post_success as session:
confidential_instance_message, message_status = await session.create_instance(
rootfs="cafecafecafecafecafecafecafecafecafecafecafecafecafecafecafecafe",
rootfs_size=1,
channel="TEST",
metadata={"tags": ["test"]},
payment=Payment(
chain=Chain.AVAX,
receiver="0x4145f182EF2F06b45E50468519C1B92C60FBd4A0",
type=PaymentType.superfluid,
),
hypervisor=HypervisorType.qemu,
trusted_execution=TrustedExecutionEnvironment(
firmware="cafecafecafecafecafecafecafecafecafecafecafecafecafecafecafecafe",
policy=0b1,
),
requirements=HostRequirements(
node=NodeRequirements(
node_hash="cafecafecafecafecafecafecafecafecafecafecafecafecafecafecafecafe",
)
),
)

assert mock_session_with_post_success.http_session.post.assert_called_once
assert isinstance(confidential_instance_message, InstanceMessage)


@pytest.mark.asyncio
async def test_forget(mock_session_with_post_success):
async with mock_session_with_post_success as session:
Expand Down