-
Notifications
You must be signed in to change notification settings - Fork 70
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
Support configurable hooking into LavaMoat scuttling #462
Conversation
IntroThinking out loud on how configuration should look like. There are a few things to be considered when deciding on the right configuration for the motivation this PR pushes forward:
Option 1We could turn
Few thoughts:
Option 2We could just implement the activation of Snow as a separate config field, such as
Few thoughts:
Option 3Any other suggestions? Would love to hear them. |
For option1:
But to address the browser being separate, we could do something like this:
with 'scuttle' being the only option for now, but open for future expansion |
@naugtur why @weizman In general I agree with the point raised by @naugtur to not go for 2. If I understand it right, I'm thinking of this as if/how recursion should be done.
if we want to be even more general and not fully close the door on
or even
Going further: Inverting it (configuring options - in this case only scuttling - per global). domain-driven rather than feature-driven configuration:
Some variation of any of these seems sensible to me. It's possible that 3.3-3.4 are "overkill" and solving for unneeded granularity (opening for treating different globals differently) |
1ca62b0
to
74c6726
Compare
packages/node/test/util.js
Outdated
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.
once #471 is merged, the diff in this file can be fixed back to make more sense
f9cccfe
to
c7f0448
Compare
@@ -41,16 +41,16 @@ function generateKernel (opts = {}) { | |||
if (opts.hasOwnProperty('scuttleGlobalThis')) { | |||
// scuttleGlobalThis config placeholder should be set only if ordered so explicitly. | |||
// if not, should be left as is to be replaced by a later processor (e.g. LavaPack). | |||
const {scuttleGlobalThis, scuttleGlobalThisExceptions} = opts |
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.
The removal of opts.scuttleGlobalThisExceptions
seems to be the only breaking part in this changeset - if it would fall back to the old field in absence of the new one, we should be able to make this non-breaking?
Looks great otherwise!
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.
you mean on core
or in all packages affected in this PR?
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.
All, given that the latest published release of each package exposes the option in the public API.
(In principle of course we can still consider each indepently if there would be particularities to any individual package)
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.
Aren't those going to be breaking changes anyway? considering the scuttleGlobalThis
option has changed
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.
The semantics don't seem to have changed? What I mean is that it would still recognize the old config, making that non-breaking (to be actually broken in a future major). Something like:
if (opts.scuttleGlobalThisExceptions) {
// log deprecation warning
}
const scuttleGlobalThis = opts.scuttleGlobalThis
const scuttleGlobalThisExceptions = scuttleGlobalThis?.exceptions || opts.scuttleGlobalThisExceptions || []
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.
We can avoid a breaking change here, yes. It's a little ugly in code. It'd be best to not have to do that and not have to bump major. That's what marking a feature as experimental initially is great - we can make breaking changes to it and get away with it.
This feature was never documented. That means, if we document it as experimental, we could consider breaking it knowing that there was no usage beyond what we control in MetaMask. Is this a good idea? Remains to be decided.
In general, we need to set some rules. I suggest:
- Features or changes cannot be merged without complete documentation.
- A new feature, distinct from other features, should be marked as experimental initially unless a good reason not to do that is provided.
- Experimental feature must be listed as experimental in documentation but can remain undocumented in detail.
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.
In general +1 @naugtur but it might be helpful to put the emphasis on "new API or behavior" rather than "new feature" since the former is less open to interpretation (though I'm sure it's arguable that one follows the other)
cf7aa96
to
1a57183
Compare
1a57183
to
0bc4b3e
Compare
@@ -1,10 +1,11 @@ | |||
<!DOCTYPE HTML> | |||
<html lang="en"> | |||
<head> | |||
<script src="https://cdn.jsdelivr.net/npm/@lavamoat/snow/snow.js"></script> |
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.
Can we include (vendor) snow.js
inside this directory (or at appropriate place in the tree) to avoid loading from CDN here?
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.
Including it will mean replacing it every time Snow updates. Or, bake it into the HTML, but that will introduce a step in the build process of the example.
We can also just demonstrate the example without Snow (after all - it is optional): 0f7a43d
packages/core/src/generateKernel.js
Outdated
const scuttleGlobalThis = opts.scuttleGlobalThis | ||
if (opts.scuttleGlobalThisExceptions) { | ||
console.warn('Lavamoat - "scuttleGlobalThisExceptions" is deprecated. Use "scuttleGlobalThis.exceptions" instead.') | ||
} | ||
const exceptions = scuttleGlobalThis?.exceptions || opts.scuttleGlobalThisExceptions | ||
scuttleGlobalThis.exceptions = exceptions |
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.
const scuttleGlobalThis = opts.scuttleGlobalThis | |
if (opts.scuttleGlobalThisExceptions) { | |
console.warn('Lavamoat - "scuttleGlobalThisExceptions" is deprecated. Use "scuttleGlobalThis.exceptions" instead.') | |
} | |
const exceptions = scuttleGlobalThis?.exceptions || opts.scuttleGlobalThisExceptions | |
scuttleGlobalThis.exceptions = exceptions | |
if (opts.scuttleGlobalThisExceptions) { | |
console.warn('Lavamoat - "scuttleGlobalThisExceptions" is deprecated. Use "scuttleGlobalThis.exceptions" instead.') | |
} | |
const scuttleGlobalThis = { | |
...opts.scuttleGlobalThis, | |
exceptions: opts.scuttleGlobalThis?.exceptions || opts.scuttleGlobalThisExceptions, | |
} | |
const exceptions = scuttleGlobalThis.exceptions |
This way we leave the opts
object unmodified.
I also personally find it more readable to assign all the options fields ni one statement like this, but that might be subjective.
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.
} | ||
scuttleGlobalThis.exceptions = scuttleGlobalThis?.exceptions || scuttleGlobalThisExceptions |
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.
We should avoid modifying the input arguments (in this case scuttleGlobalThis
.
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.
packages/browserify/test/util.js
Outdated
for (let i = 0; i < scenario.opts.scuttleGlobalThisExceptions.length; i++) { | ||
scenario.opts.scuttleGlobalThisExceptions[i] = String(scenario.opts.scuttleGlobalThisExceptions[i]) | ||
for (let i = 0; i < exceptions.length; i++) { | ||
exceptions[i] = String(exceptions[i]) |
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.
This is modifying the input (it's desirable to be pure wrt input arguments)
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.
for (let i = 0; i < scuttleGlobalThisExceptions.length; i++) { | ||
scuttleGlobalThisExceptions[i] = String(scuttleGlobalThisExceptions[i]) | ||
for (let i = 0; i < exceptions.length; i++) { | ||
exceptions[i] = String(exceptions[i]) |
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.
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.
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.
Follow-up: #597
I don't understand too much, is this the solution? Where should the following passage be executed?
|
you got it right @weilun0510 - it should be executed at any point before the execution of LavaMoat, so when LavaMoat loads it'll pick up this scuttler option from the global object. |
We took a bit too long on this one. Can we ship this in the next release cycle and finish #597 for the release after that? Are there any parts of #597 that are stable and finished that could be moved into this one? We still have time until the current release cycle is done. It'd be best to release node 18 support fully before this. |
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.
After in-person conversations I see consensus that this should have been merged a month ago and while we're good at coming up with what to improve, we need to get better at deciding when.
- integrate with snow (LavaMoat#462)
Motivation
We'd like to be able to optionally hook into the scuttling process at runtime.
It will be useful to us because it'll allow us to use Snow to perform scuttling on all new realms instead of just the main one.
Implementation
before:
after:
The new option
scuttler
will be a string pointing to a reference on the global object, which should refer to a function:When
scuttler
is left untouched, LavaMoat runtime won't try using an external scuttler.