diff --git a/src/apps.js b/src/apps.js index 11b78da9b..adfe7f423 100644 --- a/src/apps.js +++ b/src/apps.js @@ -266,10 +266,10 @@ function translatePortBindings(portBindings, manifest) { if (!portBindings) return null; - let result = {}; + const result = {}; const tcpPorts = manifest.tcpPorts || { }; - for (let portName in portBindings) { + for (const portName in portBindings) { const portType = portName in tcpPorts ? exports.PORT_TYPE_TCP : exports.PORT_TYPE_UDP; const portCount = portBindings[portName].portCount || (portName in tcpPorts ? manifest.tcpPorts[portName].portCount : manifest.udpPorts[portName].portCount); result[portName] = { hostPort: portBindings[portName], type: portType, portCount: portCount || 1 }; @@ -341,8 +341,8 @@ function parseCrontab(crontab) { try { new CronTime('00 ' + schedule); // second is disallowed - } catch (ex) { - throw new BoxError(BoxError.BAD_FIELD, `Invalid cron pattern at line ${i+1}`); + } catch (error) { + throw new BoxError(BoxError.BAD_FIELD, `Invalid cron pattern at line ${i+1}: ${error.message}`); } if (command.length === 0) throw new BoxError(BoxError.BAD_FIELD, `Invalid cron pattern. Command must not be empty at line ${i+1}`); // not possible with the regexp we have @@ -482,7 +482,7 @@ function validateTags(tags) { } function validateEnv(env) { - for (let key in env) { + for (const key in env) { if (key.length > 512) return new BoxError(BoxError.BAD_FIELD, 'Max env var key length is 512'); // http://pubs.opengroup.org/onlinepubs/000095399/basedefs/xbd_chap08.html if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(key)) return new BoxError(BoxError.BAD_FIELD, `"${key}" is not a valid environment variable`); @@ -645,9 +645,9 @@ function postProcess(result) { assert(result.environmentVariables === null || typeof result.environmentVariables === 'string'); result.portBindings = { }; - let hostPorts = result.hostPorts === null ? [ ] : result.hostPorts.split(','); - let environmentVariables = result.environmentVariables === null ? [ ] : result.environmentVariables.split(','); - let portTypes = result.portTypes === null ? [ ] : result.portTypes.split(','); + const hostPorts = result.hostPorts === null ? [ ] : result.hostPorts.split(','); + const environmentVariables = result.environmentVariables === null ? [ ] : result.environmentVariables.split(','); + const portTypes = result.portTypes === null ? [ ] : result.portTypes.split(','); delete result.hostPorts; delete result.environmentVariables; @@ -724,7 +724,7 @@ function postProcess(result) { const volumeIds = JSON.parse(result.volumeIds); delete result.volumeIds; - let volumeReadOnlys = JSON.parse(result.volumeReadOnlys); + const volumeReadOnlys = JSON.parse(result.volumeReadOnlys); delete result.volumeReadOnlys; result.mounts = volumeIds[0] === null ? [] : volumeIds.map((v, idx) => { return { volumeId: v, readOnly: !!volumeReadOnlys[idx] }; }); // NOTE: volumeIds is [null] when volumes of an app is empty @@ -739,8 +739,8 @@ function attachProperties(app, domainObjectMap) { assert.strictEqual(typeof app, 'object'); assert.strictEqual(typeof domainObjectMap, 'object'); - let result = {}; - for (let portName in app.portBindings) { + const result = {}; + for (const portName in app.portBindings) { result[portName] = app.portBindings[portName].hostPort; } app.portBindings = result; @@ -802,7 +802,7 @@ async function checkForPortBindingConflict(portBindings, id = '') { const tcpPorts = existingPortBindings.filter((p) => p.type === 'tcp'); const udpPorts = existingPortBindings.filter((p) => p.type === 'udp'); - for (let portName in portBindings) { + for (const portName in portBindings) { const p = portBindings[portName]; const testPorts = p.type === 'tcp' ? tcpPorts : udpPorts; @@ -1218,7 +1218,7 @@ async function scheduleTask(appId, installationState, taskId, auditSource) { debug(`scheduleTask: task ${taskId} of ${appId} completed`); if (error && (error.code === tasks.ECRASHED || error.code === tasks.ESTOPPED)) { // if task crashed, update the error debug(`Apptask crashed/stopped: ${error.message}`); - let boxError = new BoxError(BoxError.TASK_ERROR, error.message); + const boxError = new BoxError(BoxError.TASK_ERROR, error.message); boxError.details.crashed = error.code === tasks.ECRASHED; boxError.details.stopped = error.code === tasks.ESTOPPED; // see also apptask makeTaskError @@ -1461,7 +1461,7 @@ async function setAccessRestriction(app, accessRestriction, auditSource) { assert.strictEqual(typeof auditSource, 'object'); const appId = app.id; - let error = validateAccessRestriction(accessRestriction); + const error = validateAccessRestriction(accessRestriction); if (error) throw error; await update(appId, { accessRestriction }); @@ -1515,7 +1515,7 @@ async function setLabel(app, label, auditSource) { assert.strictEqual(typeof auditSource, 'object'); const appId = app.id; - let error = validateLabel(label); + const error = validateLabel(label); if (error) throw error; await update(appId, { label }); @@ -1528,7 +1528,7 @@ async function setTags(app, tags, auditSource) { assert.strictEqual(typeof auditSource, 'object'); const appId = app.id; - let error = validateTags(tags); + const error = validateTags(tags); if (error) throw error; await update(appId, { tags }); @@ -1621,7 +1621,7 @@ async function setMounts(app, mounts, auditSource) { assert.strictEqual(typeof auditSource, 'object'); const appId = app.id; - let error = checkAppState(app, exports.ISTATE_PENDING_RECREATE_CONTAINER); + const error = checkAppState(app, exports.ISTATE_PENDING_RECREATE_CONTAINER); if (error) throw error; const task = { @@ -1772,7 +1772,7 @@ async function setTurn(app, enableTurn, auditSource) { assert.strictEqual(typeof auditSource, 'object'); const appId = app.id; - let error = checkAppState(app, exports.ISTATE_PENDING_SERVICES_CHANGE); + const error = checkAppState(app, exports.ISTATE_PENDING_SERVICES_CHANGE); if (error) throw error; if (!app.manifest.addons?.turn) throw new BoxError(BoxError.BAD_FIELD, 'App does not use turn addon'); @@ -1795,7 +1795,7 @@ async function setRedis(app, enableRedis, auditSource) { assert.strictEqual(typeof auditSource, 'object'); const appId = app.id; - let error = checkAppState(app, exports.ISTATE_PENDING_SERVICES_CHANGE); + const error = checkAppState(app, exports.ISTATE_PENDING_SERVICES_CHANGE); if (error) throw error; if (!app.manifest.addons?.redis) throw new BoxError(BoxError.BAD_FIELD, 'App does not use redis addon'); @@ -1943,9 +1943,9 @@ async function setLocation(app, data, auditSource) { }, values }; - let [taskError, taskId] = await safe(addTask(appId, exports.ISTATE_PENDING_LOCATION_CHANGE, task, auditSource)); - if (taskError && taskError.reason === BoxError.ALREADY_EXISTS) taskError = getDuplicateErrorDetails(taskError.message, locations, data.portBindings); - if (taskError) throw taskError; + const [taskError, taskId] = await safe(addTask(appId, exports.ISTATE_PENDING_LOCATION_CHANGE, task, auditSource)); + if (taskError && taskError.reason !== BoxError.ALREADY_EXISTS) throw taskError; + if (taskError && taskError.reason === BoxError.ALREADY_EXISTS) throw getDuplicateErrorDetails(taskError.message, locations, data.portBindings); values.fqdn = dns.fqdn(values.subdomain, values.domain); values.secondaryDomains.forEach(function (ad) { ad.fqdn = dns.fqdn(ad.subdomain, ad.domain); }); @@ -1964,7 +1964,7 @@ async function setStorage(app, volumeId, volumePrefix, auditSource) { assert.strictEqual(typeof auditSource, 'object'); const appId = app.id; - let error = checkAppState(app, exports.ISTATE_PENDING_DATA_DIR_MIGRATION); + const error = checkAppState(app, exports.ISTATE_PENDING_DATA_DIR_MIGRATION); if (error) throw error; if (volumeId) { @@ -1995,7 +1995,7 @@ async function updateApp(app, data, auditSource) { manifest = data.manifest, appStoreId = data.appStoreId; - let values = {}; + const values = {}; if (app.runState === exports.RSTATE_STOPPED) throw new BoxError(BoxError.BAD_STATE, 'Stopped apps cannot be updated'); @@ -2168,7 +2168,7 @@ async function repair(app, data, auditSource) { } else { errorState = exports.ISTATE_PENDING_CONFIGURE; if (data.dockerImage) { - let newManifest = Object.assign({}, app.manifest, { dockerImage: data.dockerImage }); + const newManifest = Object.assign({}, app.manifest, { dockerImage: data.dockerImage }); task.values.manifest = newManifest; } } @@ -2291,7 +2291,7 @@ async function exportApp(app, data, auditSource) { const appId = app.id; - let error = checkAppState(app, exports.ISTATE_PENDING_BACKUP); + const error = checkAppState(app, exports.ISTATE_PENDING_BACKUP); if (error) throw error; const task = { @@ -2412,7 +2412,7 @@ async function uninstall(app, auditSource) { assert.strictEqual(typeof auditSource, 'object'); const appId = app.id; - let error = checkAppState(app, exports.ISTATE_PENDING_UNINSTALL); + const error = checkAppState(app, exports.ISTATE_PENDING_UNINSTALL); if (error) throw error; await appstore.unpurchaseApp(appId, { appstoreId: app.appStoreId, manifestId: app.manifest.id || 'customapp' }); @@ -2433,7 +2433,7 @@ async function start(app, auditSource) { assert.strictEqual(typeof auditSource, 'object'); const appId = app.id; - let error = checkAppState(app, exports.ISTATE_PENDING_START); + const error = checkAppState(app, exports.ISTATE_PENDING_START); if (error) throw error; const task = { @@ -2450,7 +2450,7 @@ async function stop(app, auditSource) { assert.strictEqual(typeof auditSource, 'object'); const appId = app.id; - let error = checkAppState(app, exports.ISTATE_PENDING_STOP); + const error = checkAppState(app, exports.ISTATE_PENDING_STOP); if (error) throw error; const task = { @@ -2469,7 +2469,7 @@ async function restart(app, auditSource) { assert.strictEqual(typeof auditSource, 'object'); const appId = app.id; - let error = checkAppState(app, exports.ISTATE_PENDING_RESTART); + const error = checkAppState(app, exports.ISTATE_PENDING_RESTART); if (error) throw error; const task = { @@ -2596,7 +2596,7 @@ function canAutoupdateApp(app, updateInfo) { const newUdpPorts = manifest.udpPorts || { }; const portBindings = app.portBindings; // this is never null - for (let portName in portBindings) { + for (const portName in portBindings) { if (!(portName in newTcpPorts) && !(portName in newUdpPorts)) return false; // portName was in use but new update removes it } @@ -2637,7 +2637,7 @@ async function backup(app, auditSource) { const appId = app.id; - let error = checkAppState(app, exports.ISTATE_PENDING_BACKUP); + const error = checkAppState(app, exports.ISTATE_PENDING_BACKUP); if (error) throw error; const task = { @@ -2838,7 +2838,8 @@ async function downloadFile(app, filePath) { const parts = data.split('-'); if (parts.length !== 2) throw new BoxError(BoxError.NOT_FOUND, 'file does not exist'); - let type = parts[0], filename, cmd, size; + const type = parts[0]; + let filename, cmd, size; if (type === 'regular file') { cmd = [ 'cat', filePath ];