@mastra/e2b 0.2.0-alpha.0 → 0.3.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +48 -0
- package/README.md +7 -1
- package/dist/index.cjs +231 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +231 -1
- package/dist/index.js.map +1 -1
- package/dist/sandbox/index.d.ts.map +1 -1
- package/dist/sandbox/mounts/azure.d.ts +40 -0
- package/dist/sandbox/mounts/azure.d.ts.map +1 -0
- package/dist/sandbox/mounts/index.d.ts +1 -0
- package/dist/sandbox/mounts/index.d.ts.map +1 -1
- package/dist/sandbox/mounts/types.d.ts +3 -2
- package/dist/sandbox/mounts/types.d.ts.map +1 -1
- package/package.json +11 -11
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,53 @@
|
|
|
1
1
|
# @mastra/e2b
|
|
2
2
|
|
|
3
|
+
## 0.3.0-alpha.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- Added Azure Blob sandbox mount support via blobfuse2 in @mastra/e2b and @mastra/daytona. `sandbox.mount(azureBlobFilesystem, '/data')` now works for Azure containers, matching the existing s3fs (S3) and gcsfuse (GCS) integration. Supports authentication via accountKey, sasToken, connectionString, or managed identity/default credentials, and preserves AzureBlobFilesystem prefixes when mounting. ([#15874](https://github.com/mastra-ai/mastra/pull/15874))
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
import { E2BSandbox } from '@mastra/e2b';
|
|
11
|
+
import { AzureBlobFilesystem } from '@mastra/azure/blob';
|
|
12
|
+
|
|
13
|
+
const azureFs = new AzureBlobFilesystem({ container: 'my-data', connectionString: '...' });
|
|
14
|
+
const sandbox = new E2BSandbox();
|
|
15
|
+
await sandbox.mount(azureFs, '/data');
|
|
16
|
+
// Sandbox processes can now read/write /data/* directly against the Azure container.
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
### Patch Changes
|
|
20
|
+
|
|
21
|
+
- Updated dependencies [[`512a013`](https://github.com/mastra-ai/mastra/commit/512a013f285aa9c0aa8f08a35b2ce09f9938b017), [`e9becde`](https://github.com/mastra-ai/mastra/commit/e9becdeed9176b9f8392e557bde12b933f99cf7a)]:
|
|
22
|
+
- @mastra/core@1.29.1-alpha.2
|
|
23
|
+
|
|
24
|
+
## 0.2.0
|
|
25
|
+
|
|
26
|
+
### Minor Changes
|
|
27
|
+
|
|
28
|
+
- Added S3 prefix (subdirectory) mount support. You can now mount a specific folder within an S3 bucket instead of the entire bucket by setting the `prefix` option on your S3 filesystem. ([#15171](https://github.com/mastra-ai/mastra/pull/15171))
|
|
29
|
+
|
|
30
|
+
**Example:**
|
|
31
|
+
|
|
32
|
+
```typescript
|
|
33
|
+
const fs = new S3Filesystem({
|
|
34
|
+
bucket: 'my-bucket',
|
|
35
|
+
region: 'us-east-1',
|
|
36
|
+
prefix: 'workspace/data',
|
|
37
|
+
accessKeyId: process.env.AWS_ACCESS_KEY_ID!,
|
|
38
|
+
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!,
|
|
39
|
+
});
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
When mounted in a sandbox, only the contents under `workspace/data/` in the bucket will be visible at the mount path. This uses the s3fs `bucket:/path` syntax under the hood.
|
|
43
|
+
|
|
44
|
+
Closes #15147.
|
|
45
|
+
|
|
46
|
+
### Patch Changes
|
|
47
|
+
|
|
48
|
+
- Updated dependencies [[`f112db1`](https://github.com/mastra-ai/mastra/commit/f112db179557ae9b5a0f1d25dc47f928d7d61cd9), [`21d9706`](https://github.com/mastra-ai/mastra/commit/21d970604d89eee970cbf8013d26d7551aff6ea5), [`0a0aa94`](https://github.com/mastra-ai/mastra/commit/0a0aa94729592e99885af2efb90c56aaada62247), [`ed07df3`](https://github.com/mastra-ai/mastra/commit/ed07df32a9d539c8261e892fc1bade783f5b41a6), [`01a7d51`](https://github.com/mastra-ai/mastra/commit/01a7d513493d21562f677f98550f7ceb165ba78c)]:
|
|
49
|
+
- @mastra/core@1.27.0
|
|
50
|
+
|
|
3
51
|
## 0.2.0-alpha.0
|
|
4
52
|
|
|
5
53
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -31,11 +31,12 @@ const agent = new Agent({
|
|
|
31
31
|
|
|
32
32
|
### Mounting Cloud Storage
|
|
33
33
|
|
|
34
|
-
E2B sandboxes can mount S3 or
|
|
34
|
+
E2B sandboxes can mount S3, GCS, or Azure Blob filesystems, making cloud storage accessible as a local directory inside the sandbox:
|
|
35
35
|
|
|
36
36
|
```typescript
|
|
37
37
|
import { Workspace } from '@mastra/core/workspace';
|
|
38
38
|
import { S3Filesystem } from '@mastra/s3';
|
|
39
|
+
import { AzureBlobFilesystem } from '@mastra/azure/blob';
|
|
39
40
|
import { E2BSandbox } from '@mastra/e2b';
|
|
40
41
|
|
|
41
42
|
const workspace = new Workspace({
|
|
@@ -46,6 +47,11 @@ const workspace = new Workspace({
|
|
|
46
47
|
accessKeyId: process.env.AWS_ACCESS_KEY_ID,
|
|
47
48
|
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
|
|
48
49
|
}),
|
|
50
|
+
'/azure-data': new AzureBlobFilesystem({
|
|
51
|
+
container: 'my-container',
|
|
52
|
+
connectionString: process.env.AZURE_STORAGE_CONNECTION_STRING,
|
|
53
|
+
prefix: 'workspace/data',
|
|
54
|
+
}),
|
|
49
55
|
},
|
|
50
56
|
sandbox: new E2BSandbox(),
|
|
51
57
|
});
|
package/dist/index.cjs
CHANGED
|
@@ -197,6 +197,231 @@ async function mountGCS(mountPath, config, ctx) {
|
|
|
197
197
|
throw new Error(`Failed to mount GCS bucket: ${stderr || stdout || error}`);
|
|
198
198
|
}
|
|
199
199
|
}
|
|
200
|
+
var SAFE_CONTAINER_NAME = /^[a-z0-9][a-z0-9-]{1,61}[a-z0-9]$/;
|
|
201
|
+
var BLOBFUSE2_GITHUB_DEB = "https://github.com/Azure/azure-storage-fuse/releases/download/blobfuse2-2.5.1/blobfuse2-2.5.1-Ubuntu-22.04.x86_64.deb";
|
|
202
|
+
function validateContainerName(name) {
|
|
203
|
+
if (!SAFE_CONTAINER_NAME.test(name) || name.includes("--")) {
|
|
204
|
+
throw new Error(
|
|
205
|
+
`Invalid Azure container name: "${name}". Container names must be 3-63 lowercase alphanumeric characters or hyphens, with no consecutive hyphens.`
|
|
206
|
+
);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
function parseConnectionString(cs) {
|
|
210
|
+
const out = {};
|
|
211
|
+
for (const part of cs.split(";")) {
|
|
212
|
+
const eq = part.indexOf("=");
|
|
213
|
+
if (eq === -1) continue;
|
|
214
|
+
const key = part.slice(0, eq).trim();
|
|
215
|
+
const value = part.slice(eq + 1).trim();
|
|
216
|
+
if (!value) continue;
|
|
217
|
+
if (key === "AccountName") out.accountName = value;
|
|
218
|
+
else if (key === "AccountKey") out.accountKey = value;
|
|
219
|
+
else if (key === "SharedAccessSignature") out.sasToken = value;
|
|
220
|
+
else if (key === "BlobEndpoint") out.endpoint = value;
|
|
221
|
+
else if (key === "EndpointSuffix") out.endpointSuffix = value;
|
|
222
|
+
else if (key === "DefaultEndpointsProtocol") out.protocol = value;
|
|
223
|
+
}
|
|
224
|
+
if (!out.endpoint && out.accountName) {
|
|
225
|
+
out.endpoint = `${out.protocol || "https"}://${out.accountName}.blob.${out.endpointSuffix || "core.windows.net"}`;
|
|
226
|
+
}
|
|
227
|
+
return out;
|
|
228
|
+
}
|
|
229
|
+
function yamlString(value) {
|
|
230
|
+
return `"${value.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`;
|
|
231
|
+
}
|
|
232
|
+
function parseOsRelease(output) {
|
|
233
|
+
const values = {};
|
|
234
|
+
for (const line of output.split("\n")) {
|
|
235
|
+
const eq = line.indexOf("=");
|
|
236
|
+
if (eq === -1) continue;
|
|
237
|
+
const key = line.slice(0, eq);
|
|
238
|
+
const value = line.slice(eq + 1).trim().replace(/^"|"$/g, "");
|
|
239
|
+
values[key] = value;
|
|
240
|
+
}
|
|
241
|
+
return values;
|
|
242
|
+
}
|
|
243
|
+
function resolveMicrosoftAptRepos(osReleaseOutput) {
|
|
244
|
+
const osRelease = parseOsRelease(osReleaseOutput);
|
|
245
|
+
const distroId = osRelease.ID || "ubuntu";
|
|
246
|
+
const codename = osRelease.VERSION_CODENAME || (distroId === "debian" ? "bookworm" : "jammy");
|
|
247
|
+
const versionId = osRelease.VERSION_ID || (distroId === "debian" ? "12" : "22.04");
|
|
248
|
+
if (!/^[a-z0-9][a-z0-9-]*$/.test(codename)) {
|
|
249
|
+
throw new Error(`Invalid distro codename for blobfuse2 repo: "${codename}"`);
|
|
250
|
+
}
|
|
251
|
+
if (!/^\d+(?:\.\d+)?$/.test(versionId)) {
|
|
252
|
+
throw new Error(`Invalid distro version for blobfuse2 repo: "${versionId}"`);
|
|
253
|
+
}
|
|
254
|
+
if (distroId === "debian") {
|
|
255
|
+
const repos = [
|
|
256
|
+
{ repoUrl: `https://packages.microsoft.com/debian/${versionId.split(".")[0]}/prod`, suite: codename }
|
|
257
|
+
];
|
|
258
|
+
if (versionId.split(".")[0] !== "12" || codename !== "bookworm") {
|
|
259
|
+
repos.push({ repoUrl: "https://packages.microsoft.com/debian/12/prod", suite: "bookworm" });
|
|
260
|
+
}
|
|
261
|
+
return repos;
|
|
262
|
+
}
|
|
263
|
+
if (distroId === "ubuntu") {
|
|
264
|
+
const repos = [{ repoUrl: `https://packages.microsoft.com/ubuntu/${versionId}/prod`, suite: codename }];
|
|
265
|
+
if (versionId !== "24.04" || codename !== "noble") {
|
|
266
|
+
repos.push({ repoUrl: "https://packages.microsoft.com/ubuntu/24.04/prod", suite: "noble" });
|
|
267
|
+
}
|
|
268
|
+
if (versionId !== "22.04" || codename !== "jammy") {
|
|
269
|
+
repos.push({ repoUrl: "https://packages.microsoft.com/ubuntu/22.04/prod", suite: "jammy" });
|
|
270
|
+
}
|
|
271
|
+
return repos;
|
|
272
|
+
}
|
|
273
|
+
throw new Error(`Unsupported distro for blobfuse2 runtime installation: "${distroId}"`);
|
|
274
|
+
}
|
|
275
|
+
function resolveAuth(config) {
|
|
276
|
+
let accountName = config.accountName;
|
|
277
|
+
let accountKey = config.accountKey;
|
|
278
|
+
let sasToken = config.sasToken;
|
|
279
|
+
let endpoint = config.endpoint;
|
|
280
|
+
if (config.connectionString) {
|
|
281
|
+
const parsed = parseConnectionString(config.connectionString);
|
|
282
|
+
accountName = accountName ?? parsed.accountName;
|
|
283
|
+
accountKey = accountKey ?? parsed.accountKey;
|
|
284
|
+
sasToken = sasToken ?? parsed.sasToken;
|
|
285
|
+
endpoint = endpoint ?? parsed.endpoint;
|
|
286
|
+
}
|
|
287
|
+
let mode;
|
|
288
|
+
if (config.useDefaultCredential) {
|
|
289
|
+
mode = "msi";
|
|
290
|
+
} else if (sasToken) {
|
|
291
|
+
mode = "sas";
|
|
292
|
+
} else if (accountKey) {
|
|
293
|
+
mode = "key";
|
|
294
|
+
} else {
|
|
295
|
+
throw new Error(
|
|
296
|
+
"Azure Blob mount requires credentials: provide connectionString, accountKey + accountName, sasToken + accountName, or useDefaultCredential."
|
|
297
|
+
);
|
|
298
|
+
}
|
|
299
|
+
if (!accountName) {
|
|
300
|
+
throw new Error("Azure Blob mount requires an accountName (either explicitly or via connectionString).");
|
|
301
|
+
}
|
|
302
|
+
if (endpoint) {
|
|
303
|
+
validateEndpoint(endpoint);
|
|
304
|
+
}
|
|
305
|
+
return { mode, accountName, accountKey, sasToken, endpoint };
|
|
306
|
+
}
|
|
307
|
+
function buildBlobfuseConfig(container, auth, cachePath, readOnly) {
|
|
308
|
+
const lines = [
|
|
309
|
+
"allow-other: true",
|
|
310
|
+
"foreground: false",
|
|
311
|
+
`read-only: ${readOnly ? "true" : "false"}`,
|
|
312
|
+
"logging:",
|
|
313
|
+
" type: silent",
|
|
314
|
+
"components:",
|
|
315
|
+
" - libfuse",
|
|
316
|
+
" - file_cache",
|
|
317
|
+
" - attr_cache",
|
|
318
|
+
" - azstorage",
|
|
319
|
+
"libfuse:",
|
|
320
|
+
" attribute-expiration-sec: 240",
|
|
321
|
+
" entry-expiration-sec: 240",
|
|
322
|
+
" negative-entry-expiration-sec: 120",
|
|
323
|
+
"file_cache:",
|
|
324
|
+
` path: ${yamlString(cachePath)}`,
|
|
325
|
+
" timeout-sec: 120",
|
|
326
|
+
"attr_cache:",
|
|
327
|
+
" timeout-sec: 7200",
|
|
328
|
+
"azstorage:",
|
|
329
|
+
` mode: ${auth.mode}`,
|
|
330
|
+
` account-name: ${yamlString(auth.accountName)}`,
|
|
331
|
+
` container: ${yamlString(container)}`
|
|
332
|
+
];
|
|
333
|
+
if (auth.mode === "key" && auth.accountKey) {
|
|
334
|
+
lines.push(` account-key: ${yamlString(auth.accountKey)}`);
|
|
335
|
+
} else if (auth.mode === "sas" && auth.sasToken) {
|
|
336
|
+
lines.push(` sas: ${yamlString(auth.sasToken)}`);
|
|
337
|
+
}
|
|
338
|
+
if (auth.endpoint) {
|
|
339
|
+
lines.push(` endpoint: ${yamlString(auth.endpoint.replace(/\/$/, ""))}`);
|
|
340
|
+
}
|
|
341
|
+
return lines.join("\n") + "\n";
|
|
342
|
+
}
|
|
343
|
+
async function mountAzure(mountPath, config, ctx) {
|
|
344
|
+
const { sandbox, logger } = ctx;
|
|
345
|
+
validateContainerName(config.container);
|
|
346
|
+
const auth = resolveAuth(config);
|
|
347
|
+
const prefix = config.prefix ? validatePrefix(config.prefix) : void 0;
|
|
348
|
+
const checkResult = await sandbox.commands.run('which blobfuse2 || echo "not found"');
|
|
349
|
+
if (checkResult.stdout.includes("not found")) {
|
|
350
|
+
logger.warn(`${LOG_PREFIX} blobfuse2 not found, attempting runtime installation...`);
|
|
351
|
+
logger.info(
|
|
352
|
+
`${LOG_PREFIX} Tip: For faster startup, pre-install blobfuse2 in your sandbox template via createMountableTemplate()`
|
|
353
|
+
);
|
|
354
|
+
const osReleaseResult = await sandbox.commands.run("cat /etc/os-release 2>/dev/null || true");
|
|
355
|
+
const repos = resolveMicrosoftAptRepos(osReleaseResult.stdout);
|
|
356
|
+
const repoSetupResult = await sandbox.commands.run(
|
|
357
|
+
"sudo mkdir -p /etc/apt/keyrings && curl --retry 3 --retry-all-errors --retry-delay 2 -fsSL https://packages.microsoft.com/keys/microsoft.asc -o /tmp/ms-key.asc && sudo gpg --batch --yes --dearmor -o /etc/apt/keyrings/microsoft.gpg /tmp/ms-key.asc",
|
|
358
|
+
{ timeoutMs: 6e4 }
|
|
359
|
+
);
|
|
360
|
+
let installResult;
|
|
361
|
+
if (repoSetupResult.exitCode === 0) {
|
|
362
|
+
for (const { repoUrl, suite } of repos) {
|
|
363
|
+
installResult = await sandbox.commands.run(
|
|
364
|
+
`echo "deb [signed-by=/etc/apt/keyrings/microsoft.gpg] ${repoUrl} ${suite} main" | sudo tee /etc/apt/sources.list.d/microsoft-prod.list && sudo apt-get update 2>&1 && sudo apt-get install -y blobfuse2 fuse3 2>&1`,
|
|
365
|
+
{ timeoutMs: 18e4 }
|
|
366
|
+
);
|
|
367
|
+
if (installResult.exitCode === 0) break;
|
|
368
|
+
logger.warn(`${LOG_PREFIX} blobfuse2 install failed for ${repoUrl} ${suite}, trying fallback if available`);
|
|
369
|
+
}
|
|
370
|
+
} else {
|
|
371
|
+
logger.warn(`${LOG_PREFIX} Failed to set up Microsoft apt repository, trying GitHub release fallback`);
|
|
372
|
+
}
|
|
373
|
+
let verifyResult = await sandbox.commands.run("which blobfuse2 && blobfuse2 --version", { timeoutMs: 3e4 });
|
|
374
|
+
if (verifyResult.exitCode !== 0) {
|
|
375
|
+
installResult = await sandbox.commands.run(
|
|
376
|
+
`sudo apt-get update -qq 2>&1 || true && sudo apt-get install -y fuse3 ca-certificates curl 2>&1 && curl -L --retry 3 --retry-all-errors --retry-delay 2 -fSLo /tmp/blobfuse2.deb ${BLOBFUSE2_GITHUB_DEB} && sudo dpkg -i /tmp/blobfuse2.deb 2>&1 && sudo bash -c 'lib=$(find /usr/lib -name "libfuse3.so.3.*" | head -1); [ -z "$lib" ] || ln -sf "$lib" /usr/lib/x86_64-linux-gnu/libfuse3.so.3'`,
|
|
377
|
+
{ timeoutMs: 18e4 }
|
|
378
|
+
);
|
|
379
|
+
verifyResult = await sandbox.commands.run("which blobfuse2 && blobfuse2 --version", { timeoutMs: 3e4 });
|
|
380
|
+
}
|
|
381
|
+
if (!installResult || verifyResult.exitCode !== 0) {
|
|
382
|
+
throw new Error(
|
|
383
|
+
`Failed to install blobfuse2. For Azure Blob mounting, your template needs blobfuse2 and fuse3.
|
|
384
|
+
|
|
385
|
+
Option 1: Use createMountableTemplate() helper:
|
|
386
|
+
import { E2BSandbox, createMountableTemplate } from '@mastra/e2b';
|
|
387
|
+
const sandbox = new E2BSandbox({ template: createMountableTemplate() });
|
|
388
|
+
|
|
389
|
+
Option 2: Customize the base template:
|
|
390
|
+
new E2BSandbox({ template: base => base.aptInstall(['your-packages']) })
|
|
391
|
+
|
|
392
|
+
Error details: ${verifyResult.stderr || verifyResult.stdout || installResult?.stderr || installResult?.stdout || "unknown error"}`
|
|
393
|
+
);
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
const mountHash = crypto.createHash("md5").update(mountPath).digest("hex").slice(0, 8);
|
|
397
|
+
const configPath = `/tmp/.blobfuse2-config-${mountHash}.yaml`;
|
|
398
|
+
const cachePath = `/tmp/blobfuse2-cache-${mountHash}`;
|
|
399
|
+
const yaml = buildBlobfuseConfig(config.container, auth, cachePath, !!config.readOnly);
|
|
400
|
+
await sandbox.commands.run(`sudo rm -f ${configPath}`);
|
|
401
|
+
await sandbox.files.write(configPath, yaml);
|
|
402
|
+
await sandbox.commands.run(`sudo chown root:root ${configPath} && sudo chmod 600 ${configPath}`);
|
|
403
|
+
await sandbox.commands.run(`sudo rm -rf ${shellQuote(cachePath)} && sudo mkdir -p ${shellQuote(cachePath)}`);
|
|
404
|
+
const prefixFlags = prefix ? ` --virtual-directory=true --subdirectory=${shellQuote(prefix)}` : "";
|
|
405
|
+
const mountCmd = `sudo blobfuse2 mount ${shellQuote(mountPath)} --config-file=${shellQuote(configPath)}${prefixFlags}`;
|
|
406
|
+
logger.debug(`${LOG_PREFIX} Mounting Azure Blob:`, mountCmd);
|
|
407
|
+
try {
|
|
408
|
+
const result = await sandbox.commands.run(mountCmd, { timeoutMs: 6e4 });
|
|
409
|
+
logger.debug(`${LOG_PREFIX} blobfuse2 result:`, {
|
|
410
|
+
exitCode: result.exitCode,
|
|
411
|
+
stdout: result.stdout,
|
|
412
|
+
stderr: result.stderr
|
|
413
|
+
});
|
|
414
|
+
if (result.exitCode !== 0) {
|
|
415
|
+
throw new Error(`Failed to mount Azure Blob container: ${result.stderr || result.stdout}`);
|
|
416
|
+
}
|
|
417
|
+
} catch (error) {
|
|
418
|
+
const errorObj = error;
|
|
419
|
+
const stderr = errorObj.result?.stderr || "";
|
|
420
|
+
const stdout = errorObj.result?.stdout || "";
|
|
421
|
+
logger.error(`${LOG_PREFIX} blobfuse2 error:`, { stderr, stdout, error: String(error) });
|
|
422
|
+
throw new Error(`Failed to mount Azure Blob container: ${stderr || stdout || error}`);
|
|
423
|
+
}
|
|
424
|
+
}
|
|
200
425
|
var E2BProcessHandle = class extends workspace.ProcessHandle {
|
|
201
426
|
pid;
|
|
202
427
|
_e2bHandle;
|
|
@@ -604,6 +829,11 @@ var E2BSandbox = class extends workspace.MastraSandbox {
|
|
|
604
829
|
await mountGCS(mountPath, config, mountCtx);
|
|
605
830
|
this.logger.debug(`${LOG_PREFIX} Mounted GCS bucket at ${mountPath}`);
|
|
606
831
|
break;
|
|
832
|
+
case "azure-blob":
|
|
833
|
+
this.logger.debug(`${LOG_PREFIX} Mounting Azure Blob container at ${mountPath}...`);
|
|
834
|
+
await mountAzure(mountPath, config, mountCtx);
|
|
835
|
+
this.logger.debug(`${LOG_PREFIX} Mounted Azure Blob container at ${mountPath}`);
|
|
836
|
+
break;
|
|
607
837
|
default:
|
|
608
838
|
this.mounts.set(mountPath, {
|
|
609
839
|
filesystem,
|
|
@@ -679,7 +909,7 @@ var E2BSandbox = class extends workspace.MastraSandbox {
|
|
|
679
909
|
}
|
|
680
910
|
this.logger.debug(`${LOG_PREFIX} Reconciling mounts. Expected paths:`, expectedMountPaths);
|
|
681
911
|
const mountsResult = await this._sandbox.commands.run(
|
|
682
|
-
`grep -E 'fuse\\.(s3fs|gcsfuse)' /proc/mounts | awk '{print $2}'`
|
|
912
|
+
`grep -E 'fuse\\.(s3fs|gcsfuse|blobfuse2)' /proc/mounts | awk '{print $2}'`
|
|
683
913
|
);
|
|
684
914
|
const currentMounts = mountsResult.stdout.trim().split("\n").filter((p) => p.length > 0);
|
|
685
915
|
this.logger.debug(`${LOG_PREFIX} Current FUSE mounts in sandbox:`, currentMounts);
|