mirror of
https://github.com/safedep/pmg.git
synced 2026-08-03 07:24:09 +02:00
fix(sandbox): bind parent dir for globstar allow_write on bwrap (#321)
* fix(sandbox): bind parent dir for globstar allow_write on bwrap
Fine-grained per-path mounts under read-only project binds broke pip
install into in-project .venv directories. Always mount the parent tree
for ** write rules instead.
Fixes #315
* test(sandbox): tighten globstar bind assertions and ensure ~/.npm exists for e2e
Strengthen TestBubblewrapAllowWriteGlobstarBindsParentOnly to verify the
parent dir is writably bound and the child path is read-only bound, not
just substring presence. Pre-create ~/.npm in the e2e harness so
bubblewrap --bind-try does not skip the npm cache dir on fresh runners.
* switch pnpm to /tmp in sandbox e2e
* test(sandbox): update glob ** test for parent-bind semantics
Globstar allow_write now binds the parent dir only (e2e740d), so the
test should assert the parent is writably bound and child subdirs are
not individually bound, instead of substring-matching subdir names.
* fix(sandbox): bind correct base dir for in-pattern globstar allow_write
Globstar allow_write previously used extractGlobParentDir, which walks past
the first ** and yields the wrong root for patterns like /a/b/**/d/**/e.
Introduce extractGlobstarWriteBaseDir, which takes the prefix before the
first /**, and use it in processWriteRule. Also dedup the coarse-fallback
parent-bind loop to mirror the read-rule fallback.
This commit is contained in:
+25
-3
@@ -47,15 +47,37 @@ function cleanup(dir) {
|
||||
}
|
||||
}
|
||||
|
||||
// npm-restrictive allow_write includes /tmp/**. Use cache/store paths under /tmp so
|
||||
// bubblewrap can bind /tmp read-write without pre-creating ~/.npm or ~/.cache/pnpm.
|
||||
function pmEnv(pm) {
|
||||
const base = path.join(os.tmpdir(), 'pmg-e2e');
|
||||
fs.mkdirSync(base, { recursive: true });
|
||||
|
||||
const env = { ...process.env };
|
||||
env.npm_config_cache = path.join(base, 'npm-cache');
|
||||
fs.mkdirSync(env.npm_config_cache, { recursive: true });
|
||||
|
||||
if (pm === 'pnpm') {
|
||||
env.PNPM_HOME = path.join(base, 'pnpm-home');
|
||||
env.npm_config_store_dir = path.join(base, 'pnpm-store');
|
||||
fs.mkdirSync(env.PNPM_HOME, { recursive: true });
|
||||
fs.mkdirSync(env.npm_config_store_dir, { recursive: true });
|
||||
env.PATH = `${env.PNPM_HOME}${path.delimiter}${env.PATH}`;
|
||||
}
|
||||
|
||||
return env;
|
||||
}
|
||||
|
||||
function testPackageManager(pm) {
|
||||
const testDir = createTempDir(`pmg-e2e-${pm}-`);
|
||||
const env = pmEnv(pm);
|
||||
console.log(`\n Test directory: ${testDir}`);
|
||||
|
||||
try {
|
||||
// Initialize project
|
||||
test(`${pm}: Initialize project`, () => {
|
||||
const initCmd = pm === 'npm' ? 'npm init -y' : 'pnpm init';
|
||||
const result = exec(initCmd, { cwd: testDir });
|
||||
const result = exec(initCmd, { cwd: testDir, env });
|
||||
if (!result.success) {
|
||||
console.log(` ❌ FAIL: ${result.error}`);
|
||||
return false;
|
||||
@@ -77,7 +99,7 @@ function testPackageManager(pm) {
|
||||
const addCmd = pm === 'npm'
|
||||
? `npm install ${depsList}`
|
||||
: `pnpm add ${depsList}`;
|
||||
const result = exec(addCmd, { cwd: testDir });
|
||||
const result = exec(addCmd, { cwd: testDir, env });
|
||||
if (!result.success) {
|
||||
console.log(` ❌ FAIL: ${result.error}`);
|
||||
return false;
|
||||
@@ -122,7 +144,7 @@ function testPackageManager(pm) {
|
||||
|
||||
// Reinstall
|
||||
const installCmd = pm === 'npm' ? 'npm install' : 'pnpm install';
|
||||
const result = exec(installCmd, { cwd: testDir });
|
||||
const result = exec(installCmd, { cwd: testDir, env });
|
||||
if (!result.success) {
|
||||
console.log(` ❌ FAIL: ${result.error}`);
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user