diff --git a/ZelBack/src/services/appsService.js b/ZelBack/src/services/appsService.js index ad732efd3..d2c008317 100644 --- a/ZelBack/src/services/appsService.js +++ b/ZelBack/src/services/appsService.js @@ -9714,7 +9714,7 @@ async function checkInstallingAppPortAvailable(portsToTest = []) { } if ((userconfig.initial.apiport && userconfig.initial.apiport !== config.server.apiport) || isUPNP) { // eslint-disable-next-line no-await-in-loop - await upnpService.mapUpnpPort(portToTest, 'Flux_Test_App'); + await upnpService.mapUpnpPort(portToTest, `Flux_Prelaunch_App_${portToTest}`); } const beforeAppInstallTestingExpress = express(); const beforeAppInstallTestingServer = http.createServer(beforeAppInstallTestingExpress); @@ -9961,23 +9961,24 @@ async function checkForNonAllowedAppsOnLocalNetwork() { if (logs.toLowerCase().includes('duplicate ip: this ip address is already running another node')) { log.error('Another PresearchNode was detected running on your local network.'); // dosDuplicateAppMessage = 'Another PresearchNode was detected running on your local network.'; - // break; + break; } } } if (dosDuplicateAppMessage) { setTimeout(() => { checkForNonAllowedAppsOnLocalNetwork(); - }, 5 * 60 * 1000); + }, 60 * 60 * 1000); + } else { + setTimeout(() => { + checkForNonAllowedAppsOnLocalNetwork(); + }, 12 * 60 * 60 * 1000); } - setTimeout(() => { - checkForNonAllowedAppsOnLocalNetwork(); - }, 12 * 60 * 60 * 1000); } catch (error) { log.error(error); setTimeout(() => { checkForNonAllowedAppsOnLocalNetwork(); - }, 5 * 60 * 1000); + }, 60 * 60 * 1000); } } diff --git a/ZelBack/src/services/idService.js b/ZelBack/src/services/idService.js index 79dc0158b..cac3afb5f 100644 --- a/ZelBack/src/services/idService.js +++ b/ZelBack/src/services/idService.js @@ -94,6 +94,7 @@ async function confirmNodeTierHardware() { * @param {object} res Response. * @returns {void} Return statement is only used here to interrupt the function and nothing is returned. */ +let firstLoginPhraseExecution = true; async function loginPhrase(req, res) { try { // check db @@ -105,17 +106,16 @@ async function loginPhrase(req, res) { await dbHelper.findOneInDatabase(database, collection, query, projection); // fast find call for db test // check synthing availability - const syncthingDeviceID = await syncthingService.getDeviceID(); - if (syncthingDeviceID.status === 'error') { + if (!syncthingService.isRunning() && !firstLoginPhraseExecution) { if (syncthingWorking) { syncthingWorking = false; - syncthingService.systemRestart(); } else { throw new Error('Syncthing is not running properly'); } } else { syncthingWorking = true; } + firstLoginPhraseExecution = false; // check docker availablility await dockerService.dockerListImages(); // check Node Hardware Requirements are ok. diff --git a/ZelBack/src/services/syncthingService.js b/ZelBack/src/services/syncthingService.js index b106551eb..d4cfa115e 100644 --- a/ZelBack/src/services/syncthingService.js +++ b/ZelBack/src/services/syncthingService.js @@ -1911,6 +1911,7 @@ async function getSvcReport(req, res) { * @param {object} res Response. * @returns {object} Message */ +let syncthingStatusOk = false; async function getDeviceID(req, res) { try { const meta = await getMeta(); @@ -1929,6 +1930,7 @@ async function getDeviceID(req, res) { const deviceObject = JSON.parse(adjustedString); const { deviceID } = deviceObject; const successResponse = messageHelper.createDataMessage(deviceID); + syncthingStatusOk = true; return res ? res.json(successResponse) : successResponse; } log.info(meta.status); @@ -1936,6 +1938,7 @@ async function getDeviceID(req, res) { log.info(healthy.data); throw new Error('Syncthing is not running properly'); } catch (error) { + syncthingStatusOk = false; log.error(error); const errorResponse = messageHelper.createErrorMessage(error.message, error.name, error.code); return res ? res.json(errorResponse) : errorResponse; @@ -1943,12 +1946,36 @@ async function getDeviceID(req, res) { } /** - * To install Syncthing + * Returns if syncthing service is running ok + * @returns {boolean} True if getDeviceID last execution was successful */ +function isRunning() { + return syncthingStatusOk; +} + +/** + * Check if Synchtng is installed and if not install it + */ +let syncthingInstalled = false; async function installSyncthing() { // can throw - const nodedpath = path.join(__dirname, '../../../helpers'); - const exec = `cd ${nodedpath} && bash installSyncthing.sh`; - await cmdAsync(exec); + // check if syncthing is installed or not + log.info('Checking if Syncthing is installed...'); + const execIsInstalled = 'syncthing --version'; + let isInstalled = true; + await cmdAsync(execIsInstalled).catch((error) => { + if (error) { + log.error(error); + log.info('Syncthing not installed....'); + isInstalled = false; + } + }); + if (!isInstalled) { + log.info('Installing Syncthing...'); + const nodedpath = path.join(__dirname, '../../../helpers'); + const exec = `cd ${nodedpath} && bash installSyncthing.sh`; + await cmdAsync(exec); + } + syncthingInstalled = true; log.info('Syncthing installed'); } @@ -1956,18 +1983,26 @@ async function installSyncthing() { // can throw * To Start Syncthing */ let previousSyncthingErrored = false; +let lastGetDeviceIdCallOk = false; async function startSyncthing() { try { + if (!syncthingInstalled) { + await installSyncthing(); + await serviceHelper.delay(10 * 1000); + startSyncthing(); + } // check wether syncthing is running or not const myDevice = await getDeviceID(); if (myDevice.status === 'error') { // retry before killing and restarting - if (previousSyncthingErrored === false) { + if (!previousSyncthingErrored && lastGetDeviceIdCallOk) { await systemRestart(); + lastGetDeviceIdCallOk = false; previousSyncthingErrored = true; await serviceHelper.delay(60 * 1000); startSyncthing(); } + lastGetDeviceIdCallOk = false; previousSyncthingErrored = false; log.error('Syncthing Error'); log.error(myDevice); @@ -1983,23 +2018,18 @@ async function startSyncthing() { await serviceHelper.delay(10 * 1000); await cmdAsync(execKill).catch((error) => log.error(error)); await cmdAsync(execKillB).catch((error) => log.error(error)); - const exec = 'sudo nohup syncthing --allow-newer-config --no-browser --home=$HOME/.config/syncthing &'; + const exec = 'sudo nohup syncthing -logfile $HOME/.config/syncthing/syncthing.log --allow-newer-config --no-browser --home=$HOME/.config/syncthing &'; log.info('Spawning Syncthing instance...'); - let errored = false; nodecmd.get(exec, async (err) => { if (err) { - errored = true; log.error(err); - log.info('Syncthing is not installed, proceeding with installation'); + log.info('Error starting synchting.'); } }); - await serviceHelper.delay(30 * 1000); - if (errored) { - await installSyncthing(); - await serviceHelper.delay(60 * 1000); - } + await serviceHelper.delay(60 * 1000); startSyncthing(); } else { + lastGetDeviceIdCallOk = true; const currentConfigOptions = await getConfigOptions(); const currentDefaultsFolderOptions = await getConfigDefaultsFolder(); const apiPort = userconfig.initial.apiport || config.server.apiport; @@ -2058,6 +2088,11 @@ async function startSyncthing() { } } +// test helper +function setSyncthingRunningState(value) { + syncthingStatusOk = value; +} + module.exports = { startSyncthing, getDeviceID, @@ -2145,4 +2180,8 @@ module.exports = { // helpers adjustConfigFolders, adjustConfigDevices, + // status + isRunning, + // test + setSyncthingRunningState, }; diff --git a/package.json b/package.json index 45f4aa81e..805898b24 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "flux", - "version": "4.0.0", + "version": "4.0.1", "description": "Flux, Your Gateway to a Decentralized World", "repository": { "type": "git", diff --git a/tests/ZelBack/apiTests.js b/tests/ZelBack/apiTests.js index 6e1a61311..c6e1aeb29 100644 --- a/tests/ZelBack/apiTests.js +++ b/tests/ZelBack/apiTests.js @@ -5,6 +5,7 @@ const chai = require('chai'); const app = require('../../ZelBack/src/lib/server'); const log = require('../../ZelBack/src/lib/log'); const dbHelper = require('../../ZelBack/src/services/dbHelper'); +const syncthingService = require('../../ZelBack/src/services/syncthingService'); const packageJson = require('../../package.json'); @@ -43,6 +44,7 @@ describe('loading express', () => { .expect(404, done); }); it('/id/loginphrase', (done) => { + syncthingService.setSyncthingRunningState(true); request(server) .get('/id/loginphrase') .expect(200) diff --git a/tests/unit/idService.test.js b/tests/unit/idService.test.js index 8cb86f709..48cce6ab8 100644 --- a/tests/unit/idService.test.js +++ b/tests/unit/idService.test.js @@ -13,6 +13,7 @@ const serviceHelper = require('../../ZelBack/src/services/serviceHelper'); const generalService = require('../../ZelBack/src/services/generalService'); const dockerService = require('../../ZelBack/src/services/dockerService'); const fluxNetworkHelper = require('../../ZelBack/src/services/fluxNetworkHelper'); +const syncthingService = require('../../ZelBack/src/services/syncthingService'); const adminConfig = { fluxTeamZelId: '1zasdfg', @@ -272,6 +273,7 @@ describe('idService tests', () => { tierStub = sinon.stub(generalService, 'nodeTier'); collateralStub = sinon.stub(generalService, 'nodeCollateral'); getDOSStateStub = sinon.stub(fluxNetworkHelper, 'getDOSState'); + syncthingService.setSyncthingRunningState(true); // only checks for docker availablity sinon.stub(dockerService, 'dockerListImages').returns(true); });