sandboxbox 1.0.9 → 1.2.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/package.json +1 -1
- package/scripts/build.js +63 -158
package/package.json
CHANGED
package/scripts/build.js
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
/**
|
4
4
|
* SQLite-style build script for SandboxBox
|
5
|
-
* Downloads
|
5
|
+
* Downloads bubblewrap binary during npm install, with fallback to building from source
|
6
6
|
*/
|
7
7
|
|
8
8
|
import fs from 'fs';
|
@@ -46,21 +46,29 @@ async function downloadAndBuild() {
|
|
46
46
|
}
|
47
47
|
}
|
48
48
|
|
49
|
-
//
|
49
|
+
// SQLite-style approach: try binary downloads first, then build from source
|
50
|
+
if (await downloadPreBuiltBinary(binaryPath)) {
|
51
|
+
return; // Binary download succeeded
|
52
|
+
}
|
53
|
+
|
50
54
|
if (await buildFromSource(binaryPath)) {
|
51
|
-
return; // Build succeeded
|
52
|
-
} else {
|
53
|
-
// Build failed - exit with error to make the problem visible
|
54
|
-
console.error('❌ Bubblewrap build failed!');
|
55
|
-
console.error('');
|
56
|
-
console.error('💡 Install build tools:');
|
57
|
-
console.error(' Ubuntu/Debian: sudo apt-get install build-essential autoconf automake libtool xz-utils');
|
58
|
-
console.error(' CentOS/RHEL: sudo yum groupinstall "Development Tools" && sudo yum install xz');
|
59
|
-
console.error('');
|
60
|
-
console.error('🚫 SandboxBox cannot function without bubblewrap.');
|
61
|
-
console.error(' Please install build tools and try again.');
|
62
|
-
process.exit(1);
|
55
|
+
return; // Build from source succeeded
|
63
56
|
}
|
57
|
+
|
58
|
+
// Everything failed - show clear error
|
59
|
+
console.error('❌ All bubblewrap installation methods failed!');
|
60
|
+
console.error('');
|
61
|
+
console.error('💡 Option 1 - Install system bubblewrap (recommended):');
|
62
|
+
console.error(' sudo apt-get install bubblewrap # Ubuntu/Debian');
|
63
|
+
console.error(' sudo apk add bubblewrap # Alpine');
|
64
|
+
console.error(' sudo yum install bubblewrap # CentOS/RHEL');
|
65
|
+
console.error('');
|
66
|
+
console.error('💡 Option 2 - Install build tools for compilation:');
|
67
|
+
console.error(' sudo apt-get install build-essential git autoconf automake libtool xz-utils');
|
68
|
+
console.error(' sudo yum groupinstall "Development Tools" && sudo yum install git xz');
|
69
|
+
console.error('');
|
70
|
+
console.error('🚫 SandboxBox cannot function without bubblewrap.');
|
71
|
+
process.exit(1);
|
64
72
|
}
|
65
73
|
|
66
74
|
async function downloadPreBuiltBinary(binaryPath) {
|
@@ -70,7 +78,7 @@ async function downloadPreBuiltBinary(binaryPath) {
|
|
70
78
|
const possibleUrls = [
|
71
79
|
// Alpine packages (HTTPS) - use the actual available version
|
72
80
|
`https://dl-cdn.alpinelinux.org/alpine/v3.20/main/${arch}/bubblewrap-0.10.0-r0.apk`,
|
73
|
-
// Try
|
81
|
+
// Try GitHub releases with different architectures
|
74
82
|
`https://github.com/containers/bubblewrap/releases/download/v${BWRAP_VERSION}/bubblewrap-${BWRAP_VERSION}-${arch}.tar.xz`,
|
75
83
|
`https://github.com/containers/bubblewrap/releases/download/v${BWRAP_VERSION}/bubblewrap-${BWRAP_VERSION}.tar.gz`,
|
76
84
|
];
|
@@ -200,46 +208,27 @@ async function buildFromSource(binaryPath) {
|
|
200
208
|
const tmpDir = fs.mkdtempSync(path.join(process.env.TMPDIR || '/tmp', 'bwrap-build-'));
|
201
209
|
|
202
210
|
try {
|
203
|
-
//
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
function download(url) {
|
213
|
-
https.get(url, (response) => {
|
214
|
-
// Handle redirects
|
215
|
-
if (response.statusCode >= 300 && response.statusCode < 400 && response.headers.location) {
|
216
|
-
console.log(`🔄 Following redirect to: ${response.headers.location}`);
|
217
|
-
download(response.headers.location);
|
218
|
-
return;
|
219
|
-
}
|
220
|
-
|
221
|
-
if (response.statusCode !== 200) {
|
222
|
-
reject(new Error(`HTTP ${response.statusCode}: ${response.statusMessage}`));
|
223
|
-
return;
|
224
|
-
}
|
225
|
-
|
226
|
-
response.pipe(file);
|
227
|
-
|
228
|
-
file.on('finish', () => {
|
229
|
-
file.close();
|
230
|
-
resolve();
|
231
|
-
});
|
232
|
-
}).on('error', reject);
|
211
|
+
// Try to use system bubblewrap as fallback if available
|
212
|
+
try {
|
213
|
+
const systemBwrap = execSync('which bwrap', { encoding: 'utf8' }).trim();
|
214
|
+
if (systemBwrap && fs.existsSync(systemBwrap)) {
|
215
|
+
fs.copyFileSync(systemBwrap, binaryPath);
|
216
|
+
fs.chmodSync(binaryPath, 0o755);
|
217
|
+
console.log('✅ Using system bubblewrap:', systemBwrap);
|
218
|
+
return true;
|
233
219
|
}
|
220
|
+
} catch (e) {
|
221
|
+
// System bwrap not found, continue with build
|
222
|
+
}
|
234
223
|
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
// Extract source
|
239
|
-
console.log('📦 Extracting source...');
|
240
|
-
execSync(`tar -xf "${tarballPath}" -C "${tmpDir}"`, { stdio: 'inherit' });
|
224
|
+
// Clone git repository for build files
|
225
|
+
console.log('📥 Downloading bubblewrap source from git...');
|
226
|
+
const sourceDir = path.join(tmpDir, 'bubblewrap');
|
241
227
|
|
242
|
-
|
228
|
+
execSync(`
|
229
|
+
cd "${tmpDir}" &&
|
230
|
+
timeout 120 git clone --depth 1 --branch v${BWRAP_VERSION} https://github.com/containers/bubblewrap.git
|
231
|
+
`, { stdio: 'inherit' });
|
243
232
|
|
244
233
|
// Check for required build tools
|
245
234
|
const missingTools = [];
|
@@ -250,61 +239,37 @@ async function buildFromSource(binaryPath) {
|
|
250
239
|
}
|
251
240
|
|
252
241
|
try {
|
253
|
-
execSync('which
|
242
|
+
execSync('which git', { stdio: 'ignore' });
|
254
243
|
} catch (e) {
|
255
|
-
missingTools.push('
|
256
|
-
}
|
257
|
-
|
258
|
-
try {
|
259
|
-
execSync('which autoconf', { stdio: 'ignore' });
|
260
|
-
} catch (e) {
|
261
|
-
missingTools.push('autoconf');
|
262
|
-
}
|
263
|
-
|
264
|
-
try {
|
265
|
-
execSync('which automake', { stdio: 'ignore' });
|
266
|
-
} catch (e) {
|
267
|
-
missingTools.push('automake');
|
268
|
-
}
|
269
|
-
|
270
|
-
try {
|
271
|
-
execSync('which libtool', { stdio: 'ignore' });
|
272
|
-
} catch (e) {
|
273
|
-
missingTools.push('libtool');
|
244
|
+
missingTools.push('git');
|
274
245
|
}
|
275
246
|
|
276
247
|
if (missingTools.length > 0) {
|
277
248
|
console.error(`❌ Missing build tools: ${missingTools.join(', ')}`);
|
278
249
|
console.error('');
|
279
250
|
console.error('💡 Install build tools:');
|
280
|
-
console.error(' Ubuntu/Debian: sudo apt-get install build-essential
|
281
|
-
console.error(' CentOS/RHEL: sudo yum groupinstall "Development Tools" && sudo yum install
|
251
|
+
console.error(' Ubuntu/Debian: sudo apt-get install build-essential git');
|
252
|
+
console.error(' CentOS/RHEL: sudo yum groupinstall "Development Tools" && sudo yum install git');
|
282
253
|
console.error('');
|
283
254
|
console.error('🚫 SandboxBox requires these build tools to compile bubblewrap.');
|
284
|
-
return false;
|
255
|
+
return false;
|
285
256
|
}
|
286
257
|
|
287
|
-
//
|
288
|
-
console.log('
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
console.log('📦 Installing...');
|
301
|
-
execSync(`
|
302
|
-
cd "${sourceDir}" &&
|
303
|
-
make install
|
304
|
-
`, { stdio: 'inherit' });
|
258
|
+
// Simple compilation without autotools
|
259
|
+
console.log('🏗️ Compiling bubblewrap directly...');
|
260
|
+
try {
|
261
|
+
execSync(`
|
262
|
+
cd "${sourceDir}" &&
|
263
|
+
timeout 120 gcc -std=c99 -O2 -DHAVE_CONFIG_H=1 -o bwrap bubblewrap.c || \
|
264
|
+
gcc -std=c99 -O2 -o bwrap bubblewrap.c
|
265
|
+
`, { stdio: 'inherit' });
|
266
|
+
} catch (e) {
|
267
|
+
console.error('❌ Direct compilation failed');
|
268
|
+
return false;
|
269
|
+
}
|
305
270
|
|
306
271
|
// Copy binary to final location
|
307
|
-
const builtBinary = path.join(
|
272
|
+
const builtBinary = path.join(sourceDir, 'bwrap');
|
308
273
|
if (fs.existsSync(builtBinary)) {
|
309
274
|
fs.copyFileSync(builtBinary, binaryPath);
|
310
275
|
fs.chmodSync(binaryPath, 0o755);
|
@@ -313,15 +278,15 @@ async function buildFromSource(binaryPath) {
|
|
313
278
|
// Test the binary
|
314
279
|
const version = execSync(`"${binaryPath}" --version`, { encoding: 'utf8' });
|
315
280
|
console.log(`🎯 Built: ${version.trim()}`);
|
316
|
-
return true;
|
281
|
+
return true;
|
317
282
|
} else {
|
318
283
|
console.log('❌ Built binary not found');
|
319
|
-
return false;
|
284
|
+
return false;
|
320
285
|
}
|
321
286
|
|
322
287
|
} catch (error) {
|
323
288
|
console.log(`❌ Build from source failed: ${error.message}`);
|
324
|
-
return false;
|
289
|
+
return false;
|
325
290
|
} finally {
|
326
291
|
// Cleanup
|
327
292
|
fs.rmSync(tmpDir, { recursive: true, force: true });
|
@@ -335,64 +300,4 @@ downloadAndBuild().catch(error => {
|
|
335
300
|
console.error('🚫 SandboxBox cannot function without bubblewrap.');
|
336
301
|
console.error(' Please install build tools and try again.');
|
337
302
|
process.exit(1);
|
338
|
-
});
|
339
|
-
|
340
|
-
function createMinimalBubblewrap(binaryPath) {
|
341
|
-
console.log('🔧 Creating minimal bubblewrap fallback...');
|
342
|
-
|
343
|
-
const minimalBwrap = `#!/bin/bash
|
344
|
-
# Minimal bubblewrap fallback for SandboxBox
|
345
|
-
# This provides basic namespace isolation functionality
|
346
|
-
|
347
|
-
# Handle --version flag for compatibility
|
348
|
-
if [[ "$1" == "--version" ]]; then
|
349
|
-
echo "bubblewrap 0.11.0 (minimal fallback for SandboxBox)"
|
350
|
-
exit 0
|
351
|
-
fi
|
352
|
-
|
353
|
-
# Handle --help flag
|
354
|
-
if [[ "$1" == "--help" ]] || [[ "$1" == "-h" ]]; then
|
355
|
-
echo "bubblewrap - minimal fallback version"
|
356
|
-
echo ""
|
357
|
-
echo "⚠️ This is a minimal fallback for SandboxBox"
|
358
|
-
echo "💡 For full functionality, install bubblewrap:"
|
359
|
-
echo " sudo apt-get install bubblewrap"
|
360
|
-
echo ""
|
361
|
-
echo "Usage: bwrap [options] -- command [args]"
|
362
|
-
exit 0
|
363
|
-
fi
|
364
|
-
|
365
|
-
echo "⚠️ Using minimal bubblewrap fallback"
|
366
|
-
echo "💡 For full functionality, install bubblewrap:"
|
367
|
-
echo " sudo apt-get install bubblewrap"
|
368
|
-
echo ""
|
369
|
-
|
370
|
-
# Filter out bubblewrap-specific options that unshare doesn't support
|
371
|
-
ARGS=()
|
372
|
-
for arg in "$@"; do
|
373
|
-
case "$arg" in
|
374
|
-
--ro-bind|--bind|--dev-bind|--proc|--tmpfs|--symlink|--dir|--file|--setenv|--die-with-parent|--new-session|--share-net|--unshare-net|--unshare-pid|--unshare-ipc|--unshare-uts|--unshare-cgroup|--unshare-user)
|
375
|
-
# Skip bubblewrap-specific options
|
376
|
-
;;
|
377
|
-
*)
|
378
|
-
ARGS+=("$arg")
|
379
|
-
;;
|
380
|
-
esac
|
381
|
-
done
|
382
|
-
|
383
|
-
# Basic namespace isolation using unshare
|
384
|
-
exec unshare \\
|
385
|
-
--pid \\
|
386
|
-
--mount \\
|
387
|
-
--uts \\
|
388
|
-
--ipc \\
|
389
|
-
--net \\
|
390
|
-
--fork \\
|
391
|
-
--mount-proc \\
|
392
|
-
"\${ARGS[@]}"
|
393
|
-
`;
|
394
|
-
|
395
|
-
fs.writeFileSync(binaryPath, minimalBwrap);
|
396
|
-
fs.chmodSync(binaryPath, 0o755);
|
397
|
-
console.log('✅ Created minimal bubblewrap fallback');
|
398
|
-
}
|
303
|
+
});
|