Skip to content

Commit 13aa170

Browse files
committed
fix server start create buckets for juicefs
1 parent 5e4c9cb commit 13aa170

4 files changed

Lines changed: 21 additions & 7 deletions

File tree

api/api.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -429,8 +429,9 @@ def _effective_storage_provider() -> str:
429429
"""
430430
from lab.storage import STORAGE_PROVIDER
431431

432-
if STORAGE_PROVIDER == "localfs":
433-
return "localfs"
432+
# juicefs and localfs are always active when configured — no TFL_REMOTE_STORAGE_ENABLED gate.
433+
if STORAGE_PROVIDER in ("localfs", "juicefs"):
434+
return STORAGE_PROVIDER
434435
remote_enabled = os.getenv("TFL_REMOTE_STORAGE_ENABLED", "false").lower() == "true"
435436
return STORAGE_PROVIDER if remote_enabled else "localfs"
436437

api/scripts/on_server_start.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,11 @@ async def main() -> None:
2828
# Buckets/containers/local workspace dirs must exist before seed_default_experiments(),
2929
# which writes experiment metadata to remote storage (e.g. Azure block upload).
3030
tfl_remote_storage_enabled = os.getenv("TFL_REMOTE_STORAGE_ENABLED", "false").lower() == "true"
31-
if tfl_remote_storage_enabled or (os.getenv("TFL_STORAGE_PROVIDER") == "localfs" and os.getenv("TFL_STORAGE_URI")):
31+
if (
32+
tfl_remote_storage_enabled
33+
or os.getenv("TFL_STORAGE_PROVIDER") == "juicefs"
34+
or (os.getenv("TFL_STORAGE_PROVIDER") == "localfs" and os.getenv("TFL_STORAGE_URI"))
35+
):
3236
print("✅ CHECKING STORAGE FOR EXISTING TEAMS")
3337
try:
3438
async with async_session() as session:

api/test/api/test_remote_workspace_juicefs.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ def test_validate_juicefs_config_passes_when_valid(monkeypatch, tmp_path):
5959

6060
def test_create_juicefs_directory_creates_dir_and_sets_quota(monkeypatch, tmp_path):
6161
monkeypatch.setenv("TFL_JUICEFS_MOUNT_POINT", str(tmp_path))
62+
monkeypatch.setenv("TFL_JUICEFS_VOLUME_NAME", "myvol")
6263
monkeypatch.setenv("TFL_JUICEFS_QUOTA_GB", "50")
6364

6465
with patch("transformerlab.shared.remote_workspace.subprocess.run") as mock_run:
@@ -68,7 +69,7 @@ def test_create_juicefs_directory_creates_dir_and_sets_quota(monkeypatch, tmp_pa
6869
org_path = os.path.join(str(tmp_path), "orgs", "team-abc")
6970
assert os.path.isdir(org_path)
7071
mock_run.assert_called_once_with(
71-
["juicefs", "quota", "set", org_path, "--capacity", "50"],
72+
["juicefs", "quota", "set", "myvol", "--path", "/orgs/team-abc", "--capacity", "50"],
7273
check=True,
7374
capture_output=True,
7475
text=True,
@@ -77,6 +78,7 @@ def test_create_juicefs_directory_creates_dir_and_sets_quota(monkeypatch, tmp_pa
7778

7879
def test_create_juicefs_directory_returns_false_on_error(monkeypatch, tmp_path):
7980
monkeypatch.setenv("TFL_JUICEFS_MOUNT_POINT", str(tmp_path))
81+
monkeypatch.setenv("TFL_JUICEFS_VOLUME_NAME", "myvol")
8082
monkeypatch.setenv("TFL_JUICEFS_QUOTA_GB", "100")
8183

8284
with patch("transformerlab.shared.remote_workspace.subprocess.run", side_effect=Exception("juicefs not found")):
@@ -87,6 +89,7 @@ def test_create_juicefs_directory_returns_false_on_error(monkeypatch, tmp_path):
8789

8890
def test_create_bucket_for_team_routes_to_juicefs(monkeypatch, tmp_path):
8991
monkeypatch.setenv("TFL_JUICEFS_MOUNT_POINT", str(tmp_path))
92+
monkeypatch.setenv("TFL_JUICEFS_VOLUME_NAME", "myvol")
9093
monkeypatch.setenv("TFL_JUICEFS_QUOTA_GB", "100")
9194
monkeypatch.setattr(remote_workspace, "STORAGE_PROVIDER", "juicefs", raising=False)
9295

api/transformerlab/shared/remote_workspace.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -503,16 +503,21 @@ def _create_azure_container(container_name: str, team_id: str) -> bool:
503503

504504
def _create_juicefs_directory(team_id: str) -> bool:
505505
mount_point = os.getenv("TFL_JUICEFS_MOUNT_POINT", "/mnt/juicefs")
506+
volume_name = os.getenv("TFL_JUICEFS_VOLUME_NAME", "")
506507
quota_gb = int(os.getenv("TFL_JUICEFS_QUOTA_GB", "100"))
507508
org_path = os.path.join(mount_point, "orgs", team_id)
509+
subdir_path = f"/orgs/{team_id}"
508510
try:
509511
os.makedirs(org_path, exist_ok=True)
510512
except OSError as e:
511513
print(f"❌ Failed to create JuiceFS directory {org_path}: {e}")
512514
return False
515+
if not volume_name:
516+
print("❌ TFL_JUICEFS_VOLUME_NAME is not set, cannot set JuiceFS quota")
517+
return False
513518
try:
514519
subprocess.run(
515-
["juicefs", "quota", "set", org_path, "--capacity", str(quota_gb)],
520+
["juicefs", "quota", "set", volume_name, "--path", subdir_path, "--capacity", str(quota_gb)],
516521
check=True,
517522
capture_output=True,
518523
text=True,
@@ -549,6 +554,9 @@ async def create_buckets_for_all_teams(session, profile_name: Optional[str] = No
549554
print("TFL_STORAGE_PROVIDER=localfs but TFL_STORAGE_URI is not set, skipping")
550555
return (0, 0, ["TFL_STORAGE_URI is not set"])
551556
print("Initialising local workspaces for all teams (localfs mode)")
557+
elif STORAGE_PROVIDER == "juicefs":
558+
# juicefs doesn't require TFL_REMOTE_STORAGE_ENABLED — it's always active when configured.
559+
print("Initialising JuiceFS directories for all teams")
552560
else:
553561
tfl_remote_storage_enabled = os.getenv("TFL_REMOTE_STORAGE_ENABLED", "false").lower() == "true"
554562
if not tfl_remote_storage_enabled:
@@ -558,8 +566,6 @@ async def create_buckets_for_all_teams(session, profile_name: Optional[str] = No
558566
remote_label = "GCS"
559567
elif STORAGE_PROVIDER == "azure":
560568
remote_label = "Azure"
561-
elif STORAGE_PROVIDER == "juicefs":
562-
remote_label = "JuiceFS"
563569
else:
564570
remote_label = "S3"
565571
print(f"Creating buckets for all teams using {remote_label} (TFL_STORAGE_PROVIDER={STORAGE_PROVIDER})")

0 commit comments

Comments
 (0)