signalk-mosquitto
Version:
SignalK plugin for managing Mosquitto MQTT broker with bridge connections and security
472 lines • 20 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.MosquittoInstaller = void 0;
const file_utils_1 = require("../utils/file-utils");
const os = __importStar(require("os"));
const path = __importStar(require("path"));
class MosquittoInstaller {
constructor(app) {
this.app = app;
this.platform = process.platform;
}
async isInstalled() {
try {
// Check if mosquitto command is available
if (await file_utils_1.FileUtils.isCommandAvailable('mosquitto')) {
return true;
}
// Check common installation paths
const commonPaths = this.getCommonInstallPaths();
for (const binPath of commonPaths) {
if (await file_utils_1.FileUtils.fileExists(binPath)) {
return true;
}
}
return false;
}
catch (error) {
console.log(`Error checking Mosquitto installation: ${error.message}`);
return false;
}
}
async install() {
console.log(`Installing Mosquitto on ${this.platform}...`);
try {
switch (this.platform) {
case 'darwin':
await this.installOnMacOS();
break;
case 'linux':
await this.installOnLinux();
break;
case 'win32':
await this.installOnWindows();
break;
default:
throw new Error(`Unsupported platform: ${this.platform}`);
}
// Verify installation
const installed = await this.isInstalled();
if (!installed) {
throw new Error('Mosquitto installation verification failed');
}
// Setup system service if needed
await this.setupSystemService();
console.log('Mosquitto installation completed successfully');
}
catch (error) {
console.error(`Mosquitto installation failed: ${error.message}`);
throw error;
}
}
async installOnMacOS() {
console.log('Installing Mosquitto on macOS...');
// Check if Homebrew is available
if (await file_utils_1.FileUtils.isCommandAvailable('brew')) {
console.log('Using Homebrew to install Mosquitto');
await file_utils_1.FileUtils.executeCommand('brew', ['update']);
await file_utils_1.FileUtils.executeCommand('brew', ['install', 'mosquitto']);
// Start and enable the service
await file_utils_1.FileUtils.executeCommand('brew', ['services', 'start', 'mosquitto']);
return;
}
// Check if MacPorts is available
if (await file_utils_1.FileUtils.isCommandAvailable('port')) {
console.log('Using MacPorts to install Mosquitto');
await file_utils_1.FileUtils.executeCommand('sudo', ['port', 'install', 'mosquitto']);
return;
}
// Fallback: Download and compile from source
console.log('No package manager found, installing from source');
await this.installFromSource();
}
async installOnLinux() {
console.log('Installing Mosquitto on Linux...');
const distro = await this.getLinuxDistribution();
console.log(`Detected Linux distribution: ${distro}`);
if (distro.includes('ubuntu') || distro.includes('debian')) {
await this.installOnDebian();
}
else if (distro.includes('centos') ||
distro.includes('rhel') ||
distro.includes('rocky') ||
distro.includes('almalinux')) {
await this.installOnRedHat();
}
else if (distro.includes('fedora')) {
await this.installOnFedora();
}
else if (distro.includes('arch') || distro.includes('manjaro')) {
await this.installOnArch();
}
else if (distro.includes('alpine')) {
await this.installOnAlpine();
}
else if (distro.includes('opensuse') || distro.includes('suse')) {
await this.installOnOpenSUSE();
}
else {
console.log('Unknown distribution, attempting generic installation');
await this.attemptGenericLinuxInstall();
}
}
async installOnDebian() {
console.log('Installing on Debian/Ubuntu...');
// Update package list
await file_utils_1.FileUtils.executeCommand('sudo', ['apt-get', 'update']);
// Install Mosquitto and clients
await file_utils_1.FileUtils.executeCommand('sudo', [
'apt-get',
'install',
'-y',
'mosquitto',
'mosquitto-clients',
]);
// Enable and start service
if (await file_utils_1.FileUtils.isCommandAvailable('systemctl')) {
await file_utils_1.FileUtils.executeCommand('sudo', ['systemctl', 'enable', 'mosquitto']);
await file_utils_1.FileUtils.executeCommand('sudo', ['systemctl', 'start', 'mosquitto']);
}
}
async installOnRedHat() {
console.log('Installing on RHEL/CentOS...');
// Check if we need to enable EPEL repository
try {
await file_utils_1.FileUtils.executeCommand('sudo', ['yum', 'install', '-y', 'epel-release']);
}
catch {
console.log('EPEL repository already available or not needed');
}
// Install Mosquitto
if (await file_utils_1.FileUtils.isCommandAvailable('dnf')) {
await file_utils_1.FileUtils.executeCommand('sudo', [
'dnf',
'install',
'-y',
'mosquitto',
'mosquitto-clients',
]);
}
else {
await file_utils_1.FileUtils.executeCommand('sudo', [
'yum',
'install',
'-y',
'mosquitto',
'mosquitto-clients',
]);
}
// Enable and start service
if (await file_utils_1.FileUtils.isCommandAvailable('systemctl')) {
await file_utils_1.FileUtils.executeCommand('sudo', ['systemctl', 'enable', 'mosquitto']);
await file_utils_1.FileUtils.executeCommand('sudo', ['systemctl', 'start', 'mosquitto']);
}
}
async installOnFedora() {
console.log('Installing on Fedora...');
await file_utils_1.FileUtils.executeCommand('sudo', [
'dnf',
'install',
'-y',
'mosquitto',
'mosquitto-clients',
]);
// Enable and start service
if (await file_utils_1.FileUtils.isCommandAvailable('systemctl')) {
await file_utils_1.FileUtils.executeCommand('sudo', ['systemctl', 'enable', 'mosquitto']);
await file_utils_1.FileUtils.executeCommand('sudo', ['systemctl', 'start', 'mosquitto']);
}
}
async installOnArch() {
console.log('Installing on Arch Linux...');
await file_utils_1.FileUtils.executeCommand('sudo', ['pacman', '-S', '--noconfirm', 'mosquitto']);
// Enable and start service
if (await file_utils_1.FileUtils.isCommandAvailable('systemctl')) {
await file_utils_1.FileUtils.executeCommand('sudo', ['systemctl', 'enable', 'mosquitto']);
await file_utils_1.FileUtils.executeCommand('sudo', ['systemctl', 'start', 'mosquitto']);
}
}
async installOnAlpine() {
console.log('Installing on Alpine Linux...');
await file_utils_1.FileUtils.executeCommand('sudo', ['apk', 'update']);
await file_utils_1.FileUtils.executeCommand('sudo', ['apk', 'add', 'mosquitto', 'mosquitto-clients']);
// Enable service using OpenRC
if (await file_utils_1.FileUtils.isCommandAvailable('rc-update')) {
await file_utils_1.FileUtils.executeCommand('sudo', ['rc-update', 'add', 'mosquitto', 'default']);
await file_utils_1.FileUtils.executeCommand('sudo', ['rc-service', 'mosquitto', 'start']);
}
}
async installOnOpenSUSE() {
console.log('Installing on openSUSE...');
await file_utils_1.FileUtils.executeCommand('sudo', ['zypper', 'refresh']);
await file_utils_1.FileUtils.executeCommand('sudo', [
'zypper',
'install',
'-y',
'mosquitto',
'mosquitto-clients',
]);
// Enable and start service
if (await file_utils_1.FileUtils.isCommandAvailable('systemctl')) {
await file_utils_1.FileUtils.executeCommand('sudo', ['systemctl', 'enable', 'mosquitto']);
await file_utils_1.FileUtils.executeCommand('sudo', ['systemctl', 'start', 'mosquitto']);
}
}
async installOnWindows() {
console.log('Installing Mosquitto on Windows...');
// Check if Chocolatey is available
if (await file_utils_1.FileUtils.isCommandAvailable('choco')) {
console.log('Using Chocolatey to install Mosquitto');
await file_utils_1.FileUtils.executeCommand('choco', ['install', 'mosquitto', '-y']);
return;
}
// Check if Scoop is available
if (await file_utils_1.FileUtils.isCommandAvailable('scoop')) {
console.log('Using Scoop to install Mosquitto');
await file_utils_1.FileUtils.executeCommand('scoop', ['install', 'mosquitto']);
return;
}
// Manual installation guidance
throw new Error('Please install Mosquitto manually from https://mosquitto.org/download/ or install Chocolatey/Scoop first');
}
async attemptGenericLinuxInstall() {
console.log('Attempting generic Linux installation...');
// Try different package managers in order of preference
const packageManagers = [
{
cmd: 'apt-get',
args: ['update'],
installArgs: ['install', '-y', 'mosquitto', 'mosquitto-clients'],
},
{ cmd: 'yum', args: [], installArgs: ['install', '-y', 'mosquitto', 'mosquitto-clients'] },
{ cmd: 'dnf', args: [], installArgs: ['install', '-y', 'mosquitto', 'mosquitto-clients'] },
{ cmd: 'pacman', args: [], installArgs: ['-S', '--noconfirm', 'mosquitto'] },
{
cmd: 'zypper',
args: ['refresh'],
installArgs: ['install', '-y', 'mosquitto', 'mosquitto-clients'],
},
{ cmd: 'apk', args: ['update'], installArgs: ['add', 'mosquitto', 'mosquitto-clients'] },
];
for (const pm of packageManagers) {
if (await file_utils_1.FileUtils.isCommandAvailable(pm.cmd)) {
console.log(`Using ${pm.cmd} package manager`);
if (pm.args.length > 0) {
await file_utils_1.FileUtils.executeCommand('sudo', [pm.cmd, ...pm.args]);
}
await file_utils_1.FileUtils.executeCommand('sudo', [pm.cmd, ...pm.installArgs]);
return;
}
}
// If no package manager found, try building from source
console.log('No package manager found, building from source');
await this.installFromSource();
}
async installFromSource() {
console.log('Installing Mosquitto from source...');
const tempDir = path.join(os.tmpdir(), 'mosquitto-build');
await file_utils_1.FileUtils.ensureDir(tempDir);
try {
// Download source
const version = '2.0.18'; // Latest stable version
const tarUrl = `https://mosquitto.org/files/source/mosquitto-${version}.tar.gz`;
// This is a simplified version - in practice you'd need more robust downloading
await file_utils_1.FileUtils.executeCommand('wget', [
'-O',
path.join(tempDir, 'mosquitto.tar.gz'),
tarUrl,
]);
// Extract
await file_utils_1.FileUtils.executeCommand('tar', [
'-xzf',
path.join(tempDir, 'mosquitto.tar.gz'),
'-C',
tempDir,
]);
// Build and install
const sourceDir = path.join(tempDir, `mosquitto-${version}`);
process.chdir(sourceDir);
await file_utils_1.FileUtils.executeCommand('make');
await file_utils_1.FileUtils.executeCommand('sudo', ['make', 'install']);
console.log('Mosquitto built and installed from source');
}
finally {
// Cleanup
try {
await file_utils_1.FileUtils.executeCommand('rm', ['-rf', tempDir]);
}
catch (error) {
console.log(`Failed to clean up temp directory: ${error.message}`);
}
}
}
async setupSystemService() {
// Stop the system mosquitto service to avoid conflicts
// We'll manage our own mosquitto instance
try {
if (await file_utils_1.FileUtils.isCommandAvailable('systemctl')) {
await file_utils_1.FileUtils.executeCommand('sudo', ['systemctl', 'stop', 'mosquitto']);
await file_utils_1.FileUtils.executeCommand('sudo', ['systemctl', 'disable', 'mosquitto']);
console.log('Disabled system Mosquitto service to avoid conflicts');
}
}
catch (error) {
console.log(`Could not disable system service: ${error.message}`);
}
}
getCommonInstallPaths() {
const paths = [];
switch (this.platform) {
case 'darwin':
paths.push('/usr/local/bin/mosquitto', '/opt/homebrew/bin/mosquitto');
break;
case 'linux':
paths.push('/usr/bin/mosquitto', '/usr/local/bin/mosquitto', '/usr/sbin/mosquitto');
break;
case 'win32':
paths.push('C:\\Program Files\\mosquitto\\mosquitto.exe', 'C:\\mosquitto\\mosquitto.exe');
break;
}
return paths;
}
async getLinuxDistribution() {
try {
// Try reading os-release file
if (await file_utils_1.FileUtils.fileExists('/etc/os-release')) {
const content = await file_utils_1.FileUtils.readFile('/etc/os-release');
return content.toLowerCase();
}
// Try lsb_release command
if (await file_utils_1.FileUtils.isCommandAvailable('lsb_release')) {
const { stdout } = await file_utils_1.FileUtils.executeCommand('lsb_release', ['-a']);
return stdout.toLowerCase();
}
// Try reading various release files
const releaseFiles = [
'/etc/redhat-release',
'/etc/debian_version',
'/etc/alpine-release',
'/etc/arch-release',
];
for (const file of releaseFiles) {
if (await file_utils_1.FileUtils.fileExists(file)) {
const content = await file_utils_1.FileUtils.readFile(file);
return content.toLowerCase();
}
}
return 'unknown';
}
catch (error) {
console.log(`Failed to detect Linux distribution: ${error.message}`);
return 'unknown';
}
}
async uninstall() {
console.log('Uninstalling Mosquitto...');
try {
// Stop any running processes first
const pids = await file_utils_1.FileUtils.findProcessByName('mosquitto');
for (const pid of pids) {
await file_utils_1.FileUtils.killProcess(pid);
}
switch (this.platform) {
case 'darwin':
await this.uninstallOnMacOS();
break;
case 'linux':
await this.uninstallOnLinux();
break;
case 'win32':
await this.uninstallOnWindows();
break;
}
console.log('Mosquitto uninstalled successfully');
}
catch (error) {
console.error(`Mosquitto uninstallation failed: ${error.message}`);
throw error;
}
}
async uninstallOnMacOS() {
if (await file_utils_1.FileUtils.isCommandAvailable('brew')) {
await file_utils_1.FileUtils.executeCommand('brew', ['services', 'stop', 'mosquitto']);
await file_utils_1.FileUtils.executeCommand('brew', ['uninstall', 'mosquitto']);
}
}
async uninstallOnLinux() {
const distro = await this.getLinuxDistribution();
if (distro.includes('ubuntu') || distro.includes('debian')) {
await file_utils_1.FileUtils.executeCommand('sudo', [
'apt-get',
'remove',
'-y',
'mosquitto',
'mosquitto-clients',
]);
}
else if (distro.includes('centos') || distro.includes('rhel') || distro.includes('fedora')) {
const cmd = (await file_utils_1.FileUtils.isCommandAvailable('dnf')) ? 'dnf' : 'yum';
await file_utils_1.FileUtils.executeCommand('sudo', [
cmd,
'remove',
'-y',
'mosquitto',
'mosquitto-clients',
]);
}
else if (distro.includes('arch')) {
await file_utils_1.FileUtils.executeCommand('sudo', ['pacman', '-R', '--noconfirm', 'mosquitto']);
}
}
async uninstallOnWindows() {
if (await file_utils_1.FileUtils.isCommandAvailable('choco')) {
await file_utils_1.FileUtils.executeCommand('choco', ['uninstall', 'mosquitto', '-y']);
}
}
async getVersion() {
try {
const { stdout } = await file_utils_1.FileUtils.executeCommand('mosquitto', ['-h']);
const versionMatch = stdout.match(/mosquitto version (\d+\.\d+\.\d+)/i);
return versionMatch ? versionMatch[1] : 'unknown';
}
catch (error) {
console.log(`Failed to get Mosquitto version: ${error.message}`);
return 'unknown';
}
}
}
exports.MosquittoInstaller = MosquittoInstaller;
//# sourceMappingURL=mosquitto-installer.js.map