diff --git a/lib/actions-oclif/device/init.ts b/lib/actions-oclif/device/init.ts index 5cd8586b..c8fc7c3f 100644 --- a/lib/actions-oclif/device/init.ts +++ b/lib/actions-oclif/device/init.ts @@ -79,7 +79,7 @@ export default class DeviceInitCmd extends Command { const { flags: options } = this.parse(DeviceInitCmd); // Imports - const { promisify } = await import('bluebird'); + const { promisify } = await import('util'); const rimraf = promisify(await import('rimraf')); const tmp = await import('tmp'); const tmpNameAsync = promisify(tmp.tmpName); diff --git a/lib/actions-oclif/scan.ts b/lib/actions-oclif/scan.ts index 47f96217..03be5c6b 100644 --- a/lib/actions-oclif/scan.ts +++ b/lib/actions-oclif/scan.ts @@ -59,7 +59,6 @@ export default class ScanCmd extends Command { public static root = true; public async run() { - const Bluebird = await import('bluebird'); const _ = await import('lodash'); const { SpinnerPromise } = getVisuals(); const { discover } = await import('balena-sync'); @@ -106,22 +105,22 @@ export default class ScanCmd extends Command { // Query devices for info const devicesInfo = await Promise.all( - activeLocalDevices.map(({ host, address }) => { + activeLocalDevices.map(async ({ host, address }) => { const docker = dockerUtils.createClient({ host: address, port: dockerPort, timeout: dockerTimeout, }) as any; - return Bluebird.props({ + const [dockerInfo, dockerVersion] = await Promise.all([ + docker.infoAsync().catchReturn('Could not get Docker info'), + docker.versionAsync().catchReturn('Could not get Docker version'), + ]); + return { host, address, - dockerInfo: docker - .infoAsync() - .catchReturn('Could not get Docker info'), - dockerVersion: docker - .versionAsync() - .catchReturn('Could not get Docker version'), - }); + dockerInfo, + dockerVersion, + }; }), ); diff --git a/lib/utils/deploy-legacy.js b/lib/utils/deploy-legacy.js index 20b39805..1034a3c1 100644 --- a/lib/utils/deploy-legacy.js +++ b/lib/utils/deploy-legacy.js @@ -15,8 +15,8 @@ * limitations under the License. */ -import * as Bluebird from 'bluebird'; import { getVisuals } from './lazy'; +import { promisify } from 'util'; const getBuilderPushEndpoint = function (baseUrl, owner, app) { const querystring = require('querystring'); @@ -158,7 +158,7 @@ opts must be a hash with the following keys: - buildLogs: a string with build output - shouldUploadLogs */ -export const deployLegacy = function ( +export const deployLegacy = async function ( docker, logger, token, @@ -167,7 +167,7 @@ export const deployLegacy = function ( opts, ) { const tmp = require('tmp'); - const tmpNameAsync = Bluebird.promisify(tmp.tmpName); + const tmpNameAsync = promisify(tmp.tmpName); // Ensure the tmp files gets deleted tmp.setGracefulCleanup(); @@ -175,37 +175,35 @@ export const deployLegacy = function ( const { appName, imageName, buildLogs, shouldUploadLogs } = opts; const logs = buildLogs; - return tmpNameAsync() - .then(function (bufferFile) { - logger.logInfo('Initializing deploy...'); - return bufferImage(docker, imageName, bufferFile) - .then((stream) => - uploadImage(stream, token, username, url, appName, logger), - ) - .finally(() => - // If the file was never written to (for instance because an error - // has occured before any data was written) this call will throw an - // ugly error, just suppress it - Bluebird.try(() => - require('fs').promises.unlink(bufferFile), - ).catchReturn(undefined), - ); - }) - .tap(function ({ buildId }) { - if (!shouldUploadLogs) { - return; - } + const bufferFile = await tmpNameAsync(); - logger.logInfo('Uploading logs...'); - return Bluebird.join( - logs, - token, - url, - buildId, - username, - appName, - uploadLogs, - ); - }) - .get('buildId'); + logger.logInfo('Initializing deploy...'); + const { buildId } = await bufferImage(docker, imageName, bufferFile) + .then((stream) => + uploadImage(stream, token, username, url, appName, logger), + ) + .finally(() => + // If the file was never written to (for instance because an error + // has occured before any data was written) this call will throw an + // ugly error, just suppress it + + require('fs') + .promises.unlink(bufferFile) + .catch(() => undefined), + ); + + if (shouldUploadLogs) { + logger.logInfo('Uploading logs...'); + const args = await Promise.all([ + logs, + token, + url, + buildId, + username, + appName, + ]); + await uploadLogs(...args); + } + + return buildId; }; diff --git a/lib/utils/device/api.ts b/lib/utils/device/api.ts index 5189eea9..a7b50cde 100644 --- a/lib/utils/device/api.ts +++ b/lib/utils/device/api.ts @@ -14,7 +14,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import * as Bluebird from 'bluebird'; import * as _ from 'lodash'; import type { NodeJSSocketWithFileDescriptor } from 'net-keepalive'; import * as os from 'os'; @@ -85,8 +84,8 @@ export class DeviceAPI { public async setTargetState(state: any): Promise { const url = this.getUrlForAction('setTargetState'); return DeviceAPI.promisifiedRequest( - request.post, { + method: 'POST', url, json: true, body: state, @@ -99,8 +98,8 @@ export class DeviceAPI { const url = this.getUrlForAction('getTargetState'); return DeviceAPI.promisifiedRequest( - request.get, { + method: 'GET', url, json: true, }, @@ -114,8 +113,8 @@ export class DeviceAPI { const url = this.getUrlForAction('getDeviceInformation'); return DeviceAPI.promisifiedRequest( - request.get, { + method: 'GET', url, json: true, }, @@ -129,8 +128,8 @@ export class DeviceAPI { const url = this.getUrlForAction('containerId'); const body = await DeviceAPI.promisifiedRequest( - request.get, { + method: 'GET', url, json: true, qs: { @@ -152,8 +151,8 @@ export class DeviceAPI { const url = this.getUrlForAction('ping'); return DeviceAPI.promisifiedRequest( - request.get, { + method: 'GET', url, }, this.logger, @@ -163,7 +162,8 @@ export class DeviceAPI { public getVersion(): Promise { const url = this.getUrlForAction('version'); - return DeviceAPI.promisifiedRequest(request.get, { + return DeviceAPI.promisifiedRequest({ + method: 'GET', url, json: true, }).then((body) => { @@ -180,7 +180,8 @@ export class DeviceAPI { public getStatus(): Promise { const url = this.getUrlForAction('status'); - return DeviceAPI.promisifiedRequest(request.get, { + return DeviceAPI.promisifiedRequest({ + method: 'GET', url, json: true, }).then((body) => { @@ -233,14 +234,9 @@ export class DeviceAPI { // A helper method for promisifying general (non-streaming) requests. Streaming // requests should use a seperate setup - private static async promisifiedRequest( - requestMethod: ( - opts: T, - cb: (err?: any, res?: any, body?: any) => void, - ) => void, - opts: T, - logger?: Logger, - ): Promise { + private static async promisifiedRequest< + T extends Parameters[0] + >(opts: T, logger?: Logger): Promise { interface ObjectWithUrl { url?: string; } @@ -260,22 +256,24 @@ export class DeviceAPI { } } - return Bluebird.fromCallback<[request.Response, { message: string }]>( - (cb) => { - return requestMethod(opts, cb); - }, - { multiArgs: true }, - ).then(([response, body]) => { - switch (response.statusCode) { - case 200: - return body; - case 400: - throw new ApiErrors.BadRequestDeviceAPIError(body.message); - case 503: - throw new ApiErrors.ServiceUnavailableAPIError(body.message); - default: - throw new ApiErrors.DeviceAPIError(body.message); - } + return new Promise((resolve, reject) => { + return request(opts, (err, response, body) => { + if (err) { + return reject(err); + } + switch (response.statusCode) { + case 200: + return resolve(body); + case 400: + return reject(new ApiErrors.BadRequestDeviceAPIError(body.message)); + case 503: + return reject( + new ApiErrors.ServiceUnavailableAPIError(body.message), + ); + default: + return reject(new ApiErrors.DeviceAPIError(body.message)); + } + }); }); } } diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index 9c45b169..e1e569b2 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -1469,9 +1469,9 @@ "dev": true }, "@types/rimraf": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@types/rimraf/-/rimraf-2.0.4.tgz", - "integrity": "sha512-8gBudvllD2A/c0CcEX/BivIDorHFt5UI5m46TsNj8DjWCCTTZT74kEe4g+QsY7P/B9WdO98d82zZgXO/RQzu2Q==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/rimraf/-/rimraf-3.0.0.tgz", + "integrity": "sha512-7WhJ0MdpFgYQPXlF4Dx+DhgvlPCfz/x5mHaeDQAKhcenvQP1KCpLQ18JklAqeGMYSAT2PxLpzd0g2/HE7fj7hQ==", "dev": true, "requires": { "@types/glob": "*", @@ -1562,9 +1562,9 @@ } }, "@types/tmp": { - "version": "0.0.34", - "resolved": "https://registry.npmjs.org/@types/tmp/-/tmp-0.0.34.tgz", - "integrity": "sha512-Tx7JYeYR+pkAnDQjN1Cj43KuOuUvyybZHl+fAezReXuH/SQoxLhsuPvHZH/SA4XtrBEhaTcbb5gVc1WQcjQgdg==", + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@types/tmp/-/tmp-0.2.0.tgz", + "integrity": "sha512-flgpHJjntpBAdJD43ShRosQvNC0ME97DCfGvZEDlAThQmnerRXrLbX6YgzRBQCZTthET9eAWFAMaYP0m0Y4HzQ==", "dev": true }, "@types/tough-cookie": { @@ -3634,6 +3634,16 @@ "upath": "^1.1.1" }, "dependencies": { + "fsevents": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", + "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", + "optional": true, + "requires": { + "bindings": "^1.5.0", + "nan": "^2.12.1" + } + }, "normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -6086,6 +6096,14 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "tmp": { + "version": "0.0.31", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.31.tgz", + "integrity": "sha1-jzirlDjhcxXl29izZX6L+yd65Kc=", + "requires": { + "os-tmpdir": "~1.0.1" + } } } }, @@ -6938,74 +6956,10 @@ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, "fsevents": { - "version": "1.2.11", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.11.tgz", - "integrity": "sha512-+ux3lx6peh0BpvY0JebGyZoiR4D+oYzdPZMKJwkZ+sFkNJzpL7tXc/wehS49gUAxg3tmMHPHZkA8JU2rhhgDHw==", - "optional": true, - "requires": { - "bindings": "^1.5.0", - "nan": "^2.12.1", - "node-pre-gyp": "*" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "requires": { - "ms": "^2.1.1" - } - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "requires": { - "glob": "^7.1.3" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "requires": { - "ansi-regex": "^2.0.0" - } - } - } + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", + "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "optional": true }, "fstream": { "version": "1.0.12", @@ -9052,12 +9006,6 @@ "to-regex-range": "^5.0.1" } }, - "fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", - "optional": true - }, "glob-parent": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", @@ -10254,9 +10202,9 @@ } }, "net-keepalive": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/net-keepalive/-/net-keepalive-1.3.3.tgz", - "integrity": "sha512-Qsov2o2DFY8/EHxcAIYHgvcieNwLTQsYKfdaFwTu+21lf9pCo2YLV7OmbrE9KffRlyEgRm5ixhVgmvz71Lh4Zw==", + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/net-keepalive/-/net-keepalive-1.3.6.tgz", + "integrity": "sha512-AABQ5mfFte5OprZfEPkJHVknSNAMvrkb/7BakNdUb/yF/mPhe25B6WEAI52NrNXRduSxY5Mivv4TEI4PtyGolA==", "optional": true, "requires": { "ffi-napi": "^3.0.1", @@ -10369,9 +10317,9 @@ } }, "node-gyp-build": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.2.2.tgz", - "integrity": "sha512-Lqh7mrByWCM8Cf9UPqpeoVBBo5Ugx+RKu885GAzmLBVYjeywScxHXPGLa4JfYNZmcNGwzR0Glu5/9GaQZMFqyA==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.2.3.tgz", + "integrity": "sha512-MN6ZpzmfNCRM+3t57PTJHgHyw/h4OWnZ6mR8P5j/uZtqQr46RRuDE/P+g3n0YR/AiYXeWixZZzaip77gdICfRg==", "optional": true }, "node-localstorage": { @@ -14738,11 +14686,11 @@ } }, "tmp": { - "version": "0.0.31", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.31.tgz", - "integrity": "sha1-jzirlDjhcxXl29izZX6L+yd65Kc=", + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", + "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", "requires": { - "os-tmpdir": "~1.0.1" + "rimraf": "^3.0.0" } }, "to-absolute-glob": { @@ -15789,14 +15737,22 @@ } }, "winusb-driver-generator": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/winusb-driver-generator/-/winusb-driver-generator-1.2.4.tgz", - "integrity": "sha512-fXWUGyMDGRzuncIWje1+9ObnZmok0PVb9L+Wq9nJ0ZCGVd8YHNjGJP2O6uD3jX1tJL1Us9te95Em3diMGlo0DA==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/winusb-driver-generator/-/winusb-driver-generator-1.2.7.tgz", + "integrity": "sha512-NMRpH61jvvU32kGp7TcB0uzC2vxbTNpdX8kkGn4RLafycm5bKRKNzIqinnshs8G5Z7VFAMVACaCo1uPLslT3nw==", "optional": true, "requires": { "bindings": "^1.3.0", - "nan": "^2.10.0", + "nan": "^2.14.0", "prebuild-install": "^5.2.2" + }, + "dependencies": { + "nan": { + "version": "2.14.1", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.1.tgz", + "integrity": "sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw==", + "optional": true + } } }, "with-open-file": { diff --git a/package.json b/package.json index 767d98b4..bc1a0105 100644 --- a/package.json +++ b/package.json @@ -142,14 +142,14 @@ "@types/progress-stream": "^2.0.0", "@types/request": "^2.48.4", "@types/rewire": "^2.5.28", - "@types/rimraf": "^2.0.4", + "@types/rimraf": "^3.0.0", "@types/shell-escape": "^0.2.0", "@types/sinon": "^9.0.3", "@types/split": "^1.0.0", "@types/stream-to-promise": "2.2.0", "@types/tar-stream": "^2.1.0", "@types/through2": "^2.0.34", - "@types/tmp": "0.0.34", + "@types/tmp": "^0.2.0", "@types/which": "^1.3.2", "catch-uncommitted": "^1.5.0", "chai": "^4.2.0", @@ -260,7 +260,7 @@ "tar-stream": "^2.1.0", "tar-utils": "^2.1.0", "through2": "^2.0.3", - "tmp": "0.0.31", + "tmp": "^0.2.1", "typed-error": "^3.2.0", "umount": "^1.1.6", "update-notifier": "^4.1.0",