sandboxbox 1.1.0 → 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 +55 -165
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,76 +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; // Indicate build failed
|
285
|
-
}
|
286
|
-
|
287
|
-
// Configure and build
|
288
|
-
console.log('⚙️ Configuring build...');
|
289
|
-
try {
|
290
|
-
execSync(`
|
291
|
-
cd "${sourceDir}" &&
|
292
|
-
timeout 60 ./configure --prefix="${tmpDir}/install" --disable-man
|
293
|
-
`, { stdio: 'inherit' });
|
294
|
-
} catch (e) {
|
295
|
-
console.error('❌ Configure step failed or timed out');
|
296
255
|
return false;
|
297
256
|
}
|
298
257
|
|
299
|
-
|
258
|
+
// Simple compilation without autotools
|
259
|
+
console.log('🏗️ Compiling bubblewrap directly...');
|
300
260
|
try {
|
301
261
|
execSync(`
|
302
262
|
cd "${sourceDir}" &&
|
303
|
-
timeout
|
263
|
+
timeout 120 gcc -std=c99 -O2 -DHAVE_CONFIG_H=1 -o bwrap bubblewrap.c || \
|
264
|
+
gcc -std=c99 -O2 -o bwrap bubblewrap.c
|
304
265
|
`, { stdio: 'inherit' });
|
305
266
|
} catch (e) {
|
306
|
-
console.error('❌
|
307
|
-
return false;
|
308
|
-
}
|
309
|
-
|
310
|
-
console.log('📦 Installing...');
|
311
|
-
try {
|
312
|
-
execSync(`
|
313
|
-
cd "${sourceDir}" &&
|
314
|
-
timeout 60 make install
|
315
|
-
`, { stdio: 'inherit' });
|
316
|
-
} catch (e) {
|
317
|
-
console.error('❌ Install step failed or timed out');
|
267
|
+
console.error('❌ Direct compilation failed');
|
318
268
|
return false;
|
319
269
|
}
|
320
270
|
|
321
271
|
// Copy binary to final location
|
322
|
-
const builtBinary = path.join(
|
272
|
+
const builtBinary = path.join(sourceDir, 'bwrap');
|
323
273
|
if (fs.existsSync(builtBinary)) {
|
324
274
|
fs.copyFileSync(builtBinary, binaryPath);
|
325
275
|
fs.chmodSync(binaryPath, 0o755);
|
@@ -328,15 +278,15 @@ async function buildFromSource(binaryPath) {
|
|
328
278
|
// Test the binary
|
329
279
|
const version = execSync(`"${binaryPath}" --version`, { encoding: 'utf8' });
|
330
280
|
console.log(`🎯 Built: ${version.trim()}`);
|
331
|
-
return true;
|
281
|
+
return true;
|
332
282
|
} else {
|
333
283
|
console.log('❌ Built binary not found');
|
334
|
-
return false;
|
284
|
+
return false;
|
335
285
|
}
|
336
286
|
|
337
287
|
} catch (error) {
|
338
288
|
console.log(`❌ Build from source failed: ${error.message}`);
|
339
|
-
return false;
|
289
|
+
return false;
|
340
290
|
} finally {
|
341
291
|
// Cleanup
|
342
292
|
fs.rmSync(tmpDir, { recursive: true, force: true });
|
@@ -350,64 +300,4 @@ downloadAndBuild().catch(error => {
|
|
350
300
|
console.error('🚫 SandboxBox cannot function without bubblewrap.');
|
351
301
|
console.error(' Please install build tools and try again.');
|
352
302
|
process.exit(1);
|
353
|
-
});
|
354
|
-
|
355
|
-
function createMinimalBubblewrap(binaryPath) {
|
356
|
-
console.log('🔧 Creating minimal bubblewrap fallback...');
|
357
|
-
|
358
|
-
const minimalBwrap = `#!/bin/bash
|
359
|
-
# Minimal bubblewrap fallback for SandboxBox
|
360
|
-
# This provides basic namespace isolation functionality
|
361
|
-
|
362
|
-
# Handle --version flag for compatibility
|
363
|
-
if [[ "$1" == "--version" ]]; then
|
364
|
-
echo "bubblewrap 0.11.0 (minimal fallback for SandboxBox)"
|
365
|
-
exit 0
|
366
|
-
fi
|
367
|
-
|
368
|
-
# Handle --help flag
|
369
|
-
if [[ "$1" == "--help" ]] || [[ "$1" == "-h" ]]; then
|
370
|
-
echo "bubblewrap - minimal fallback version"
|
371
|
-
echo ""
|
372
|
-
echo "⚠️ This is a minimal fallback for SandboxBox"
|
373
|
-
echo "💡 For full functionality, install bubblewrap:"
|
374
|
-
echo " sudo apt-get install bubblewrap"
|
375
|
-
echo ""
|
376
|
-
echo "Usage: bwrap [options] -- command [args]"
|
377
|
-
exit 0
|
378
|
-
fi
|
379
|
-
|
380
|
-
echo "⚠️ Using minimal bubblewrap fallback"
|
381
|
-
echo "💡 For full functionality, install bubblewrap:"
|
382
|
-
echo " sudo apt-get install bubblewrap"
|
383
|
-
echo ""
|
384
|
-
|
385
|
-
# Filter out bubblewrap-specific options that unshare doesn't support
|
386
|
-
ARGS=()
|
387
|
-
for arg in "$@"; do
|
388
|
-
case "$arg" in
|
389
|
-
--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)
|
390
|
-
# Skip bubblewrap-specific options
|
391
|
-
;;
|
392
|
-
*)
|
393
|
-
ARGS+=("$arg")
|
394
|
-
;;
|
395
|
-
esac
|
396
|
-
done
|
397
|
-
|
398
|
-
# Basic namespace isolation using unshare
|
399
|
-
exec unshare \\
|
400
|
-
--pid \\
|
401
|
-
--mount \\
|
402
|
-
--uts \\
|
403
|
-
--ipc \\
|
404
|
-
--net \\
|
405
|
-
--fork \\
|
406
|
-
--mount-proc \\
|
407
|
-
"\${ARGS[@]}"
|
408
|
-
`;
|
409
|
-
|
410
|
-
fs.writeFileSync(binaryPath, minimalBwrap);
|
411
|
-
fs.chmodSync(binaryPath, 0o755);
|
412
|
-
console.log('✅ Created minimal bubblewrap fallback');
|
413
|
-
}
|
303
|
+
});
|