diff --git a/packages/api/.env b/packages/api/.env index b438b9fba..2ea12e8f0 100644 --- a/packages/api/.env +++ b/packages/api/.env @@ -1,6 +1,8 @@ DEVMODE=1 SHELL_SCRIPTING=1 +CLOUD_UPGRADE_FILE=c:\test\upg\upgrade.zip + # PERMISSIONS=~widgets/app,~widgets/plugins # DISABLE_SHELL=1 # HIDE_APP_EDITOR=1 diff --git a/packages/api/package.json b/packages/api/package.json index 991c8611c..41d6b6746 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -56,6 +56,7 @@ "pinomin": "^1.0.4", "portfinder": "^1.0.28", "rimraf": "^3.0.0", + "semver": "^7.6.3", "simple-encryptor": "^4.0.0", "ssh2": "^1.11.0", "stream-json": "^1.8.0", diff --git a/packages/api/src/main.js b/packages/api/src/main.js index d8a1a4fe3..ad77278be 100644 --- a/packages/api/src/main.js +++ b/packages/api/src/main.js @@ -35,6 +35,7 @@ const getExpressPath = require('./utility/getExpressPath'); const _ = require('lodash'); const { getLogger } = require('dbgate-tools'); const { getDefaultAuthProvider } = require('./auth/authProvider'); +const startCloudUpgradeTimer = require('./utility/cloudUpgrade'); const logger = getLogger('main'); @@ -168,6 +169,10 @@ function start() { process.on('SIGINT', shutdown); process.on('SIGTERM', shutdown); process.on('SIGBREAK', shutdown); + + if (process.env.CLOUD_UPGRADE_FILE) { + startCloudUpgradeTimer(); + } } function useAllControllers(app, electron) { diff --git a/packages/api/src/utility/cloudUpgrade.js b/packages/api/src/utility/cloudUpgrade.js new file mode 100644 index 000000000..12d60868e --- /dev/null +++ b/packages/api/src/utility/cloudUpgrade.js @@ -0,0 +1,61 @@ +const axios = require('axios'); +const fs = require('fs'); +const fsp = require('fs/promises'); +const semver = require('semver'); +const currentVersion = require('../currentVersion'); +const { getLogger, extractErrorLogData } = require('dbgate-tools'); + +const logger = getLogger('cloudUpgrade'); + +async function checkCloudUpgrade() { + try { + const resp = await axios.default.get('https://api.github.com/repos/dbgate/dbgate/releases/latest'); + const json = resp.data; + const version = json.name.substring(1); + let cloudDownloadedVersion = null; + try { + cloudDownloadedVersion = await fsp.readFile(process.env.CLOUD_UPGRADE_FILE + '.version', 'utf-8'); + } catch (err) { + cloudDownloadedVersion = null; + } + if ( + semver.gt(version, currentVersion.version) && + (!cloudDownloadedVersion || semver.gt(version, cloudDownloadedVersion)) + ) { + logger.info(`New version available: ${version}`); + const zipUrl = json.assets.find(x => x.name == 'cloud-build.zip').browser_download_url; + + const writer = fs.createWriteStream(process.env.CLOUD_UPGRADE_FILE); + + const response = await axios.default({ + url: zipUrl, + method: 'GET', + responseType: 'stream', + }); + + response.data.pipe(writer); + + await new Promise((resolve, reject) => { + writer.on('finish', resolve); + writer.on('error', reject); + }); + await fsp.writeFile(process.env.CLOUD_UPGRADE_FILE + '.version', version); + + logger.info(`Downloaded new version from ${zipUrl}`); + } else { + logger.info(`Checked version ${version} is not newer than ${cloudDownloadedVersion ?? currentVersion.version}, upgrade skippped`); + } + } catch (err) { + logger.error(extractErrorLogData(err), 'Error checking cloud upgrade'); + } +} + +function startCloudUpgradeTimer() { + // at first in 5 seconds + setTimeout(checkCloudUpgrade, 5000); + + // hourly + setInterval(checkCloudUpgrade, 60 * 60 * 1000); +} + +module.exports = startCloudUpgradeTimer; diff --git a/yarn.lock b/yarn.lock index 6eb67e0bb..c96abd7f2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4129,10 +4129,10 @@ dbgate-plugin-xml@^5.0.0-alpha.1: resolved "https://registry.yarnpkg.com/dbgate-plugin-xml/-/dbgate-plugin-xml-5.2.7.tgz#0762af51ba6f100e75a63907ea6c679e827c9f7c" integrity sha512-gBXy4qetf7eJQW6lM01B+OKLnKB8MKesojdYKysD9oZ+YpQCX8Tq7aHJCrN14FiyIDinpX61kmFH1+LGJ2RkxQ== -dbgate-query-splitter@^4.11.1: - version "4.11.1" - resolved "https://registry.yarnpkg.com/dbgate-query-splitter/-/dbgate-query-splitter-4.11.1.tgz#8bbf8e1d5bc1dbc7ca43be5cf7b7fa9ac0fed0c7" - integrity sha512-5qcSRmnTkdZFWy9m7iiE1PtaE0fkwFx0HuUV5M/EjF6susz1DXStg05rWvybK9y7Sgvu5SjQlV1C3cvsEnSNSw== +dbgate-query-splitter@^4.11.2: + version "4.11.2" + resolved "https://registry.yarnpkg.com/dbgate-query-splitter/-/dbgate-query-splitter-4.11.2.tgz#f54e6bcb998de7630978cd45b347d6f329115171" + integrity sha512-LG326CAsTvb4IhJPDf6vbv92zOEhVza/Cncj1L4RSFchppIdlJMhwEyAekZzCm7U2NKzYObPJN5eWvF/QJrrKQ== debug@2.6.9, debug@^2.2.0, debug@^2.3.3: version "2.6.9" @@ -10154,6 +10154,11 @@ semver@7.x, semver@^7.1.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5, semver@^ resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.1.tgz#60bfe090bf907a25aa8119a72b9f90ef7ca281b2" integrity sha512-f/vbBsu+fOiYt+lmwZV0rVwJScl46HppnOA1ZvIuBWKOTlllpyJ3bfVax76/OrhCH38dyxoDIA8K7uB963IYgA== +semver@^7.6.3: + version "7.6.3" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.3.tgz#980f7b5550bc175fb4dc09403085627f9eb33143" + integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A== + semver@~7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e"