-
-
Notifications
You must be signed in to change notification settings - Fork 570
mount import directory for pyodide sandbox #2073
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||
|---|---|---|---|---|
|
|
@@ -73,8 +73,16 @@ class GristPipe { | |||
| async mountImportDirIfNeeded() { | ||||
| if (process.env.IMPORTDIR) { | ||||
| this.log("Setting up import from", process.env.IMPORTDIR); | ||||
| // Could mount directly, but instead copy so we can drop read perms early. | ||||
| await this.copyFiles(process.env.IMPORTDIR, "/import_src", "/import"); | ||||
| // All imports for a given doc live in the same root directory. | ||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is it worth adding to this comment, something like:
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added. |
||||
| // Copying import files in and dropping read permissions isn't | ||||
| // workable in that case, since the same sandbox is re-used for | ||||
| // subsequent imports. The files would only be copied once on | ||||
| // startup, meaning the files for these later imports won't be | ||||
| // available to Pyodide, resulting in errors. | ||||
| await this.pyodide.FS.mkdir("/import"); | ||||
| await this.pyodide.FS.mount(this.pyodide.FS.filesystems.NODEFS, { | ||||
| root: process.env.IMPORTDIR, | ||||
| }, "/import"); | ||||
| } | ||||
| } | ||||
|
|
||||
|
|
@@ -146,11 +154,22 @@ async function main() { | |||
|
|
||||
| if (isDeno) { | ||||
| // Revoke write permissions now that packages are loaded. | ||||
| // Revoke read access as well, why not. | ||||
| // eslint-disable-next-line no-undef | ||||
| await Deno.permissions.revoke({ name: "write" }); | ||||
| // eslint-disable-next-line no-undef | ||||
| await Deno.permissions.revoke({ name: "read" }); | ||||
|
|
||||
| // Read access has been limited quite a lot already. | ||||
| // We need to keep access to the import directory, but can shed | ||||
| // everything else. See --allow-read in SandboxPyodide.ts | ||||
| const readDir = fs.realpathSync(__dirname); | ||||
| const gristDir = fs.realpathSync(path.join(__dirname, "..", "grist")); | ||||
| const reqFile = fs.realpathSync(path.join(__dirname, "..", "requirements.txt")); | ||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For my own understanding, why is I think I see the reason for adding (Thanks for the comment BTW, it is very helpful to understand a bit more the context!)
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For
This could be done a different way, but is what is there right now.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Correct about the rest. |
||||
| for (const dir of [readDir, gristDir, reqFile]) { | ||||
| // eslint-disable-next-line no-undef | ||||
| await Deno.permissions.revoke({ | ||||
| name: "read", | ||||
| path: dir | ||||
| }); | ||||
| } | ||||
| console.error("[pyodide sandbox]", "revoked read and write permissions."); | ||||
| } | ||||
|
|
||||
|
|
||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alright,
IMPORTDIRis a subdirectory to a temporary directory attributed exclusively to the ActiveDoc?Also after adding some logs, I found that a sandbox is spawned during the import, am I right? It is fine here to share the same import directory because it is scoped to the ActiveDoc? (in which case it would make sense to me too)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes that is what @Spoffy found when working on a Grist Desktop issue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That was my understanding / findings on how this all worked, yeah. The logic connecting
parseFileinDocPluginManagerto the sandbox is convoluted, but I'll do my best to summarise:plugins/core/manifest.yml.DocPluginManager(which is created on a per-doc basis) whenDocPluginManageris created.DocPluginManageris created one-per-doc.In short: yes, the temp directory is per active document. 🙂