mirror of
https://github.com/langgenius/dify.git
synced 2026-05-05 01:48:04 +08:00
fix: centralize sandbox temp path management
This commit is contained in:
@ -72,14 +72,14 @@ class SandboxBashSession:
|
|||||||
tools: ToolDependencies,
|
tools: ToolDependencies,
|
||||||
cli_api_session: CliApiSession,
|
cli_api_session: CliApiSession,
|
||||||
) -> str:
|
) -> str:
|
||||||
node_tools_path = f"{cli.tools_root}/{node_id}"
|
node_tools_path = cli.node_tools_path(node_id)
|
||||||
config_json = json.dumps(
|
config_json = json.dumps(
|
||||||
DifyCliConfig.create(session=cli_api_session, tenant_id=self._tenant_id, tool_deps=tools).model_dump(
|
DifyCliConfig.create(session=cli_api_session, tenant_id=self._tenant_id, tool_deps=tools).model_dump(
|
||||||
mode="json"
|
mode="json"
|
||||||
),
|
),
|
||||||
ensure_ascii=False,
|
ensure_ascii=False,
|
||||||
)
|
)
|
||||||
config_path = shlex.quote(f"{node_tools_path}/{DifyCli.CONFIG_FILENAME}")
|
config_path = shlex.quote(cli.node_config_path(node_id))
|
||||||
|
|
||||||
vm = self._sandbox.vm
|
vm = self._sandbox.vm
|
||||||
# Merge mkdir + config write into a single pipeline to reduce round-trips.
|
# Merge mkdir + config write into a single pipeline to reduce round-trips.
|
||||||
|
|||||||
@ -19,15 +19,25 @@ class DifyCli:
|
|||||||
|
|
||||||
# --- instance attributes ---
|
# --- instance attributes ---
|
||||||
root: str
|
root: str
|
||||||
|
bin_dir: str
|
||||||
bin_path: str
|
bin_path: str
|
||||||
tools_root: str
|
tools_root: str
|
||||||
global_tools_path: str
|
global_tools_path: str
|
||||||
|
global_config_path: str
|
||||||
|
|
||||||
def __init__(self, env_id: str) -> None:
|
def __init__(self, env_id: str) -> None:
|
||||||
self.root = f"/tmp/.dify/{env_id}"
|
self.root = f"/tmp/.dify/{env_id}"
|
||||||
self.bin_path = f"{self.root}/bin/dify"
|
self.bin_dir = f"{self.root}/bin"
|
||||||
|
self.bin_path = f"{self.bin_dir}/dify"
|
||||||
self.tools_root = f"{self.root}/tools"
|
self.tools_root = f"{self.root}/tools"
|
||||||
self.global_tools_path = f"{self.root}/tools/global"
|
self.global_tools_path = f"{self.root}/tools/global"
|
||||||
|
self.global_config_path = f"{self.global_tools_path}/{DifyCli.CONFIG_FILENAME}"
|
||||||
|
|
||||||
|
def node_tools_path(self, node_id: str) -> str:
|
||||||
|
return f"{self.tools_root}/{node_id}"
|
||||||
|
|
||||||
|
def node_config_path(self, node_id: str) -> str:
|
||||||
|
return f"{self.node_tools_path(node_id)}/{DifyCli.CONFIG_FILENAME}"
|
||||||
|
|
||||||
|
|
||||||
class AppAssets:
|
class AppAssets:
|
||||||
@ -40,7 +50,9 @@ class AppAssets:
|
|||||||
|
|
||||||
PATH: Final[str] = "skills"
|
PATH: Final[str] = "skills"
|
||||||
|
|
||||||
|
root: str
|
||||||
zip_path: str
|
zip_path: str
|
||||||
|
|
||||||
def __init__(self, env_id: str) -> None:
|
def __init__(self, env_id: str) -> None:
|
||||||
self.zip_path = f"/tmp/.dify/{env_id}/assets.zip"
|
self.root = f"/tmp/.dify/{env_id}"
|
||||||
|
self.zip_path = f"{self.root}/assets.zip"
|
||||||
|
|||||||
@ -26,11 +26,11 @@ class AppAssetsInitializer(AsyncSandboxInitializer):
|
|||||||
(
|
(
|
||||||
pipeline(vm)
|
pipeline(vm)
|
||||||
.add(
|
.add(
|
||||||
["mkdir", "-p", f"/tmp/.dify/{sandbox.id}"],
|
["mkdir", "-p", assets.root],
|
||||||
error_message="Failed to create assets temp directory",
|
error_message="Failed to create assets temp directory",
|
||||||
)
|
)
|
||||||
.add(
|
.add(
|
||||||
["curl", "-fsSL", download_url, "-o", assets.zip_path],
|
["sh", "-c", 'curl -fsSL "$1" -o "$2"', "sh", download_url, assets.zip_path],
|
||||||
error_message="Failed to download assets zip",
|
error_message="Failed to download assets zip",
|
||||||
)
|
)
|
||||||
# Create the assets directory first to ensure it exists even if zip is empty
|
# Create the assets directory first to ensure it exists even if zip is empty
|
||||||
@ -41,12 +41,12 @@ class AppAssetsInitializer(AsyncSandboxInitializer):
|
|||||||
# unzip with silent error and return 1 if the zip is empty
|
# unzip with silent error and return 1 if the zip is empty
|
||||||
# FIXME(Mairuis): should use a more robust way to check if the zip is empty
|
# FIXME(Mairuis): should use a more robust way to check if the zip is empty
|
||||||
.add(
|
.add(
|
||||||
["sh", "-c", f"unzip {assets.zip_path} -d {AppAssets.PATH} 2>/dev/null || [ $? -eq 1 ]"],
|
["sh", "-c", 'unzip "$1" -d "$2" 2>/dev/null || [ $? -eq 1 ]', "sh", assets.zip_path, AppAssets.PATH],
|
||||||
error_message="Failed to unzip assets",
|
error_message="Failed to unzip assets",
|
||||||
)
|
)
|
||||||
# Ensure directories have execute permission for traversal and files are readable
|
# Ensure directories have execute permission for traversal and files are readable
|
||||||
.add(
|
.add(
|
||||||
["sh", "-c", f"chmod -R u+rwX,go+rX {AppAssets.PATH}"],
|
["sh", "-c", 'chmod -R u+rwX,go+rX "$1"', "sh", AppAssets.PATH],
|
||||||
error_message="Failed to set permissions on assets",
|
error_message="Failed to set permissions on assets",
|
||||||
)
|
)
|
||||||
.execute(timeout=APP_ASSETS_DOWNLOAD_TIMEOUT, raise_on_error=True)
|
.execute(timeout=APP_ASSETS_DOWNLOAD_TIMEOUT, raise_on_error=True)
|
||||||
|
|||||||
@ -33,9 +33,9 @@ class DifyCliInitializer(AsyncSandboxInitializer):
|
|||||||
# FIXME(Mairuis): should be more robust, effectively.
|
# FIXME(Mairuis): should be more robust, effectively.
|
||||||
binary = self._locator.resolve(vm.metadata.os, vm.metadata.arch)
|
binary = self._locator.resolve(vm.metadata.os, vm.metadata.arch)
|
||||||
|
|
||||||
pipeline(vm).add(
|
pipeline(vm).add(["mkdir", "-p", cli.bin_dir], error_message="Failed to create dify CLI directory").execute(
|
||||||
["mkdir", "-p", f"{cli.root}/bin"], error_message="Failed to create dify CLI directory"
|
raise_on_error=True
|
||||||
).execute(raise_on_error=True)
|
)
|
||||||
|
|
||||||
vm.upload_file(cli.bin_path, BytesIO(binary.path.read_bytes()))
|
vm.upload_file(cli.bin_path, BytesIO(binary.path.read_bytes()))
|
||||||
|
|
||||||
@ -69,7 +69,7 @@ class DifyCliInitializer(AsyncSandboxInitializer):
|
|||||||
|
|
||||||
config = DifyCliConfig.create(self._cli_api_session, ctx.tenant_id, bundle.get_tool_dependencies())
|
config = DifyCliConfig.create(self._cli_api_session, ctx.tenant_id, bundle.get_tool_dependencies())
|
||||||
config_json = json.dumps(config.model_dump(mode="json"), ensure_ascii=False)
|
config_json = json.dumps(config.model_dump(mode="json"), ensure_ascii=False)
|
||||||
config_path = f"{cli.global_tools_path}/{DifyCli.CONFIG_FILENAME}"
|
config_path = cli.global_config_path
|
||||||
vm.upload_file(config_path, BytesIO(config_json.encode("utf-8")))
|
vm.upload_file(config_path, BytesIO(config_json.encode("utf-8")))
|
||||||
|
|
||||||
pipeline(vm, cwd=cli.global_tools_path).add(
|
pipeline(vm, cwd=cli.global_tools_path).add(
|
||||||
|
|||||||
Reference in New Issue
Block a user