UNPKG

tcp-serial-relay

Version:

Modular TCP to Serial relay service with comprehensive logging, monitoring and web dashboard

298 lines (257 loc) 9.8 kB
#!/usr/bin/env node // scripts/debug-config.js - Debug configuration path resolution const fs = require('fs'); const path = require('path'); const os = require('os'); function debugConfigPaths() { console.log('TCP-Serial Relay Configuration Debug'); console.log('===================================\n'); // Check all possible config paths const configPaths = [ { name: 'Environment Variable (CONFIG_PATH)', path: process.env.CONFIG_PATH, priority: 1 }, { name: 'System Config', path: '/etc/tcp-serial-relay/relay-config.json', priority: 2 }, { name: 'Local Config (CWD)', path: path.join(process.cwd(), 'config', 'relay-config.json'), priority: 3 }, { name: 'Home Directory Config', path: path.join(os.homedir(), '.tcp-serial-relay', 'relay-config.json'), priority: 4 } ]; console.log('Configuration Path Resolution Order:'); console.log('===================================='); let activeConfigPath = null; configPaths.forEach((config, index) => { const exists = config.path ? fs.existsSync(config.path) : false; const readable = exists ? (() => { try { fs.accessSync(config.path, fs.constants.R_OK); return true; } catch { return false; } })() : false; const writable = exists ? (() => { try { fs.accessSync(config.path, fs.constants.W_OK); return true; } catch { return false; } })() : false; const status = !config.path ? 'Not Set' : !exists ? 'Does Not Exist' : !readable ? 'Not Readable' : !writable ? 'Read Only' : 'OK'; console.log(`${index + 1}. ${config.name}`); console.log(` Path: ${config.path || 'undefined'}`); console.log(` Status: ${status}`); if (exists && readable) { try { const content = fs.readFileSync(config.path, 'utf8'); const parsed = JSON.parse(content); console.log(` Content: Valid JSON (${Object.keys(parsed).length} keys)`); console.log(` Connection Type: ${parsed.connectionType || 'not set'}`); if (!activeConfigPath) { activeConfigPath = config.path; console.log(` >>> THIS WILL BE USED <<<`); } } catch (error) { console.log(` Content: Invalid JSON - ${error.message}`); } } console.log(''); }); // Show which config would actually be used console.log('Actual Resolution Result:'); console.log('========================'); try { // Import the actual config path resolver const configIndexPath = path.join(__dirname, '..', 'src', 'config', 'index.js'); if (fs.existsSync(configIndexPath)) { delete require.cache[require.resolve(configIndexPath)]; const { getConfigPath } = require(configIndexPath); const resolvedPath = getConfigPath(); console.log(`Resolved config path: ${resolvedPath}`); console.log(`Path exists: ${fs.existsSync(resolvedPath)}`); if (fs.existsSync(resolvedPath)) { try { const content = fs.readFileSync(resolvedPath, 'utf8'); const config = JSON.parse(content); console.log(`Configuration preview:`); console.log(` Connection Type: ${config.connectionType}`); console.log(` Primary TCP: ${config.tcpIp}:${config.tcpPort}`); if (config.connectionType === 'tcp') { console.log(` Secondary TCP: ${config.secondaryTcpIp}:${config.secondaryTcpPort}`); } else if (config.connectionType === 'serial') { console.log(` Serial: ${config.serialPath} @ ${config.serialBaud}`); } } catch (error) { console.log(`Error reading config: ${error.message}`); } } } else { console.log('Config resolver not found - using fallback logic'); const fallbackPath = process.env.CONFIG_PATH || (fs.existsSync('/etc/tcp-serial-relay/relay-config.json') ? '/etc/tcp-serial-relay/relay-config.json' : path.join(process.cwd(), 'config', 'relay-config.json')); console.log(`Fallback path: ${fallbackPath}`); } } catch (error) { console.log(`Error resolving config path: ${error.message}`); } console.log('\nEnvironment Variables:'); console.log('====================='); const envVars = [ 'CONFIG_PATH', 'NODE_ENV', 'TCP_IP', 'TCP_PORT', 'CONNECTION_TYPE', 'SERIAL_PATH', 'SERIAL_BAUD', 'SECONDARY_TCP_IP', 'SECONDARY_TCP_PORT' ]; envVars.forEach(varName => { const value = process.env[varName]; console.log(`${varName}: ${value || '(not set)'}`); }); console.log('\nPermissions Check:'); console.log('=================='); // Check directory permissions for creating config files const testDirs = [ process.cwd(), path.join(process.cwd(), 'config'), os.homedir(), path.join(os.homedir(), '.tcp-serial-relay'), '/etc/tcp-serial-relay' ]; testDirs.forEach(dir => { const exists = fs.existsSync(dir); let canWrite = false; if (exists) { try { const testFile = path.join(dir, '.test-write-' + Date.now()); fs.writeFileSync(testFile, 'test'); fs.unlinkSync(testFile); canWrite = true; } catch { canWrite = false; } } console.log(`${dir}:`); console.log(` Exists: ${exists}`); console.log(` Writable: ${canWrite}`); }); console.log('\nRecommendations:'); console.log('================'); if (activeConfigPath) { console.log(`✅ Configuration file found at: ${activeConfigPath}`); console.log(' This file will be used by the relay service.'); } else { console.log('❌ No configuration file found.'); console.log(' Run: tcp-serial-relay config --reset'); console.log(' Then: tcp-serial-relay config --edit'); } // Check if there are multiple config files that might cause confusion const existingConfigs = configPaths.filter(c => c.path && fs.existsSync(c.path)); if (existingConfigs.length > 1) { console.log('\n⚠️ Multiple configuration files found:'); existingConfigs.forEach(config => { console.log(` ${config.path}`); }); console.log(' Only the highest priority one will be used.'); console.log(' Consider removing or consolidating the others.'); } } function fixPermissions() { console.log('Attempting to fix configuration permissions...\n'); const configDir = path.join(process.cwd(), 'config'); const configFile = path.join(configDir, 'relay-config.json'); try { // Create config directory if it doesn't exist if (!fs.existsSync(configDir)) { fs.mkdirSync(configDir, { recursive: true }); console.log(`✅ Created directory: ${configDir}`); } // Create default config file if it doesn't exist if (!fs.existsSync(configFile)) { const defaultConfigPath = path.join(__dirname, '..', 'src', 'config', 'default-config.js'); if (fs.existsSync(defaultConfigPath)) { delete require.cache[require.resolve(defaultConfigPath)]; const defaultConfig = require(defaultConfigPath); fs.writeFileSync(configFile, JSON.stringify(defaultConfig, null, 2), 'utf8'); console.log(`✅ Created default config: ${configFile}`); } } // Test read/write access const testContent = fs.readFileSync(configFile, 'utf8'); fs.writeFileSync(configFile, testContent, 'utf8'); console.log(`✅ Configuration file is readable and writable`); } catch (error) { console.log(`❌ Failed to fix permissions: ${error.message}`); // Try alternative location const homeConfigDir = path.join(os.homedir(), '.tcp-serial-relay'); const homeConfigFile = path.join(homeConfigDir, 'relay-config.json'); try { if (!fs.existsSync(homeConfigDir)) { fs.mkdirSync(homeConfigDir, { recursive: true }); console.log(`✅ Created alternative directory: ${homeConfigDir}`); } if (!fs.existsSync(homeConfigFile)) { const defaultConfigPath = path.join(__dirname, '..', 'src', 'config', 'default-config.js'); if (fs.existsSync(defaultConfigPath)) { delete require.cache[require.resolve(defaultConfigPath)]; const defaultConfig = require(defaultConfigPath); fs.writeFileSync(homeConfigFile, JSON.stringify(defaultConfig, null, 2), 'utf8'); console.log(`✅ Created alternative config: ${homeConfigFile}`); } } } catch (altError) { console.log(`❌ Alternative location also failed: ${altError.message}`); } } } // Command line interface const command = process.argv[2]; switch (command) { case 'debug': case undefined: debugConfigPaths(); break; case 'fix': fixPermissions(); break; case 'help': default: console.log('TCP-Serial Relay Configuration Debug Tool'); console.log('========================================='); console.log(''); console.log('Usage:'); console.log(' node debug-config.js [command]'); console.log(''); console.log('Commands:'); console.log(' debug Show configuration path resolution (default)'); console.log(' fix Attempt to fix configuration permissions'); console.log(' help Show this help message'); console.log(''); console.log('Examples:'); console.log(' node debug-config.js'); console.log(' node debug-config.js debug'); console.log(' node debug-config.js fix'); break; } module.exports = { debugConfigPaths, fixPermissions };