feat(sandbox): enhance SandboxLayer with app_id handling and storage integration

- Introduce _app_id attribute to store application ID from system variables
- Add _get_app_id method to retrieve and validate app_id
- Update on_graph_start to log app_id during sandbox initialization
- Integrate ArchiveSandboxStorage for persisting and restoring sandbox files
- Ensure proper error handling for sandbox file operations
This commit is contained in:
Harry
2026-01-15 00:28:41 +08:00
parent 94ff904a04
commit 6cb8d03bf6

View File

@ -1,9 +1,11 @@
import logging import logging
from core.sandbox.manager import SandboxManager from core.sandbox.manager import SandboxManager
from core.sandbox.storage import ArchiveSandboxStorage
from core.virtual_environment.__base.virtual_environment import VirtualEnvironment from core.virtual_environment.__base.virtual_environment import VirtualEnvironment
from core.workflow.graph_engine.layers.base import GraphEngineLayer from core.workflow.graph_engine.layers.base import GraphEngineLayer
from core.workflow.graph_events.base import GraphEngineEvent from core.workflow.graph_events.base import GraphEngineEvent
from extensions.ext_storage import storage
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -17,6 +19,7 @@ class SandboxLayer(GraphEngineLayer):
super().__init__() super().__init__()
self._tenant_id = tenant_id self._tenant_id = tenant_id
self._workflow_execution_id: str | None = None self._workflow_execution_id: str | None = None
self._app_id: str | None = None
def _get_workflow_execution_id(self) -> str: def _get_workflow_execution_id(self) -> str:
workflow_execution_id = self.graph_runtime_state.system_variable.workflow_execution_id workflow_execution_id = self.graph_runtime_state.system_variable.workflow_execution_id
@ -24,6 +27,12 @@ class SandboxLayer(GraphEngineLayer):
raise RuntimeError("workflow_execution_id is not set in system variables") raise RuntimeError("workflow_execution_id is not set in system variables")
return workflow_execution_id return workflow_execution_id
def _get_app_id(self) -> str:
app_id = self.graph_runtime_state.system_variable.app_id
if not app_id:
raise RuntimeError("app_id is not set in system variables")
return app_id
@property @property
def sandbox(self) -> VirtualEnvironment: def sandbox(self) -> VirtualEnvironment:
if self._workflow_execution_id is None: if self._workflow_execution_id is None:
@ -35,17 +44,18 @@ class SandboxLayer(GraphEngineLayer):
def on_graph_start(self) -> None: def on_graph_start(self) -> None:
self._workflow_execution_id = self._get_workflow_execution_id() self._workflow_execution_id = self._get_workflow_execution_id()
self._app_id = self._get_app_id()
try: try:
from core.sandbox.initializer import AppAssetsInitializer, DifyCliInitializer from core.sandbox.initializer import AppAssetsInitializer, DifyCliInitializer
from services.sandbox.sandbox_provider_service import SandboxProviderService from services.sandbox.sandbox_provider_service import SandboxProviderService
app_id = self.graph_runtime_state.system_variable.app_id logger.info("Initializing sandbox for tenant_id=%s, app_id=%s", self._tenant_id, self._app_id)
logger.info("Initializing sandbox for tenant_id=%s, app_id=%s", self._tenant_id, app_id)
builder = SandboxProviderService.create_sandbox_builder(self._tenant_id).initializer(DifyCliInitializer()) builder = (
if app_id: SandboxProviderService.create_sandbox_builder(self._tenant_id)
builder.initializer(AppAssetsInitializer(self._tenant_id, app_id)) .initializer(DifyCliInitializer())
.initializer(AppAssetsInitializer(self._tenant_id, self._app_id))
)
sandbox = builder.build() sandbox = builder.build()
SandboxManager.register(self._workflow_execution_id, sandbox) SandboxManager.register(self._workflow_execution_id, sandbox)
@ -55,6 +65,14 @@ class SandboxLayer(GraphEngineLayer):
sandbox.metadata.id, sandbox.metadata.id,
sandbox.metadata.arch, sandbox.metadata.arch,
) )
sandbox_storage = ArchiveSandboxStorage(
storage=storage,
tenant_id=self._tenant_id,
sandbox_id=self._workflow_execution_id,
)
if sandbox_storage.mount(sandbox):
logger.info("Sandbox files restored, workflow_execution_id=%s", self._workflow_execution_id)
except Exception as e: except Exception as e:
logger.exception("Failed to initialize sandbox") logger.exception("Failed to initialize sandbox")
raise SandboxInitializationError(f"Failed to initialize sandbox: {e}") from e raise SandboxInitializationError(f"Failed to initialize sandbox: {e}") from e
@ -79,6 +97,17 @@ class SandboxLayer(GraphEngineLayer):
sandbox_id, sandbox_id,
) )
try:
sandbox_storage = ArchiveSandboxStorage(
storage=storage,
tenant_id=self._tenant_id,
sandbox_id=self._workflow_execution_id,
)
sandbox_storage.unmount(sandbox)
logger.info("Sandbox files persisted, workflow_execution_id=%s", self._workflow_execution_id)
except Exception:
logger.exception("Failed to persist sandbox files, workflow_execution_id=%s", self._workflow_execution_id)
try: try:
sandbox.release_environment() sandbox.release_environment()
logger.info("Sandbox released, sandbox_id=%s", sandbox_id) logger.info("Sandbox released, sandbox_id=%s", sandbox_id)