- Complete Deno-based architecture following nupst/spark patterns - SQLite database with full schema - Docker container management - Service orchestration (Docker + Nginx + DNS + SSL) - Registry authentication - Nginx reverse proxy configuration - Cloudflare DNS integration - Let's Encrypt SSL automation - Background daemon with metrics collection - HTTP API server - Comprehensive CLI - Cross-platform compilation setup - NPM distribution wrapper - Shell installer script Core features: - Deploy containers with single command - Automatic domain configuration - Automatic SSL certificates - Multi-registry support - Metrics and logging - Systemd integration Ready for Angular UI implementation and testing.
106 lines
3.0 KiB
JavaScript
106 lines
3.0 KiB
JavaScript
#!/usr/bin/env node
|
|
|
|
/**
|
|
* Postinstall script to download Onebox binary
|
|
*/
|
|
|
|
import { platform, arch } from 'os';
|
|
import { join, dirname } from 'path';
|
|
import { fileURLToPath } from 'url';
|
|
import { createWriteStream, mkdirSync, chmodSync, existsSync } from 'fs';
|
|
import { get } from 'https';
|
|
|
|
const __filename = fileURLToPath(import.meta.url);
|
|
const __dirname = dirname(__filename);
|
|
|
|
// Get version from package.json
|
|
import { readFileSync } from 'fs';
|
|
const packageJson = JSON.parse(readFileSync(join(__dirname, '..', 'package.json'), 'utf-8'));
|
|
const VERSION = packageJson.version;
|
|
|
|
// Detect platform
|
|
const platformMap = {
|
|
'linux': 'linux',
|
|
'darwin': 'macos',
|
|
'win32': 'windows',
|
|
};
|
|
|
|
const archMap = {
|
|
'x64': 'x64',
|
|
'arm64': 'arm64',
|
|
};
|
|
|
|
const currentPlatform = platformMap[platform()];
|
|
const currentArch = archMap[arch()];
|
|
|
|
if (!currentPlatform || !currentArch) {
|
|
console.error(`Unsupported platform: ${platform()} ${arch()}`);
|
|
process.exit(1);
|
|
}
|
|
|
|
const binaryName = `onebox-${currentPlatform}-${currentArch}${currentPlatform === 'windows' ? '.exe' : ''}`;
|
|
const binaryPath = join(__dirname, '..', 'dist', 'binaries', binaryName);
|
|
|
|
// Create directory
|
|
mkdirSync(join(__dirname, '..', 'dist', 'binaries'), { recursive: true });
|
|
|
|
// Check if binary already exists
|
|
if (existsSync(binaryPath)) {
|
|
console.log('Binary already exists, skipping download');
|
|
process.exit(0);
|
|
}
|
|
|
|
// Download URLs
|
|
const releaseUrl = `https://code.foss.global/serve.zone/onebox/releases/download/v${VERSION}/${binaryName}`;
|
|
const fallbackUrl = `https://code.foss.global/serve.zone/onebox/raw/branch/main/dist/binaries/${binaryName}`;
|
|
|
|
console.log(`Downloading Onebox v${VERSION} for ${currentPlatform}-${currentArch}...`);
|
|
|
|
function download(url, fallback = false) {
|
|
return new Promise((resolve, reject) => {
|
|
get(url, (response) => {
|
|
if (response.statusCode === 302 || response.statusCode === 301) {
|
|
// Follow redirect
|
|
download(response.headers.location, fallback).then(resolve).catch(reject);
|
|
return;
|
|
}
|
|
|
|
if (response.statusCode !== 200) {
|
|
if (!fallback) {
|
|
console.warn(`Release not found, trying fallback URL...`);
|
|
download(fallbackUrl, true).then(resolve).catch(reject);
|
|
} else {
|
|
reject(new Error(`Failed to download: HTTP ${response.statusCode}`));
|
|
}
|
|
return;
|
|
}
|
|
|
|
const fileStream = createWriteStream(binaryPath);
|
|
|
|
response.pipe(fileStream);
|
|
|
|
fileStream.on('finish', () => {
|
|
fileStream.close();
|
|
|
|
// Make executable (Unix only)
|
|
if (currentPlatform !== 'windows') {
|
|
chmodSync(binaryPath, 0o755);
|
|
}
|
|
|
|
console.log('✓ Binary downloaded successfully');
|
|
resolve();
|
|
});
|
|
|
|
fileStream.on('error', reject);
|
|
}).on('error', reject);
|
|
});
|
|
}
|
|
|
|
download(releaseUrl).catch((error) => {
|
|
console.error(`Failed to download binary: ${error.message}`);
|
|
console.error('You can manually download the binary from:');
|
|
console.error(releaseUrl);
|
|
console.error(`And place it at: ${binaryPath}`);
|
|
process.exit(1);
|
|
});
|