Skip to content

Commit 5d66bf7

Browse files
authored
Add AlephApp.vm_hash (#52)
This simple property returns the `item_hash` of the Aleph message that created the VM that is currently running (and invoking the method).
1 parent 16e3769 commit 5d66bf7

File tree

2 files changed

+48
-0
lines changed

2 files changed

+48
-0
lines changed

src/aleph/sdk/vm/app.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
import base64
2+
import binascii
3+
import socket
14
from dataclasses import dataclass
25
from typing import (
36
Any,
@@ -85,3 +88,29 @@ async def send_handler_result():
8588
def __getattr__(self, name):
8689
# Default all calls to the HTTP handler
8790
return getattr(self.http_app, name)
91+
92+
@property
93+
def vm_hash(self) -> Optional[str]:
94+
"""
95+
Returns the hash of the VM that is running this app. If the VM is not
96+
running in Aleph, this will return None.
97+
"""
98+
# Get hostname from environment
99+
hostname = socket.gethostname()
100+
101+
# Add padding if necessary
102+
padding_length = len(hostname) % 8
103+
if padding_length != 0:
104+
hostname += "=" * (8 - padding_length)
105+
106+
try:
107+
# Convert the hostname back to its original binary form
108+
item_hash_binary = base64.b32decode(hostname.upper())
109+
110+
# Convert the binary form to the original vm_hash
111+
vm_hash = base64.b16encode(item_hash_binary).decode().lower()
112+
except binascii.Error:
113+
# If the hostname is not a valid base32 string, just return None
114+
return None
115+
116+
return vm_hash

tests/unit/test_vm_app.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import asyncio
2+
import base64
23

34
import pytest
45
from fastapi.testclient import TestClient
@@ -31,3 +32,21 @@ def test_app_http():
3132
response = client.get("/")
3233
assert response.status_code == 200
3334
assert response.json() == {"index": "/"}
35+
36+
37+
def test_get_vm_hash(mocker):
38+
vm_hash = "deadbeef" * 8
39+
# Uses the same logic as
40+
# https://github.com/aleph-im/aleph-vm/blob/main/runtimes/aleph-debian-11-python/init1.py#L488
41+
item_hash_binary: bytes = base64.b16decode(vm_hash.encode().upper())
42+
hostname = base64.b32encode(item_hash_binary).decode().strip("=").lower()
43+
44+
mocker.patch("socket.gethostname", return_value=hostname)
45+
46+
assert app.vm_hash == vm_hash
47+
48+
49+
def test_get_vm_hash_no_vm(mocker):
50+
mocker.patch("socket.gethostname", return_value="not-a-vm")
51+
52+
assert app.vm_hash is None

0 commit comments

Comments
 (0)