Compare commits

...

148 Commits

Author SHA1 Message Date
3f9288e9d3 v22.1.1 2025-06-19 09:32:56 +00:00
0efa745628 Merge pull request #2957 from balena-io/truncate-error-message
Deploy: Limit the submitted error_message of images that fail to build to 300K characters
2025-06-19 09:31:58 +00:00
bddad252f7 Deploy: Limit the submitted error_message of images that fail to build to 1000 characters
Change-type: patch
See: https://balena.fibery.io/Work/Project/re-pitching-API-Limit-size-of-large-fields-975
2025-06-19 11:28:38 +03:00
a1a0e4f028 Deduplicate dependencies 2025-06-17 23:47:57 +03:00
de74baa2ff v22.1.0 2025-06-09 20:05:12 +00:00
6c12f755c5 Merge pull request #2955 from balena-io/node-22
Node 22
2025-06-09 17:04:26 -03:00
f80b8e63b1 Add support for node 22
Change-type: minor
2025-06-07 11:14:48 -03:00
b32514f5af Bump etcher-sdk to v10.0.0
Update balena-device-init from 8.1.3 to 8.1.1
Update etcher-sdk from 9.1.4 to 10.0.0
Update resin-cli-form from 3.0.0 to 4.0.0
Update resin-cli-visuals from 2.0.1 to 3.0.0

Change-type: patch
2025-06-07 11:13:55 -03:00
935f8d2549 v22.0.6 2025-06-02 12:27:13 +00:00
b2de857ef1 Merge pull request #2952 from balena-io/remove-request
Remove request
2025-06-02 08:26:26 -04:00
78f1471bf4 Deduplicate dependencies 2025-05-30 08:23:23 -04:00
d47abf072d Remove request dependency
Change-type: patch
2025-05-30 08:16:08 -04:00
8502c4db4b Replace request usage with got
Change-type: patch
2025-05-30 08:16:08 -04:00
dd2c5c40d7 v22.0.5 2025-05-29 15:47:35 +00:00
d23b253ac5 Merge pull request #2951 from balena-io/bump-etcher-sdk
Bump etcher-sdk to v9.1.4
2025-05-29 12:46:43 -03:00
0b0e24c9b2 Bump etcher-sdk to v9.1.4
Update etcher-sdk from 9.1.0 to 9.1.4

Change-type: patch
2025-05-29 10:54:45 -03:00
f9656cbe91 v22.0.4 2025-05-29 13:19:04 +00:00
e174f7db4c Merge pull request #2949 from balena-io/use-got-instead-of-request-legacy-deploy
Use got instead of request legacy deploy
2025-05-29 13:18:10 +00:00
a7a408a5c7 tests: Replace request with got
Change-type: patch
2025-05-29 09:35:57 -03:00
e5877c7de9 deploy-legacy: Replace request with got
Change-type: patch
2025-05-29 09:35:57 -03:00
ecb8b3ae6b v22.0.3 2025-05-29 12:09:59 +00:00
fd20516f69 Merge pull request #2950 from balena-io/bump-sentry-v9
Bump sentry to v9
2025-05-29 12:09:11 +00:00
5ccee0e4f1 Bump sentry to v9
Change-type: patch
2025-05-28 20:29:40 -03:00
7bb13a551c v22.0.2 2025-05-28 19:32:18 +00:00
19d287aefc Merge pull request #2948 from balena-io/build-nologs
fix: allow balena build to work with --nologs
2025-05-28 16:31:28 -03:00
8d10c1af2a Fix balena build to work with --nologs
Change-type: patch
2025-05-28 15:36:56 -03:00
ebfabdba6a v22.0.1 2025-05-28 17:00:48 +00:00
b0cbe43708 Merge pull request #2947 from balena-io/nock-14
Update `nock` to 14.0.4 & Move DeviceAPI off `request`
2025-05-28 13:59:58 -03:00
b7f1469912 Deduplicate dependencies 2025-05-28 12:08:37 -04:00
3396ba5a97 DeviceAPI: Move away from request in favor of BalenaSdk request
Change-type: patch
2025-05-28 12:08:37 -04:00
78ffff83bc Update nock to 14.0.4
Change-type: patch
2025-05-28 08:35:40 -04:00
ae13d584a3 v22.0.0 2025-05-26 13:53:39 +00:00
14f12d17eb Merge pull request #2912 from balena-io/native-build-2
Build standalone without pkg
2025-05-26 10:52:55 -03:00
45eb0ad4b1 Add migration guide to v22
Change-type: patch
2025-05-24 08:17:07 -03:00
21fd8a3307 Build standalone without pkg
Change-type: major
2025-05-23 18:52:51 -03:00
b545bd00ad v21.1.14 2025-05-21 15:39:23 +00:00
3eda7938f9 Merge pull request #2946 from balena-io/bump-balena-preload-2
Bump balena-preload to 18.0.4
2025-05-21 12:38:05 -03:00
2bccabfc38 Bump balena-preload to 18.0.4
Update balena-preload from 18.0.3 to 18.0.4

Change-type: patch
2025-05-21 11:41:07 -03:00
1b42d08567 v21.1.13 2025-05-21 13:46:34 +00:00
55b69be987 Merge pull request #2944 from balena-io/bump-balena-preload
Bump balena-preload to 18.0.3
2025-05-21 13:45:38 +00:00
7c8ce1b1a9 Bump balena-preload to 18.0.3
Update balena-preload from 18.0.1 to 18.0.3

Change-type: patch
2025-05-21 09:58:51 -03:00
31ddacec4c v21.1.12 2025-05-16 18:54:51 +00:00
dad26328b9 Merge pull request #2935 from balena-io/fix-build-secrets-serialization
Fix build secrets serialization
2025-05-16 14:54:04 -04:00
98197eef47 Dedupe dependencies 2025-05-15 19:13:36 -04:00
0f8ce47ec6 Update @balena/compose dependency to fix error with build secrets.
See https://github.com/balena-io-modules/balena-compose/pull/79

Change-type: patch
Signed-off-by: Ken Bannister <kb2ma@runbox.com>
2025-05-15 19:03:04 -04:00
33d3be326a v21.1.11 2025-05-06 15:25:00 +00:00
3eb397de1b Merge pull request #2611 from balena-io/lmb/fix-typos
Fix typos in the help messages
2025-05-06 15:24:01 +00:00
457b81a597 Deduplicate dependencies 2025-05-06 10:57:39 -04:00
8eb1777437 Fix typos in os configure and config generate help messages
Change-type: patch
2025-05-06 09:08:01 -04:00
bbc08dcfc5 v21.1.10 2025-05-05 17:13:26 +00:00
48cee061f4 Merge pull request #2937 from balena-io/fix-windows-signing
patch: fix windows signing
2025-05-05 17:12:40 +00:00
37e96e5d67 patch: fix windows signing 2025-05-05 13:38:05 -03:00
a5c865b7f9 v21.1.9 2025-04-07 12:53:22 +00:00
3fb3dd5819 Merge pull request #2929 from balena-io/update-balena-config-json
Update balena-config-json to rely on the balena-image-fs helpers
2025-04-07 15:52:21 +03:00
daf5c518fb Deduplicate dependencies 2025-04-04 10:38:24 +03:00
4fcedd0607 Update balena-config-json to rely on the balena-image-fs helpers
Update balena-config-json from 4.2.2 to 4.2.7
Update balena-image-fs from 7.5.0 to 7.5.2

Change-type: patch
2025-04-04 10:23:39 +03:00
42d9cbb48d v21.1.8 2025-04-03 16:10:05 +00:00
408efa91c1 Merge pull request #2933 from balena-io/renovate/actions-download-artifact-4.1.x
Update actions/download-artifact action to v4.1.9
2025-04-03 16:09:08 +00:00
a2209ffe56 Update actions/download-artifact action to v4.1.9
Update actions/download-artifact from 4.1.8 to 4.1.9

Change-type: patch
2025-04-03 15:50:05 +00:00
3f27db811b v21.1.7 2025-04-03 15:12:16 +00:00
839a3050fb Merge pull request #2932 from balena-io/renovate/actions-upload-artifact-digest
Update actions/upload-artifact digest to ea165f8
2025-04-03 15:11:18 +00:00
c8ea9cfcdb Update actions/upload-artifact digest to ea165f8
Update actions/upload-artifact

Change-type: patch
2025-04-03 14:50:26 +00:00
776115ef5d v21.1.6 2025-04-03 14:12:08 +00:00
f031ec1dea Merge pull request #2931 from balena-io/renovate/actions-setup-node-digest
Update actions/setup-node digest to cdca736
2025-04-03 14:11:10 +00:00
fe42438090 Update actions/setup-node digest to cdca736
Update actions/setup-node

Change-type: patch
2025-04-03 13:50:06 +00:00
b616fbdd79 v21.1.5 2025-04-03 13:28:12 +00:00
81edfbbae1 Merge pull request #2930 from balena-io/bump_dockerode_cachefrom
Update dockerode/docker-modem dependencies for cachefrom fix
2025-04-03 09:27:11 -04:00
663e83c3b8 Dedupe dependencies 2025-04-02 18:50:31 -04:00
b650f8ff6d Update dockerode/docker-modem dependencies for fixes
Change-type: patch
Signed-off-by: Ken Bannister <kb2ma@runbox.com>
2025-04-02 18:47:43 -04:00
58234f17e1 v21.1.4 2025-04-02 09:16:30 +00:00
77905f4a74 Merge pull request #2928 from balena-io/comment_sig_file
Add comment with example of signature file in a flasher image
2025-04-02 09:15:23 +00:00
30076fabe6 Dedupe dependencies 2025-04-01 18:25:20 -04:00
28703bb5ae Add comment with secure boot signature file example for preload
Change-type: patch
Signed-off-by: Ken Bannister <kb2ma@runbox.com>
2025-04-01 18:25:16 -04:00
37b3c6abe9 v21.1.3 2025-03-28 16:57:03 +00:00
b4e473e4d4 Merge pull request #2927 from balena-io/fix-ob-device-detail
Fix device detail for open balena
2025-03-28 16:55:56 +00:00
0d4e411777 Fix device detail for open balena
Change-type: patch
2025-03-28 13:29:52 -03:00
7e6f2189e8 v21.1.2 2025-03-27 12:20:26 +00:00
3903daf8a8 Merge pull request #2914 from balena-io/deny-preload-sb
Deny preload for an image with secure boot enabled
2025-03-27 08:19:14 -04:00
18bc0d61e7 Dedupe dependencies 2025-03-26 22:55:54 -04:00
7f2daeebb0 Deny preload for an image with secure boot enabled
Change-type: patch
Signed-off-by: Ken Bannister <kb2ma@runbox.com>
2025-03-26 22:40:43 -04:00
813e9cb82e v21.1.1 2025-03-26 20:34:47 +00:00
3bcb3c1b2e Merge pull request #2925 from balena-io/add-overall-status
Add overall status
2025-03-26 20:33:52 +00:00
20d76556c2 Add explicit read properties for device command
Change-tye: minor
2025-03-26 17:12:45 -03:00
e829068725 Bump balena-sdk to 21.3.0
Update balena-sdk from 21.2.1 to 21.3.0

Change-type: patch
2025-03-26 17:07:20 -03:00
650e896f70 v21.1.0 2025-03-12 19:34:20 +00:00
a9042124ea Merge pull request #2922 from balena-io/compose-requirement-labels
Add support for requirement labels feature
2025-03-12 19:33:23 +00:00
d24d78dac7 Fix package release action for macOS
Depending on the signing password value, the script may interpret the
contents of the password and cause the signing process to fail.

This puts quotes around the password on assignment to prevent this.
2025-03-12 15:30:49 -03:00
42c50ef8ae Add support for new requirement labels feature
Updates @balena/compose to v7 to include this new feature.

See: https://balena.fibery.io/Work/Project/Refactoring-container-contracts-1205
Depends-on: https://github.com/balena-io-modules/balena-compose/pull/64
Change-type: minor
2025-03-12 15:30:21 -03:00
ba4b9bd447 v21.0.0 2025-03-11 14:42:31 +00:00
02c0ea5b59 Merge pull request #2921 from balena-io/major-21-second-attempt
Major 21
2025-03-11 10:41:28 -04:00
bc3558dd8e Address SDK major v21 breaking changes 2025-03-11 08:19:10 -04:00
aad62d1ccd Drop support for OS versions <2.14.0
Change-type: major
2025-03-11 08:19:10 -04:00
ecc6f80164 api-key generate: Add required argument expiryDate
Change-type: major
2025-03-11 08:19:10 -04:00
c0fd1e3886 Deduplicate dependencies 2025-03-11 08:18:56 -04:00
9d3120b144 Update balena-preload to 18.0.1
Change-type: patch
2025-03-11 08:17:27 -04:00
ed0e03ddb2 Add dependency date-fns
Change-type: patch
2025-03-11 08:16:50 -04:00
8fe6d6c026 Update balena-sdk to 21.2.1
Change-type: patch
2025-03-11 08:16:31 -04:00
727033ae14 v20.2.10 2025-03-10 17:33:13 +00:00
c19ce6a905 Merge pull request #2923 from balena-io/bump-typescript-to-5.8.2
Bump typescript to 5.8.2
2025-03-10 17:32:13 +00:00
1a33029738 Deduplicate dependencies 2025-03-10 17:51:18 +02:00
043bc48a1c Add a "deduplicate-dependencies" npm script to standardize such commits 2025-03-04 08:48:31 +02:00
a10156a441 Update TypeScript to 5.8.2
Change-type: patch
2025-03-04 08:48:31 +02:00
4f665f43d2 v20.2.9 2025-02-26 12:52:10 +00:00
9f097a96f5 Merge pull request #2920 from balena-io/x-balena-client-fix
Fix CORS issue with X-Balena-Client header
2025-02-26 12:51:20 +00:00
64d1943804 Fix CORS issue with X-Balena-Client header
Change-type: patch
See: https://balena.fibery.io/Work/Project/Extend-the-X-Balena-Client-header-to-include-the-UI-CLI-version-as-well-1174
2025-02-26 14:24:57 +02:00
666ce876e6 v20.2.8 2025-02-26 00:22:16 +00:00
e01184080f Merge pull request #2915 from balena-io/fix_os_configure_test
Update balena-config-json dependency and fix test
2025-02-25 19:21:25 -05:00
93039b010d Update balena-config-json dependency and fix test
Change-type: patch
Signed-off-by: Ken Bannister <kb2ma@runbox.com>
2025-02-25 18:43:12 -05:00
795259bf30 v20.2.7 2025-02-25 20:21:03 +00:00
fa134d2d39 Merge pull request #2917 from balena-io/x-balena-client
Use the CLI version in the X-Balena-Client header
2025-02-25 20:20:10 +00:00
bef5221ed8 Use the CLI version in the X-Balena-Client header
Change-type: patch
See: https://balena.fibery.io/Work/Project/Extend-the-X-Balena-Client-header-to-include-the-UI-CLI-version-as-well-1174
2025-02-25 21:59:35 +02:00
72d6db796c v20.2.6 2025-02-25 19:13:51 +00:00
e848eb63ee Merge pull request #2918 from balena-io/renovate/actions-upload-artifact-digest
Update actions/upload-artifact digest to 4cec3d8
2025-02-25 19:12:56 +00:00
6f0f7350cf Update actions/upload-artifact digest to 4cec3d8
Update actions/upload-artifact

Change-type: patch
2025-02-25 18:51:27 +00:00
07a88c700e v20.2.5 2025-02-25 18:10:50 +00:00
9cae66bd92 Merge pull request #2913 from balena-io/renovate/actions-setup-node-digest
Update actions/setup-node digest to 1d0ff46
2025-02-25 18:09:54 +00:00
cddea24cef Update actions/setup-node digest to 1d0ff46
Update actions/setup-node

Change-type: patch
2025-02-25 17:45:52 +00:00
b1c246c0b4 v20.2.4 2025-02-25 17:17:03 +00:00
00b4d57a03 Merge pull request #2916 from balena-io/pin_docker-modem_regression
Pin docker-modem and dockerode to avoid regression in docker-modem v5.0.6
2025-02-25 12:16:10 -05:00
2cba82e914 Pin docker-modem and dockerode to avoid regression
Change-type: patch
Signed-off-by: Ken Bannister <kb2ma@runbox.com>
2025-02-24 20:22:59 -05:00
1352c5c823 v20.2.3 2025-01-15 18:21:09 +00:00
c86eb97010 Merge pull request #2910 from balena-io/clean-eslint
Remove unused old eslint version files
2025-01-15 18:19:22 +00:00
53be743b9d Remove unused old eslint version files
Change-type: patch
2025-01-15 08:37:35 -03:00
d9f21b4c3f v20.2.2 2025-01-12 14:49:07 +00:00
261ab398dd Merge pull request #2906 from balena-io/bump-balena-image-fs
Use the promises namespace of balena-image-fs
2025-01-12 16:48:08 +02:00
f28a9992e4 Deduplicate dependencies 2025-01-09 23:33:54 +02:00
29e7827eb1 Use the promises namespace of balena-image-fs
Change-type: patch
2025-01-09 23:33:54 +02:00
1d77cf3665 Update balena-device-init to 8.1.3 & balena-image-fs to 7.3.0
Update balena-device-init from 8.1.0 to 8.1.3
Update balena-image-fs from 7.0.6 to 7.3.0

Change-type: patch
2025-01-09 23:33:54 +02:00
017c767f61 v20.2.1 2025-01-01 18:05:02 +00:00
7d79c4e24b Merge pull request #2905 from balena-io/update-balena-preload-17.0.0
Update balena-preload to 17.0.0
2025-01-01 20:04:01 +02:00
60bc5092e0 Update balena-preload to 17.0.0
Update balena-preload from 16.0.0 to 17.0.0

Change-type: patch
2024-12-31 20:42:54 +02:00
a33a794931 v20.2.0 2024-12-31 18:41:50 +00:00
f0ede6fca2 Merge pull request #2901 from balena-io/balena-device-init-v-8-1-0
os configure: Locate the boot partition w/o using the device-type.json's partition field
2024-12-31 10:40:54 -08:00
dbe177e766 os configure: Give precedence to the boot partition located in the image over the device-type.json contents
Update balena-device-init from 8.0.0 to 8.1.0

Change-type: minor
2024-12-31 19:48:11 +02:00
09f80730a8 Deduplicate dependencies 2024-12-31 19:47:11 +02:00
327d28c103 v20.1.6 2024-12-30 17:16:14 +00:00
56ab785a82 Merge pull request #2903 from balena-io/os-configure-tests
Add more realistic os configure tests
2024-12-30 17:15:09 +00:00
305d65d5ed Add more realistic os configure tests
Change-type: patch
2024-12-30 18:44:07 +02:00
c4d3686a34 Deduplicate dependencies 2024-12-30 15:57:12 +02:00
ce06854b55 v20.1.5 2024-12-20 17:55:24 +00:00
8db05cc8a7 Merge pull request #2902 from oskarwilliams/express-version-4.21.2
Update shrinkwrapped express to v4.21.2
2024-12-20 17:54:36 +00:00
7a22c987d2 Update shrinkwrapped express to v4.21.2
Change-type: patch
2024-12-20 17:23:28 +00:00
45efbcdfe3 v20.1.4 2024-12-20 16:57:38 +00:00
d6a9b78b3e Merge pull request #2899 from balena-io/balena-device-init-v8
Update balena-device-init to 8.0.0
2024-12-20 16:56:43 +00:00
e8ac3ea960 Update balena-device-init to 8.0.0
Update balena-device-init from 7.0.1 to 8.0.0

Change-type: patch
See: https://github.com/balena-io-modules/balena-device-init/pull/46
2024-12-20 18:36:50 +02:00
0ffa0f85a2 v20.1.3 2024-12-20 14:33:05 +00:00
5e7479f60e Merge pull request #2898 from balena-io/bump-oclif-and-oclif-core
Update oclif to 4.17.0 and @oclif/core 4.1.0
2024-12-20 11:32:01 -03:00
07365c45f2 Update oclif to 4.17.0 and @oclif/core 4.1.0
Change-type: patch
2024-12-20 11:09:29 -03:00
76 changed files with 6542 additions and 5996 deletions

View File

@ -1,2 +0,0 @@
/completion/*
/bin/*

View File

@ -1,21 +0,0 @@
module.exports = {
extends: ['./node_modules/@balena/lint/config/.eslintrc.js'],
parserOptions: {
project: 'tsconfig.dev.json',
},
root: true,
rules: {
ignoreDefinitionFiles: 0,
// to avoid the `warning Forbidden non-null assertion @typescript-eslint/no-non-null-assertion`
'@typescript-eslint/no-non-null-assertion': 'off',
'@typescript-eslint/no-shadow': 'off',
'@typescript-eslint/no-var-requires': 'off',
'no-restricted-imports': [
'error',
{
paths: ['resin-cli-visuals', 'chalk', 'common-tags', 'resin-cli-form'],
},
],
'@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
},
};

View File

@ -67,7 +67,7 @@ fixed it.
- **Cloud backend: openBalena or balenaCloud?** If unsure, it will be balenaCloud
- **Operating system version:** e.g. Windows 10, Ubuntu 18.04, macOS 10.14.5
- **32/64 bit OS and processor:** e.g. 32-bit Windows on 64-bit Intel processor
- **Install method:** npm or zip package or executable installer
- **Install method:** npm or standalone package or executable installer
- **If npm install, Node.js and npm version:** e.g. Node v8.16.0 and npm v6.4.1
# Additional References

View File

@ -18,7 +18,7 @@ inputs:
default: 'accounts+apple@balena.io'
NODE_VERSION:
type: string
default: '20.x'
default: '22.x'
VERBOSE:
type: string
default: 'true'
@ -28,7 +28,7 @@ runs:
using: 'composite'
steps:
- name: Download custom source artifact
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
uses: actions/download-artifact@cc203385981b70ca67e1cc392babf9cc229d5806 # v4.1.9
with:
name: custom-${{ github.event.pull_request.head.sha || github.event.head_commit.id }}-${{ runner.os }}-${{ runner.arch }}
path: ${{ runner.temp }}
@ -39,7 +39,7 @@ runs:
run: tar -xf ${{ runner.temp }}/custom.tgz
- name: Setup Node.js
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4
uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e # v4
with:
node-version: ${{ inputs.NODE_VERSION }}
cache: npm
@ -48,7 +48,7 @@ runs:
if: runner.os == 'macOS'
uses: actions/setup-python@65d7f2d534ac1bc67fcd62888c5f4f3d2cb2b236 # v4
with:
python-version: "3.11"
python-version: '3.11'
- name: Install additional tools
if: runner.os == 'Windows'
@ -94,7 +94,7 @@ runs:
runner_arch="$(echo "${RUNNER_ARCH}" | tr '[:upper:]' '[:lower:]')"
if [[ $runner_os =~ darwin|macos|osx ]]; then
CSC_KEY_PASSWORD=${{ fromJSON(inputs.secrets).APPLE_SIGNING_PASSWORD }}
CSC_KEY_PASSWORD='${{ fromJSON(inputs.secrets).APPLE_SIGNING_PASSWORD }}'
CSC_KEYCHAIN=signing_temp
CSC_LINK=${{ fromJSON(inputs.secrets).APPLE_SIGNING }}
@ -112,8 +112,8 @@ runs:
PATH="/c/Program Files/DigiCert/DigiCert One Signing Manager Tools:${PATH}"
smksp_registrar.exe list
smctl.exe keypair ls
smctl.exe windows certsync
/c/Windows/System32/certutil.exe -csp "DigiCert Signing Manager KSP" -key -user
smksp_cert_sync.exe
# (signtool.exe) https://github.com/actions/runner-images/blob/main/images/win/Windows2019-Readme.md#installed-windows-sdks
PATH="/c/Program Files (x86)/Windows Kits/10/bin/${runner_arch}:${PATH}"
@ -135,9 +135,11 @@ runs:
XCODE_APP_LOADER_TEAM_ID: ${{ inputs.XCODE_APP_LOADER_TEAM_ID }}
- name: Upload artifacts
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: gh-release-${{ github.event.pull_request.head.sha || github.event.head_commit.id }}-${{ strategy.job-index }}
path: dist
path: |
dist
!dist/balena
retention-days: 1
if-no-files-found: error

View File

@ -15,7 +15,7 @@ inputs:
# --- custom environment
NODE_VERSION:
type: string
default: '20.x'
default: '22.x'
VERBOSE:
type: string
default: "true"
@ -26,7 +26,7 @@ runs:
steps:
# https://github.com/actions/setup-node#caching-global-packages-data
- name: Setup Node.js
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4
uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e # v4
with:
node-version: ${{ inputs.NODE_VERSION }}
cache: npm
@ -58,7 +58,7 @@ runs:
run: tar --exclude-vcs -acf ${{ runner.temp }}/custom.tgz .
- name: Upload custom artifact
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: custom-${{ github.event.pull_request.head.sha || github.event.head_commit.id }}-${{ runner.os }}-${{ runner.arch }}
path: ${{ runner.temp }}/custom.tgz

View File

@ -2,7 +2,7 @@ module.exports = {
reporter: 'spec',
require: 'ts-node/register/transpile-only',
file: './tests/config-tests',
timeout: 12000,
timeout: 48000,
// To test only, say, 'push.spec.ts', do it as follows so that
// requests are authenticated:
// spec: ['tests/auth/*.spec.ts', 'tests/**/deploy.spec.ts'],

File diff suppressed because it is too large Load Diff

View File

@ -4,6 +4,420 @@ All notable changes to this project will be documented in this file
automatically by Versionist. DO NOT EDIT THIS FILE MANUALLY!
This project adheres to [Semantic Versioning](http://semver.org/).
## 22.1.1 - 2025-06-19
* Deploy: Limit the submitted error_message of images that fail to build to 1000 characters [Thodoris Greasidis]
## 22.1.0 - 2025-06-09
* Add support for node 22 [Otavio Jacobi]
<details>
<summary> Bump etcher-sdk to v10.0.0 [Otavio Jacobi] </summary>
> ### etcher-sdk-10.0.0 - 2025-06-02
>
> * Drop support to node18 and add support to node 22 & 24 [Otavio Jacobi]
>
</details>
## 22.0.6 - 2025-06-02
* Remove `request` dependency [myarmolinsky]
* Replace `request` usage with `got` [myarmolinsky]
## 22.0.5 - 2025-05-29
<details>
<summary> Bump etcher-sdk to v9.1.4 [Otavio Jacobi] </summary>
> ### etcher-sdk-9.1.4 - 2025-05-29
>
> * Run `npm audit fix` which should only do non-breaking changes [Otavio Jacobi]
>
> ### etcher-sdk-9.1.3 - 2025-02-17
>
> * Embed config.json with a fixed timestamp to enable consistent checksums [Pagan Gazzard]
>
> ### etcher-sdk-9.1.2 - 2024-10-09
>
> * Update dependency unzip-stream to v0.3.2 [SECURITY] [Self-hosted Renovate Bot]
>
> ### etcher-sdk-9.1.1 - 2024-10-09
>
> * patch: add EXLOCK flag for windows [Talha Can Havadar]
>
</details>
## 22.0.4 - 2025-05-29
* tests: Replace request with got [Otavio Jacobi]
* deploy-legacy: Replace request with got [Otavio Jacobi]
## 22.0.3 - 2025-05-29
* Bump sentry to v9 [Otavio Jacobi]
## 22.0.2 - 2025-05-28
* Fix balena build to work with --nologs [Otavio Jacobi]
## 22.0.1 - 2025-05-28
* DeviceAPI: Move away from `request` in favor of BalenaSdk request [myarmolinsky]
* Update `nock` to 14.0.4 [myarmolinsky]
## 22.0.0 - 2025-05-26
* Add migration guide to v22 [Otavio Jacobi]
* Build standalone without pkg [Otavio Jacobi]
## 21.1.14 - 2025-05-21
<details>
<summary> Bump balena-preload to 18.0.4 [Otavio Jacobi] </summary>
> ### balena-preload-18.0.4 - 2025-05-21
>
> * Fix balena-preload pip deps [Otavio Jacobi]
>
</details>
## 21.1.13 - 2025-05-21
<details>
<summary> Bump balena-preload to 18.0.3 [Otavio Jacobi] </summary>
> ### balena-preload-18.0.3 - 2025-03-19
>
> * Update dependency sh to v1.14.3 [balena-renovate[bot]]
>
> ### balena-preload-18.0.2 - 2025-03-19
>
> * Update alpine Docker tag to v3.21 [balena-renovate[bot]]
>
</details>
## 21.1.12 - 2025-05-16
* Update @balena/compose dependency to fix error with build secrets. [Ken Bannister]
## 21.1.11 - 2025-05-06
* Fix typos in `os configure` and `config generate` help messages [myarmolinsky]
## 21.1.10 - 2025-05-05
* patch: fix windows signing [Edwin Joassart]
## 21.1.9 - 2025-04-07
<details>
<summary> Update balena-config-json to rely on the balena-image-fs helpers [Thodoris Greasidis] </summary>
> ### balena-config-json-4.2.7 - 2025-04-02
>
> * Fix getBootPartition always warning that the boot partitions were not found [Thodoris Greasidis]
>
> ### balena-config-json-4.2.6 - 2025-04-01
>
> * write: Allow undefined as a value for the deprecated type parameter [Thodoris Greasidis]
>
> <details>
> <summary> Use the balena-image-fs findPartition() helper to find the boot partition [Thodoris Greasidis] </summary>
>
>> #### balena-image-fs-7.5.0 - 2025-03-26
>>
>> * Add function to find a partition by name/label [Ken Bannister]
>>
>> #### balena-image-fs-7.4.1 - 2025-02-21
>>
>> * bump ext2fs to 4.2.4 [Ryan Cooke]
>>
>
> </details>
>
>
> ### balena-config-json-4.2.5 - 2025-03-26
>
> * Update @balena/lint to 9.1.4 [Thodoris Greasidis]
>
> ### balena-config-json-4.2.4 - 2025-03-26
>
> * Switch use ts-mocha instead of manually compiling the tests [Thodoris Greasidis]
> * Update TypeScript to 5.8.2 [Thodoris Greasidis]
>
> ### balena-config-json-4.2.3 - 2025-03-26
>
> * Update chai to v5 [balena-renovate[bot]]
>
> ### balena-image-fs-7.5.2 - 2025-04-02
>
> * Update dependency jsdoc-to-markdown to v9 [balena-renovate[bot]]
>
> ### balena-image-fs-7.5.1 - 2025-03-26
>
> * Update @balena/lint to v9 [Thodoris Greasidis]
> * Remove the no longer needed gpt detection helper [Thodoris Greasidis]
> * Update TypeScript to 5.8.2 [Thodoris Greasidis]
> * Drop the package-lock.json [Thodoris Greasidis]
>
</details>
## 21.1.8 - 2025-04-03
* Update actions/download-artifact action to v4.1.9 [balena-renovate[bot]]
## 21.1.7 - 2025-04-03
* Update actions/upload-artifact digest to ea165f8 [balena-renovate[bot]]
## 21.1.6 - 2025-04-03
* Update actions/setup-node digest to cdca736 [balena-renovate[bot]]
## 21.1.5 - 2025-04-03
* Update dockerode/docker-modem dependencies for fixes [Ken Bannister]
## 21.1.4 - 2025-04-02
* Add comment with secure boot signature file example for preload [Ken Bannister]
## 21.1.3 - 2025-03-28
* Fix device detail for open balena [Otavio Jacobi]
## 21.1.2 - 2025-03-27
* Deny preload for an image with secure boot enabled [Ken Bannister]
## 21.1.1 - 2025-03-26
<details>
<summary> Bump balena-sdk to 21.3.0 [Otavio Jacobi] </summary>
> ### balena-sdk-21.3.0 - 2025-03-26
>
> * device: add `changed_api_heartbeat_state_on__date` to typings [Otavio Jacobi]
>
> ### balena-sdk-21.2.2 - 2025-03-26
>
> * fix linting [Otavio Jacobi]
>
</details>
## 21.1.0 - 2025-03-12
* Add support for new requirement labels feature [Felipe Lalanne]
## 21.0.0 - 2025-03-11
* Drop support for OS versions <2.14.0 [myarmolinsky]
* api-key generate: Add required argument `expiryDate` [myarmolinsky]
* Update `balena-preload` to 18.0.1 [myarmolinsky]
* Add dependency `date-fns` [myarmolinsky]
* Update `balena-sdk` to 21.2.1 [myarmolinsky]
## 20.2.10 - 2025-03-10
* Update TypeScript to 5.8.2 [Thodoris Greasidis]
## 20.2.9 - 2025-02-26
* Fix CORS issue with X-Balena-Client header [Thodoris Greasidis]
## 20.2.8 - 2025-02-26
* Update balena-config-json dependency and fix test [Ken Bannister]
## 20.2.7 - 2025-02-25
* Use the CLI version in the X-Balena-Client header [Thodoris Greasidis]
## 20.2.6 - 2025-02-25
* Update actions/upload-artifact digest to 4cec3d8 [balena-renovate[bot]]
## 20.2.5 - 2025-02-25
* Update actions/setup-node digest to 1d0ff46 [balena-renovate[bot]]
## 20.2.4 - 2025-02-25
* Pin docker-modem and dockerode to avoid regression [Ken Bannister]
## 20.2.3 - 2025-01-15
* Remove unused old eslint version files [Otavio Jacobi]
## 20.2.2 - 2025-01-12
* Use the promises namespace of balena-image-fs [Thodoris Greasidis]
<details>
<summary> Update balena-device-init to 8.1.3 & balena-image-fs to 7.3.0 [Thodoris Greasidis] </summary>
> ### balena-image-fs-7.3.0 - 2025-01-06
>
> * Drop Bluebird from devDependencies [Thodoris Greasidis]
> * flowzone: Remove empty with clause [Thodoris Greasidis]
> * Add the promises namespace as part of the exposed fs [Thodoris Greasidis]
>
> ### balena-image-fs-7.2.2 - 2024-01-02
>
> * Update dependency @types/node to v20 [Self-hosted Renovate Bot]
>
> ### balena-image-fs-7.2.1 - 2023-12-19
>
> * Remove repo config from flowzone.yml [Kyle Harding]
>
> ### balena-image-fs-7.2.0 - 2023-01-20
>
> * Add support for Node 18 [Akis Kesoglou]
>
> ### balena-image-fs-7.1.2 - 2023-01-05
>
> * Update dependencies [ab77]
>
> ### balena-image-fs-7.1.1 - 2022-12-20
>
> * Update dependency jsdoc-to-markdown to 8.0.0 [Renovate Bot]
>
> ### balena-image-fs-7.1.0 - 2022-12-13
>
> * update dependencies [Zane Hitchcox]
>
> ### balena-device-init-8.1.3 - 2025-01-09
>
> * README: Remove the travisci badge [Thodoris Greasidis]
>
> ### balena-device-init-8.1.2 - 2025-01-09
>
>
> <details>
> <summary> Use the promises namespace of balena-image-fs [Thodoris Greasidis] </summary>
>
>> #### balena-image-fs-7.3.0 - 2025-01-06
>>
>> * Drop Bluebird from devDependencies [Thodoris Greasidis]
>> * flowzone: Remove empty with clause [Thodoris Greasidis]
>> * Add the promises namespace as part of the exposed fs [Thodoris Greasidis]
>>
>> #### balena-image-fs-7.2.2 - 2024-01-02
>>
>> * Update dependency @types/node to v20 [Self-hosted Renovate Bot]
>>
>> #### balena-image-fs-7.2.1 - 2023-12-19
>>
>> * Remove repo config from flowzone.yml [Kyle Harding]
>>
>> #### balena-image-fs-7.2.0 - 2023-01-20
>>
>> * Add support for Node 18 [Akis Kesoglou]
>>
>> #### balena-image-fs-7.1.2 - 2023-01-05
>>
>> * Update dependencies [ab77]
>>
>> #### balena-image-fs-7.1.1 - 2022-12-20
>>
>> * Update dependency jsdoc-to-markdown to 8.0.0 [Renovate Bot]
>>
>> #### balena-image-fs-7.1.0 - 2022-12-13
>>
>> * update dependencies [Zane Hitchcox]
>>
>
> </details>
>
>
> ### balena-device-init-8.1.1 - 2025-01-06
>
> * Convert some parts to async await and simplify [Thodoris Greasidis]
> * Avoid unnecessary destructuring [Thodoris Greasidis]
>
</details>
## 20.2.1 - 2025-01-01
<details>
<summary> Update balena-preload to 17.0.0 [Thodoris Greasidis] </summary>
> ### balena-preload-17.0.0 - 2024-10-21
>
> * Improve typings [Thodoris Greasidis]
> * Stop returning Bluebird promises & drop it from the dependencies [Thodoris Greasidis]
>
</details>
## 20.2.0 - 2024-12-31
<details>
<summary> os configure: Give precedence to the boot partition located in the image over the device-type.json contents [Thodoris Greasidis] </summary>
> ### balena-device-init-8.1.0 - Invalid date
>
> * Try to find the boot partition by inspecting the image [Thodoris Greasidis]
>
> ### balena-device-init-8.0.1 - 2024-12-19
>
> * Drop the unnecessary eslint.config.js [Thodoris Greasidis]
> * packacke.json: Explicitly set type commonjs [Thodoris Greasidis]
>
</details>
## 20.1.6 - 2024-12-30
* Add more realistic os configure tests [Thodoris Greasidis]
## 20.1.5 - 2024-12-20
* Update shrinkwrapped express to v4.21.2 [Oskar Williams]
## 20.1.4 - 2024-12-20
<details>
<summary> Update balena-device-init to 8.0.0 [Thodoris Greasidis] </summary>
> ### balena-device-init-8.0.0 - 2024-12-18
>
> * Avoid running linting in the custom tests [Thodoris Greasidis]
> * Stop returning Bluebird promises [Thodoris Greasidis]
> * package: Publish only the build & typings folders [Thodoris Greasidis]
> * Convert to TypeScript with es6 module notation [Thodoris Greasidis]
> * Replace gulp, coffeelint & mochainon with tsc, @balena/lint, mocha, chai & sinon [Thodoris Greasidis]
> * Drop support for node <20.6.0 [Thodoris Greasidis]
>
> ### balena-device-init-7.0.2 - 2024-12-17
>
> * flowzone: Update runner versions [Thodoris Greasidis]
> * Pin etcher-sdk to 9.0.8 to match resin-device-operations and fix tests [Thodoris Greasidis]
>
</details>
## 20.1.3 - 2024-12-20
* Update oclif to 4.17.0 and @oclif/core 4.1.0 [Otavio Jacobi]
## 20.1.2 - 2024-12-17
* Remove unnecessary `Promise.resolve` and `Promise.reject` [Pagan Gazzard]

View File

@ -14,7 +14,7 @@ The balena CLI is an open source project and your contribution is welcome!
In order to ease development:
* `npm run build:fast` skips some of the build steps for interactive testing, or
* `npm run test:source` skips testing the standalone zip packages (which is rather slow)
* `npm run test:source` skips testing the standalone packages (which is rather slow)
* `./bin/balena-dev` uses `ts-node/register` to transpile on the fly.
Before opening a PR, test your changes with `npm test`. Keep compatibility in mind, as the CLI is

View File

@ -8,8 +8,8 @@ There are 3 options to choose from to install balena's CLI:
* [Executable Installer](#executable-installer): the easiest method on Windows and macOS, using the
traditional graphical desktop application installers.
* [Standalone Zip Package](#standalone-zip-package): these are plain zip files with the balena CLI
executable in them: extract and run. Available for all platforms: Linux, Windows, macOS.
* [Standalone tar.gz Package](#standalone-targz-package): these are plain tar.gz files with the balena CLI
bundled within. Available for all platforms: Linux, Windows, macOS.
Recommended also for scripted installation in CI (continuous integration) environments.
* [NPM Installation](#npm-installation): recommended for Node.js developers who may be interested
in integrating the balena CLI in their existing projects or workflow.
@ -30,9 +30,9 @@ instructions:
> If you would like to use WSL, follow the [installations instructions for
> Linux](./INSTALL-LINUX.md) rather than Windows, as WSL consists of a Linux environment.
If you had previously installed the CLI using a standalone zip package, it may be a good idea to
If you had previously installed the CLI using a standalone tar package, it may be a good idea to
check your system's `PATH` environment variable for duplicate entries, as the terminal will use the
entry that comes first. Check the [Standalone Zip Package](#standalone-zip-package) instructions
entry that comes first. Check the [Standalone tar.gz Package](#standalone-targz-package) instructions
for how to modify the PATH variable.
By default, the CLI is installed to the following folders:
@ -42,18 +42,17 @@ OS | Folders
Windows: | `C:\Program Files\balena-cli\`
macOS: | `/usr/local/src/balena-cli/` <br> `/usr/local/bin/balena`
## Standalone Zip Package
## Standalone tar.gz Package
1. Download the latest zip file from the [releases page](https://github.com/balena-io/balena-cli/releases).
1. Download the latest tar.gz file from the [releases page](https://github.com/balena-io/balena-cli/releases).
Look for a file name that ends with the word "standalone", for example:
`balena-cli-vX.Y.Z-linux-x64-standalone.zip`_also for the Windows Subsystem for Linux_
`balena-cli-vX.Y.Z-macOS-x64-standalone.zip`
`balena-cli-vX.Y.Z-windows-x64-standalone.zip`
`balena-cli-vX.Y.Z-linux-x64-standalone.tar.gz`_also for the Windows Subsystem for Linux_
`balena-cli-vX.Y.Z-macOS-x64-standalone.tar.gz`
`balena-cli-vX.Y.Z-windows-x64-standalone.tar.gz`
2. Extract the zip file contents to any folder you choose. The extracted contents will include a
`balena-cli` folder.
2. Extract the tar.gz file contents to any folder you choose. The extracted contents will be a `balena` folder containing a `bin` subdirectory.
3. Add the `balena-cli` folder to the system's `PATH` environment variable.
3. Add the `balena/bin` folder to the system's `PATH` environment variable.
See instructions for:
[Linux](https://stackoverflow.com/questions/14637979/how-to-permanently-set-path-on-linux-unix) |
[macOS](https://www.architectryan.com/2012/10/02/add-to-the-path-on-mac-os-x-mountain-lion/#.Uydjga1dXDg) |
@ -61,14 +60,14 @@ macOS: | `/usr/local/src/balena-cli/` <br> `/usr/local/bin/balena`
> * If you are using macOS 10.15 or later (Catalina, Big Sur), [check this known issue and
> workaround](https://github.com/balena-io/balena-cli/issues/2244).
> * **Linux Alpine** and **Busybox:** the standalone zip package is not currently compatible with
> * **Linux Alpine** and **Busybox:** the standalone tar.gz package is not currently compatible with
> these "compact" Linux distributions, because of the alternative C libraries they ship with.
> For these, consider the [NPM Installation](#npm-installation) option.
> * Note that moving the `balena` executable out of the extracted `balena-cli` folder on its own
> * Note that moving the `balena/bin/balena` executable out of the extracted `balena` folder on its own
> (e.g. moving it to `/usr/local/bin/balena`) will **not** work, as it depends on the other
> folders and files also present in the `balena-cli` folder.
> folders and files also present in the `balena` folder.
To update the CLI to a new version, download a new release zip file and replace the previous
To update the CLI to a new version, download a new release tar.gz file and replace the previous
installation folder. To uninstall, simply delete the folder and edit the PATH environment variable
as described above.
@ -78,8 +77,8 @@ If you are a Node.js developer, you may wish to install the balena CLI via [npm]
The npm installation involves building native (platform-specific) binary modules, which require
some development tools to be installed first, as follows.
> **The balena CLI currently requires Node.js version ^20.6.0**
> **Versions 21 and later are not yet fully supported.**
> **The balena CLI currently requires Node.js version >=20.6.0**
> **Versions 23 and later are not yet fully supported.**
### Install development tools
@ -89,7 +88,7 @@ some development tools to be installed first, as follows.
$ sudo apt-get update && sudo apt-get -y install curl python3 git make g++
$ curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.38.0/install.sh | bash
$ . ~/.bashrc
$ nvm install 20
$ nvm install 22
```
The `curl` command line above uses
@ -106,7 +105,7 @@ recommended.
```sh
$ curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.38.0/install.sh | bash
$ . ~/.bashrc
$ nvm install 20
$ nvm install 22
```
#### **Windows** (not WSL)
@ -114,7 +113,7 @@ $ nvm install 20
Install:
* If you'd like the ability to switch between Node.js versions, install
- Node.js v20 from the [Nodejs.org releases page](https://nodejs.org/en/download/releases/).
- Node.js v22 from the [Nodejs.org releases page](https://nodejs.org/en/download/releases/).
[nvm-windows](https://github.com/coreybutler/nvm-windows#node-version-manager-nvm-for-windows)
instead.
* The [MSYS2 shell](https://www.msys2.org/), which provides `git`, `make`, `g++` and more:

View File

@ -8,15 +8,15 @@ method.
Selected operating system: **Linux**
1. Download the latest zip file from the [latest release
1. Download the latest tar.gz file from the [latest release
page](https://github.com/balena-io/balena-cli/releases/latest). Look for a file name that ends
with "-standalone.zip", for example:
`balena-cli-vX.Y.Z-linux-x64-standalone.zip`
with "-standalone.tar.gz", for example:
`balena-cli-vX.Y.Z-linux-x64-standalone.tar.gz`
2. Extract the zip file contents to any folder you choose, for example `/home/james`.
The extracted contents will include a `balena-cli` folder.
2. Extract the tar.gz file contents to any folder you choose, for example `/home/james`.
The extracted contents will include a `balena/bin` folder.
3. Add that folder (e.g. `/home/james/balena-cli`) to the `PATH` environment variable.
3. Add that folder (e.g. `/home/james/balena/bin`) to the `PATH` environment variable.
Check this [StackOverflow
post](https://stackoverflow.com/questions/14637979/how-to-permanently-set-path-on-linux-unix)
for instructions. Close and reopen the terminal window so that the changes to `PATH`
@ -27,7 +27,7 @@ Selected operating system: **Linux**
* `balena version` - should print the CLI's version
* `balena help` - should print a list of available commands
To update the balena CLI to a new version, download a new release zip file and replace the previous
To update the balena CLI to a new version, download a new release tar.gz file and replace the previous
installation folder. To uninstall, simply delete the folder and edit the PATH environment variable
as described above.

View File

@ -7,8 +7,8 @@ Selected operating system: **macOS**
1. Download the installer from the [latest release
page](https://github.com/balena-io/balena-cli/releases/latest).
Look for a file name that ends with "-installer.pkg":
`balena-cli-vX.Y.Z-macOS-x64-installer.pkg`
Look for a file name that ends with "-installer.pkg":
`balena-cli-vX.Y.Z-macOS-x64-installer.pkg`
2. Double click on the downloaded file to run the installer and follow the installer's
instructions.

View File

@ -8,7 +8,7 @@ Selected operating system: **Windows**
1. Download the installer from the [latest release
page](https://github.com/balena-io/balena-cli/releases/latest).
Look for a file name that ends with "-installer.exe":
`balena-cli-vX.Y.Z-windows-x64-installer.exe`
`balena-cli-vX.Y.Z-windows-x64-installer.exe`
2. Double click on the downloaded file to run the installer and follow the installer's
instructions.

45
MIGRATIONS.md Normal file
View File

@ -0,0 +1,45 @@
## Migrating to balena CLI v22
This guide outlines the changes introduced in balena CLI v22 and provides instructions for when and how to migrate.
---
### For Installer Users (Windows .exe, macOS .pkg)
If you are using the Windows executable (.exe) or macOS package (.pkg) installers, **no changes** are required for this update. You can continue to use the installers as before.
---
### For npm Installation Users
If you installed balena CLI via npm, **no changes** are required for this update. Your existing installation and update process remains the same.
---
### For Standalone Installation Users
Users of the standalone balena CLI will need to make the following adjustments:
1. **Archive Format Change**: The distribution archive format has changed from `.zip` to `.tar.gz`. You will need to use the `tar` command instead of `unzip` to extract the CLI.
* **Previous command (v21.x.x and older):**
```bash
unzip balena-cli-v21.1.12-linux-x64-standalone.zip
```
* **New command (v22.0.0 and newer):**
```bash
tar -xzf balena-cli-v22.0.0-linux-x64-standalone.tar.gz
```
2. **Executable Path Change**: The path to the balena CLI executable within the extracted folder has been updated.
* **Previous path (v21.x.x and older):**
```
balena-cli/balena
```
* **New path (v22.0.0 and newer):**
```
balena/bin/balena
```
Please update your scripts and any aliases to reflect these changes if you are using the standalone version.

View File

@ -20,6 +20,8 @@ GitHub](https://github.com/balena-io/balena-cli/), and your contribution is also
Check the [balena CLI installation instructions on
GitHub](https://github.com/balena-io/balena-cli/blob/master/INSTALL.md).
Note for v22 Migration: If you are upgrading to balena CLI v22 from a previous standalone installation, please [see the v22 Migration Guide](https://github.com/balena-io/balena-cli/blob/master/MIGRATIONS.md) for installation changes.
## Choosing a shell (command prompt/terminal)
On **Windows,** the standard Command Prompt (`cmd.exe`) and

View File

@ -115,7 +115,7 @@ If nothing seems to help, consider also using a different client-side terminal a
## "Docker seems to be unavailable" error when using Windows Subsystem for Linux (WSL)
When running on WSL, the recommendation is to install a CLI release for Linux, like the standalone
zip package for Linux. However, commands like "balena build" will, by default, attempt to reach the
tar.gz package for Linux. However, commands like "balena build" will, by default, attempt to reach the
Docker daemon at the Unix socket path `/var/run/docker.sock`, while Docker Desktop for Windows uses
a Windows named pipe at `//./pipe/docker_engine` (which the Linux CLI on WSL cannot use). A
solution is:

View File

@ -15,29 +15,17 @@
* limitations under the License.
*/
import type { JsonVersions } from '../src/commands/version/index';
import { run as oclifRun } from '@oclif/core';
import * as archiver from 'archiver';
import { exec, execFile } from 'child_process';
import * as filehound from 'filehound';
import type { Stats } from 'fs';
import * as fs from 'fs-extra';
import * as klaw from 'klaw';
import * as path from 'path';
import * as rimraf from 'rimraf';
import * as semver from 'semver';
import { promisify } from 'util';
import { notarize } from '@electron/notarize';
import { stripIndent } from '../build/utils/lazy';
import {
diffLines,
loadPackageJson,
ROOT,
StdOutTap,
whichSpawn,
} from './utils';
import { loadPackageJson, ROOT, whichSpawn } from './utils';
const execFileAsync = promisify(execFile);
const execAsync = promisify(exec);
@ -55,12 +43,6 @@ interface PathByPlatform {
[platform: string]: string;
}
const standaloneZips: PathByPlatform = {
linux: dPath(`balena-cli-${version}-linux-${arch}-standalone.zip`),
darwin: dPath(`balena-cli-${version}-macOS-${arch}-standalone.zip`),
win32: dPath(`balena-cli-${version}-windows-${arch}-standalone.zip`),
};
const getOclifInstallersOriginalNames = async (): Promise<PathByPlatform> => {
const { stdout } = await execAsync('git rev-parse --short HEAD');
const sha = stdout.trim();
@ -75,260 +57,28 @@ const renamedOclifInstallers: PathByPlatform = {
win32: dPath(`balena-cli-${version}-windows-${arch}-installer.exe`),
};
export const finalReleaseAssets: { [platform: string]: string[] } = {
win32: [standaloneZips['win32'], renamedOclifInstallers['win32']],
darwin: [standaloneZips['darwin'], renamedOclifInstallers['darwin']],
linux: [standaloneZips['linux']],
const getOclifStandaloneOriginalNames = async (): Promise<PathByPlatform> => {
const { stdout } = await execAsync('git rev-parse --short HEAD');
const sha = stdout.trim();
return {
linux: dPath(`balena-${version}-${sha}-linux-${arch}.tar.gz`),
darwin: dPath(`balena-${version}-${sha}-darwin-${arch}.tar.gz`),
win32: dPath(`balena-${version}-${sha}-win32-${arch}.tar.gz`),
};
};
/**
* Given the output of `pkg` as a string (containing warning messages),
* diff it against previously saved output of known "safe" warnings.
* Throw an error if the diff is not empty.
*/
async function diffPkgOutput(pkgOut: string) {
const { monochrome } = await import('../tests/helpers');
const relSavedPath = path.join(
'tests',
'test-data',
'pkg',
`expected-warnings-${process.platform}-${arch}.txt`,
);
const absSavedPath = path.join(ROOT, relSavedPath);
const ignoreStartsWith = [
'> pkg@',
'> Fetching base Node.js binaries',
' fetched-',
'prebuild-install WARN install No prebuilt binaries found',
];
const modulesRE =
process.platform === 'win32'
? /(?<=[ '])([A-Z]:)?\\.+?\\node_modules(?=\\)/
: /(?<=[ '])\/.+?\/node_modules(?=\/)/;
const buildRE =
process.platform === 'win32'
? /(?<=[ '])([A-Z]:)?\\.+\\build(?=\\)/
: /(?<=[ '])\/.+\/build(?=\/)/;
const cleanLines = (chunks: string | string[]) => {
const lines = typeof chunks === 'string' ? chunks.split('\n') : chunks;
return lines
.map((line: string) => monochrome(line)) // remove ASCII colors
.filter((line: string) => !/^\s*$/.test(line)) // blank lines
.filter((line: string) =>
ignoreStartsWith.every((i) => !line.startsWith(i)),
)
.map((line: string) => {
// replace absolute paths with relative paths
let replaced = line.replace(modulesRE, 'node_modules');
if (replaced === line) {
replaced = line.replace(buildRE, 'build');
}
return replaced;
});
};
pkgOut = cleanLines(pkgOut).join('\n');
const { readFile } = (await import('fs')).promises;
const expectedOut = cleanLines(await readFile(absSavedPath, 'utf8')).join(
'\n',
);
if (expectedOut !== pkgOut) {
const sep =
'================================================================================';
const diff = diffLines(expectedOut, pkgOut);
const msg = `pkg output does not match expected output from "${relSavedPath}"
Diff:
${sep}
${diff}
${sep}
Check whether the new or changed pkg warnings are safe to ignore, then update
"${relSavedPath}"
and share the result of your investigation as comments on the pull request.
Hint: the fix is often a matter of updating the 'pkg.scripts' or 'pkg.assets'
sections in the CLI's 'package.json' file, or a matter of updating the
'buildPkg' function in 'automation/build-bin.ts'. Sometimes it requires
patching dependencies: See for example 'patches/all/open+7.0.2.patch'.
${sep}
`;
throw new Error(msg);
}
}
/**
* Call `pkg.exec` to generate the standalone zip file, capturing its warning
* messages (stdout and stderr) in order to call diffPkgOutput().
*/
async function execPkg(...args: any[]) {
const { exec: pkgExec } = await import('@yao-pkg/pkg');
const outTap = new StdOutTap(true);
try {
outTap.tap();
await (pkgExec as any)(...args);
} catch (err) {
outTap.untap();
console.log(outTap.stdoutBuf.join(''));
console.error(outTap.stderrBuf.join(''));
throw err;
}
outTap.untap();
await diffPkgOutput(outTap.allBuf.join(''));
}
/**
* Use the 'pkg' module to create a single large executable file with
* the contents of 'node_modules' and the CLI's javascript code.
* Also copy a number of native modules (binary '.node' files) that are
* compiled during 'npm install' to the 'build-bin' folder, alongside
* the single large executable file created by pkg. (This is necessary
* because of a pkg limitation that does not allow binary executables
* to be directly executed from inside another binary executable.)
*/
async function buildPkg() {
// https://github.com/vercel/pkg#targets
let targets = `linux-${arch}`;
if (process.platform === 'darwin') {
targets = `macos-${arch}`;
}
// TBC: not yet possible to build for Windows arm64 on x64 nodes
if (process.platform === 'win32') {
targets = `win-x64`;
}
const args = [
'--targets',
targets,
'--output',
'build-bin/balena',
'package.json',
];
console.log('=======================================================');
console.log(`execPkg ${args.join(' ')}`);
console.log(`cwd="${process.cwd()}" ROOT="${ROOT}"`);
console.log('=======================================================');
await execPkg(args);
const paths: Array<[string, string[], string[]]> = [
// [platform, [source path], [destination path]]
['*', ['open', 'xdg-open'], ['xdg-open']],
['darwin', ['denymount', 'bin', 'denymount'], ['denymount']],
];
await Promise.all(
paths.map(([platform, source, dest]) => {
if (platform === '*' || platform === process.platform) {
// eg copy from node_modules/open/xdg-open to build-bin/xdg-open
return fs.copy(
path.join(ROOT, 'node_modules', ...source),
path.join(ROOT, 'build-bin', ...dest),
);
}
}),
);
const nativeExtensionPaths: string[] = await filehound
.create()
.paths(path.join(ROOT, 'node_modules'))
.ext(['node', 'dll'])
.find();
console.log(`\nCopying to build-bin:\n${nativeExtensionPaths.join('\n')}`);
await Promise.all(
nativeExtensionPaths.map((extPath) =>
fs.copy(
extPath,
extPath.replace(
path.join(ROOT, 'node_modules'),
path.join(ROOT, 'build-bin'),
),
),
),
);
}
/**
* Run some basic tests on the built pkg executable.
* TODO: test more than just `balena version -j`; integrate with the
* existing mocha/chai CLI command testing.
*/
async function testPkg() {
const pkgBalenaPath = path.join(
ROOT,
'build-bin',
process.platform === 'win32' ? 'balena.exe' : 'balena',
);
console.log(`Testing standalone package "${pkgBalenaPath}"...`);
// Run `balena version -j`, parse its stdout as JSON, and check that the
// reported Node.js major version matches semver.major(process.version)
let { stdout, stderr } = await execFileAsync(pkgBalenaPath, [
'version',
'-j',
]);
const { filterCliOutputForTests } = await import('../tests/helpers');
const filtered = filterCliOutputForTests({
err: stderr.split(/\r?\n/),
out: stdout.split(/\r?\n/),
});
stdout = filtered.out.join('\n');
stderr = filtered.err.join('\n');
let pkgNodeVersion = '';
let pkgNodeMajorVersion = 0;
try {
const balenaVersions: JsonVersions = JSON.parse(stdout);
pkgNodeVersion = balenaVersions['Node.js'];
pkgNodeMajorVersion = semver.major(pkgNodeVersion);
} catch (err) {
throw new Error(stripIndent`
Error parsing JSON output of "balena version -j": ${err}
Original output: "${stdout}"`);
}
if (semver.major(process.version) !== pkgNodeMajorVersion) {
throw new Error(
`Mismatched major version: built-in pkg Node version="${pkgNodeVersion}" vs process.version="${process.version}"`,
);
}
if (filtered.err.length > 0) {
const err = filtered.err.join('\n');
throw new Error(`"${pkgBalenaPath}": non-empty stderr "${err}"`);
}
console.log('Success! (standalone package test successful)');
}
/**
* Create the zip file for the standalone 'pkg' bundle previously created
* by the buildPkg() function in 'build-bin.ts'.
*/
async function zipPkg() {
const outputFile = standaloneZips[process.platform];
if (!outputFile) {
throw new Error(
`Standalone installer unavailable for platform "${process.platform}"`,
);
}
await fs.mkdirp(path.dirname(outputFile));
await new Promise((resolve, reject) => {
console.log(`Zipping standalone package to "${outputFile}"...`);
const archive = archiver('zip', {
zlib: { level: 7 },
});
archive.directory(path.join(ROOT, 'build-bin'), 'balena-cli');
const outputStream = fs.createWriteStream(outputFile);
outputStream.on('close', resolve);
outputStream.on('error', reject);
archive.on('error', reject);
archive.on('warning', console.warn);
archive.pipe(outputStream);
archive.finalize().catch(reject);
});
}
const renamedOclifStandalone: PathByPlatform = {
linux: dPath(`balena-cli-${version}-linux-${arch}-standalone.tar.gz`),
darwin: dPath(`balena-cli-${version}-macOS-${arch}-standalone.tar.gz`),
win32: dPath(`balena-cli-${version}-windows-${arch}-standalone.tar.gz`),
};
export async function signFilesForNotarization() {
console.log('Signing files for notarization');
if (process.platform !== 'darwin') {
// If signFilesForNotarization is called on the test CI environment (which will not set CSC_LINK)
// then we skip the signing process.
if (process.platform !== 'darwin' || !process.env.CSC_LINK) {
console.log('Skipping signing for notarization');
return;
}
console.log('Deleting unneeded zip files...');
@ -416,20 +166,39 @@ export async function signFilesForNotarization() {
]);
}
export async function buildStandaloneZip() {
console.log(`Building standalone zip package for CLI ${version}`);
export async function buildStandalone() {
console.log(`Building standalone tarball for CLI ${version}`);
fs.rmSync('./tmp', { recursive: true, force: true });
fs.rmSync('./dist', { recursive: true, force: true });
fs.mkdirSync('./dist');
try {
await buildPkg();
await testPkg();
await zipPkg();
console.log(`Standalone zip package build completed`);
let packOpts = ['-r', ROOT, '--no-xz'];
if (process.platform === 'darwin') {
packOpts = packOpts.concat('--targets', `darwin-${arch}`);
} else if (process.platform === 'win32') {
packOpts = packOpts.concat('--targets', 'win32-x64');
} else if (process.platform === 'linux') {
packOpts = packOpts.concat('--targets', `linux-${arch}`);
}
console.log(`Building oclif installer for CLI ${version}`);
const packCmd = `pack:tarballs`;
console.log('=======================================================');
console.log(`oclif ${packCmd} ${packOpts.join(' ')}`);
console.log(`cwd="${process.cwd()}" ROOT="${ROOT}"`);
console.log('=======================================================');
const oclifPath = path.join(ROOT, 'node_modules', 'oclif');
await oclifRun([packCmd].concat(...packOpts), oclifPath);
await renameStandalone();
console.log(`Standalone tarball package build completed`);
} catch (error) {
console.error(`Error creating or testing standalone zip package`);
console.error(`Error creating or testing standalone tarball package`);
throw error;
}
}
async function renameInstallerFiles() {
async function renameInstallers() {
const oclifInstallers = await getOclifInstallersOriginalNames();
if (await fs.pathExists(oclifInstallers[process.platform])) {
await fs.rename(
@ -439,6 +208,16 @@ async function renameInstallerFiles() {
}
}
async function renameStandalone() {
const oclifStandalone = await getOclifStandaloneOriginalNames();
if (await fs.pathExists(oclifStandalone[process.platform])) {
await fs.rename(
oclifStandalone[process.platform],
renamedOclifStandalone[process.platform],
);
}
}
/**
* If the CSC_LINK and CSC_KEY_PASSWORD env vars are set, digitally sign the
* executable installer using Microsoft SignTool.exe (Sign Tool)
@ -446,7 +225,7 @@ async function renameInstallerFiles() {
*/
async function signWindowsInstaller() {
if (process.env.SM_CODE_SIGNING_CERT_SHA1_HASH) {
const exeName = renamedOclifInstallers[process.platform];
const exeName = (await getOclifInstallersOriginalNames())[process.platform];
console.log(`Signing installer "${exeName}"`);
// trust ...
await execFileAsync('signtool.exe', [
@ -480,12 +259,14 @@ async function notarizeMacInstaller(): Promise<void> {
const appleId =
process.env.XCODE_APP_LOADER_EMAIL || 'accounts+apple@balena.io';
const appleIdPassword = process.env.XCODE_APP_LOADER_PASSWORD;
const appPath = (await getOclifInstallersOriginalNames())[process.platform];
console.log(`Notarizing file "${appPath}"`);
if (appleIdPassword && teamId) {
await notarize({
tool: 'notarytool',
teamId,
appPath: renamedOclifInstallers.darwin,
appPath,
appleId,
appleIdPassword,
});
@ -525,7 +306,6 @@ export async function buildOclifInstaller() {
console.log('=======================================================');
const oclifPath = path.join(ROOT, 'node_modules', 'oclif');
await oclifRun([packCmd].concat(...packOpts), oclifPath);
await renameInstallerFiles();
// The Windows installer is explicitly signed here (oclif doesn't do it).
// The macOS installer is automatically signed by oclif (which runs the
// `pkgbuild` tool), using the certificate name given in package.json
@ -537,6 +317,7 @@ export async function buildOclifInstaller() {
await notarizeMacInstaller(); // Notarize
console.log('Package notarized.');
}
await renameInstallers();
console.log(`oclif installer build completed`);
}
}
@ -572,4 +353,5 @@ export async function testShrinkwrap(): Promise<void> {
if (process.platform !== 'win32') {
await whichSpawn(path.resolve(__dirname, 'test-lock-deduplicated.sh'));
}
await Promise.resolve();
}

View File

@ -19,7 +19,7 @@ import * as _ from 'lodash';
import {
buildOclifInstaller,
buildStandaloneZip,
buildStandalone,
catchUncommitted,
signFilesForNotarization,
testShrinkwrap,
@ -36,7 +36,7 @@ process.env.DEBUG = ['0', 'no', 'false', '', undefined].includes(
* Trivial command-line parser. Check whether the command-line argument is one
* of the following strings, then call the appropriate functions:
* 'build:installer' (to build a native oclif installer)
* 'build:standalone' (to build a standalone pkg package)
* 'build:standalone' (to build a standalone package)
*
* @param args Arguments to parse (default is process.argv.slice(2))
*/
@ -49,7 +49,7 @@ async function parse(args?: string[]) {
}
const commands: { [cmd: string]: () => void | Promise<void> } = {
'build:installer': buildOclifInstaller,
'build:standalone': buildStandaloneZip,
'build:standalone': buildStandalone,
'sign:binaries': signFilesForNotarization,
'catch-uncommitted': catchUncommitted,
'test-shrinkwrap': testShrinkwrap,

View File

@ -18,73 +18,10 @@
import { spawn } from 'child_process';
import * as path from 'path';
import * as fs from 'fs';
import { diffTrimmedLines } from 'diff';
import * as whichMod from 'which';
export const ROOT = path.join(__dirname, '..');
/** Tap and buffer this process' stdout and stderr */
export class StdOutTap {
public stdoutBuf: string[] = [];
public stderrBuf: string[] = [];
public allBuf: string[] = []; // both stdout and stderr
protected origStdoutWrite: typeof process.stdout.write;
protected origStderrWrite: typeof process.stdout.write;
constructor(protected printDots = false) {}
tap() {
this.origStdoutWrite = process.stdout.write;
this.origStderrWrite = process.stderr.write;
process.stdout.write = (chunk: string, ...args: any[]): boolean => {
this.stdoutBuf.push(chunk);
this.allBuf.push(chunk);
const str = this.printDots ? '.' : chunk;
return this.origStdoutWrite.call(process.stdout, str, ...args);
};
process.stderr.write = (chunk: string, ...args: any[]): boolean => {
this.stderrBuf.push(chunk);
this.allBuf.push(chunk);
const str = this.printDots ? '.' : chunk;
return this.origStderrWrite.call(process.stderr, str, ...args);
};
}
untap() {
process.stdout.write = this.origStdoutWrite;
process.stderr.write = this.origStderrWrite;
if (this.printDots) {
console.error('');
}
}
}
/**
* Diff strings by line, using the 'diff' npm package:
* https://www.npmjs.com/package/diff
*/
export function diffLines(str1: string, str2: string): string {
const diffObjs = diffTrimmedLines(str1, str2);
const prefix = (chunk: string, char: string) =>
chunk
.split('\n')
.map((line: string) => `${char} ${line}`)
.join('\n');
const diffStr = diffObjs
.map((part: any) => {
return part.added
? prefix(part.value, '+')
: part.removed
? prefix(part.value, '-')
: prefix(part.value, ' ');
})
.join('\n');
return diffStr;
}
export function loadPackageJson() {
const packageJsonPath = path.join(ROOT, 'package.json');

View File

@ -13,6 +13,8 @@ GitHub](https://github.com/balena-io/balena-cli/), and your contribution is also
Check the [balena CLI installation instructions on
GitHub](https://github.com/balena-io/balena-cli/blob/master/INSTALL.md).
Note for v22 Migration: If you are upgrading to balena CLI v22 from a previous standalone installation, please [see the v22 Migration Guide](https://github.com/balena-io/balena-cli/blob/master/MIGRATIONS.md) for installation changes.
## Choosing a shell (command prompt/terminal)
On **Windows,** the standard Command Prompt (`cmd.exe`) and
@ -326,6 +328,8 @@ or to authenticate requests to the API with an 'Authorization: Bearer <key>' hea
Examples:
$ balena api-key generate "Jenkins Key"
$ balena api-key generate "Jenkins Key" 2025-10-30
$ balena api-key generate "Jenkins Key" never
### Arguments
@ -333,6 +337,10 @@ Examples:
the API key name
#### EXPIRYDATE
the expiry date of the API key as an ISO date string, or "never" for no expiry
## api-key list
### Aliases
@ -568,9 +576,9 @@ Generate a config.json file for a device or fleet.
The target balenaOS version must be specified with the --version option.
The '--dev' option is used to configure balenaOS to operate in development mode,
allowing anauthenticated root ssh access and exposing network ports such as
allowing unauthenticated root ssh access and exposing network ports such as
balenaEngine's 2375 (unencrypted). This option causes `"developmentMode": true`
to be inserted in the 'config.json' file in the image's boot partion. Development
to be inserted in the 'config.json' file in the image's boot partition. Development
mode (as a configurable option) is applicable to balenaOS releases from early
2022. Older releases have separate development and production balenaOS images
that cannot be reconfigured through 'config.json' or the '--dev' option. Do not
@ -2866,9 +2874,9 @@ The --device-type option is used to override the fleet's default device type,
in case of a fleet with mixed device types.
The '--dev' option is used to configure balenaOS to operate in development mode,
allowing anauthenticated root ssh access and exposing network ports such as
allowing unauthenticated root ssh access and exposing network ports such as
balenaEngine's 2375 (unencrypted). This option causes `"developmentMode": true`
to be inserted in the 'config.json' file in the image's boot partion. Development
to be inserted in the 'config.json' file in the image's boot partition. Development
mode (as a configurable option) is applicable to balenaOS releases from early
2022. Older releases have separate development and production balenaOS images
that cannot be reconfigured through 'config.json' or the '--dev' option. Do not

6658
npm-shrinkwrap.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
{
"name": "balena-cli",
"version": "20.1.2",
"version": "22.1.1",
"description": "The official balena Command Line Interface",
"main": "./build/app.js",
"homepage": "https://github.com/balena-io/balena-cli",
@ -24,26 +24,6 @@
"bin": {
"balena": "./bin/run.js"
},
"pkg": {
"scripts": [
"build/**/*.js",
"node_modules/balena-sdk/es2018/index.js",
"node_modules/pinejs-client-request/node_modules/pinejs-client-core/es2018/index.js",
"node_modules/@balena/compose/dist/parse/schemas/*.json"
],
"assets": [
"build/auth/pages/*.ejs",
"node_modules/balena-sdk/node_modules/balena-pine/**/*",
"node_modules/balena-pine/**/*",
"node_modules/pinejs-client-core/**/*",
"node_modules/open/xdg-open",
"node_modules/windosu/*.bat",
"node_modules/windosu/*.cmd",
"node_modules/axios/**/*",
"npm-shrinkwrap.json",
"oclif.manifest.json"
]
},
"scripts": {
"postinstall": "node patches/apply-patches.js",
"prebuild": "rimraf build/ build-bin/",
@ -58,6 +38,7 @@
"build:completion": "node completion/generate-completion.js",
"build:standalone": "ts-node --transpile-only automation/run.ts build:standalone",
"build:installer": "ts-node --transpile-only automation/run.ts build:installer",
"deduplicate-dependencies": "npm dd && git add npm-shrinkwrap.json && git commit --message \"Deduplicate dependencies\"",
"package": "npm run build:fast && npm run build:standalone && npm run build:installer",
"pretest": "npm run build",
"test": "npm run test:shrinkwrap && npm run test:core",
@ -91,7 +72,7 @@
"author": "Balena Inc. (https://balena.io/)",
"license": "Apache-2.0",
"engines": {
"node": "^20.6.0"
"node": ">=20.6.0 <23"
},
"oclif": {
"bin": "balena",
@ -113,14 +94,12 @@
"devDependencies": {
"@balena/lint": "^9.1.3",
"@electron/notarize": "^2.0.0",
"@types/archiver": "^6.0.2",
"@types/bluebird": "^3.5.36",
"@types/body-parser": "^1.19.2",
"@types/chai": "^4.3.0",
"@types/chai-as-promised": "^7.1.4",
"@types/cli-truncate": "^2.0.0",
"@types/common-tags": "^1.8.1",
"@types/diff": "^5.0.3",
"@types/dockerode": "3.3.23",
"@types/ejs": "^3.1.0",
"@types/express": "^4.17.13",
@ -145,7 +124,6 @@
"@types/node-cleanup": "^2.1.2",
"@types/prettyjson": "^0.0.33",
"@types/progress-stream": "^2.0.2",
"@types/request": "^2.48.7",
"@types/rewire": "^2.5.30",
"@types/rimraf": "^3.0.2",
"@types/semver": "^7.3.9",
@ -159,16 +137,12 @@
"@types/update-notifier": "^4.1.1",
"@types/which": "^2.0.1",
"@types/window-size": "^1.1.1",
"@yao-pkg/pkg": "^5.11.1",
"archiver": "^7.0.1",
"catch-uncommitted": "^2.0.0",
"chai": "^4.3.4",
"chai-as-promised": "^7.1.1",
"cross-env": "^7.0.3",
"deep-object-diff": "^1.1.0",
"diff": "^5.0.0",
"ent": "^2.2.0",
"filehound": "^1.17.5",
"fs-extra": "^11.2.0",
"http-proxy": "^1.18.1",
"husky": "^9.1.5",
@ -179,28 +153,28 @@
"mocha": "^10.6.0",
"mock-fs": "^5.2.0",
"mock-require": "^3.0.3",
"nock": "^13.2.1",
"oclif": "^4.14.0",
"nock": "^14.0.4",
"oclif": "^4.17.0",
"rewire": "^7.0.0",
"simple-git": "^3.14.1",
"sinon": "^19.0.0",
"string-to-stream": "^3.0.1",
"ts-node": "^10.4.0",
"typescript": "^5.7.2"
"typescript": "^5.8.2"
},
"dependencies": {
"@balena/compose": "^6.0.0",
"@balena/compose": "^7.0.9",
"@balena/dockerignore": "^1.0.2",
"@balena/env-parsing": "^1.1.8",
"@balena/es-version": "^1.0.1",
"@oclif/core": "^4.0.31",
"@sentry/node": "^6.16.1",
"balena-config-json": "^4.2.0",
"balena-device-init": "^7.0.1",
"@oclif/core": "^4.1.0",
"@sentry/node": "^9.0.0",
"balena-config-json": "^4.2.7",
"balena-device-init": "^8.1.11",
"balena-errors": "^4.7.3",
"balena-image-fs": "^7.0.6",
"balena-preload": "^16.0.0",
"balena-sdk": "^20.8.0",
"balena-image-fs": "^7.5.2",
"balena-preload": "^18.0.4",
"balena-sdk": "^21.3.0",
"balena-semver": "^2.3.0",
"balena-settings-client": "^5.0.2",
"balena-settings-storage": "^8.1.0",
@ -211,12 +185,13 @@
"cli-truncate": "^2.1.0",
"color-hash": "^1.1.1",
"common-tags": "^1.7.2",
"date-fns": "^4.1.0",
"denymount": "^2.3.0",
"docker-modem": "^5.0.3",
"docker-modem": "^5.0.6",
"docker-progress": "^5.1.3",
"dockerode": "^4.0.2",
"dockerode": "^4.0.5",
"ejs": "^3.1.6",
"etcher-sdk": "9.1.0",
"etcher-sdk": "^10.0.0",
"express": "^4.17.2",
"fast-boot2": "^1.1.0",
"fast-levenshtein": "^3.0.0",
@ -244,9 +219,8 @@
"prettyjson": "^1.2.5",
"progress-stream": "^2.0.0",
"reconfix": "^1.0.0-v0-1-0-fork-46760acff4d165f5238bfac5e464256ef1944476",
"request": "^2.88.2",
"resin-cli-form": "^3.0.0",
"resin-cli-visuals": "^2.0.1",
"resin-cli-form": "^4.0.0",
"resin-cli-visuals": "^3.0.0",
"resin-doodles": "^0.2.0",
"resin-stream-logger": "^0.1.2",
"rimraf": "^3.0.2",
@ -274,6 +248,6 @@
}
},
"versionist": {
"publishedAt": "2024-12-17T11:34:56.167Z"
"publishedAt": "2025-06-19T09:32:53.877Z"
}
}

View File

@ -1,8 +1,8 @@
diff --git a/node_modules/oclif/lib/commands/pack/win.js b/node_modules/oclif/lib/commands/pack/win.js
index ef7f90e..8264b7c 100644
index bfe9205..482519e 100644
--- a/node_modules/oclif/lib/commands/pack/win.js
+++ b/node_modules/oclif/lib/commands/pack/win.js
@@ -76,6 +76,12 @@ InstallDir "\$PROGRAMFILES${arch === 'x64' ? '64' : ''}\\${config.dirname}"
@@ -86,6 +86,12 @@ InstallDir "\$PROGRAMFILES${arch === 'x64' ? '64' : ''}\\${config.dirname}"
${customization}
Section "${config.name} CLI \${VERSION}"
@ -16,20 +16,18 @@ index ef7f90e..8264b7c 100644
File /r bin
File /r client
diff --git a/node_modules/oclif/lib/tarballs/build.js b/node_modules/oclif/lib/tarballs/build.js
index 14d5a6e..7b42a6f 100644
index f0c8d95..a72400e 100644
--- a/node_modules/oclif/lib/tarballs/build.js
+++ b/node_modules/oclif/lib/tarballs/build.js
@@ -200,6 +200,13 @@ const extractCLI = async (tarball, c) => {
@@ -218,6 +218,11 @@ const extractCLI = async (tarball, c) => {
(0, promises_1.rm)(path.join(workspace, path.basename(tarball)), { recursive: true }),
(0, fs_extra_1.remove)(path.join(workspace, 'bin', 'run.cmd')),
]);
+
+ // The oclif installers are a production installation, while the source
+ // `bin` folder may contain a `.fast-boot.json` file of a dev installation.
+ // This has previously led to issues preventing the CLI from starting, so
+ // delete `.fast-boot.json` (if any) from the destination folder.
+ await (0, fs_extra_1.remove)(path.join(workspace, 'bin', '.fast-boot.json'));
+
};
const buildTarget = async (target, c, options) => {
const workspace = c.workspace(target);
if (target.platform === 'win32' && target.arch === 'arm64' && (0, semver_1.lt)(c.nodeVersion, '20.0.0')) {

View File

@ -1,16 +0,0 @@
diff --git a/node_modules/open/index.js b/node_modules/open/index.js
index 13147d0..ff161dd 100644
--- a/node_modules/open/index.js
+++ b/node_modules/open/index.js
@@ -10,7 +10,10 @@ const pAccess = promisify(fs.access);
const pReadFile = promisify(fs.readFile);
// Path to included `xdg-open`.
-const localXdgOpenPath = path.join(__dirname, 'xdg-open');
+const localXdgOpenPath = process.pkg
+ ? path.join(path.dirname(process.execPath), 'xdg-open')
+ : path.join(__dirname, 'xdg-open');
+
/**
Get the mount point for fixed drives in WSL.

View File

@ -1,14 +0,0 @@
diff --git a/node_modules/node-gyp-build/node-gyp-build.js b/node_modules/node-gyp-build/node-gyp-build.js
index 61b398e..3cc3be8 100644
--- a/node_modules/node-gyp-build/node-gyp-build.js
+++ b/node_modules/node-gyp-build/node-gyp-build.js
@@ -30,6 +30,9 @@ load.resolve = load.path = function (dir) {
if (process.env[name + '_PREBUILD']) dir = process.env[name + '_PREBUILD']
} catch (err) {}
+ // pkg fix: native node modules are located externally to the pkg executable
+ dir = dir.replace(/^\/snapshot\/.+?\/node_modules\//, path.dirname(process.execPath) + path.sep)
+
if (!prebuildsOnly) {
var release = getFirst(path.join(dir, 'build/Release'), matchBuild)
if (release) return release

View File

@ -1,38 +0,0 @@
diff --git a/node_modules/windosu/lib/pipe.js b/node_modules/windosu/lib/pipe.js
index dc81fa5..a381cc7 100644
--- a/node_modules/windosu/lib/pipe.js
+++ b/node_modules/windosu/lib/pipe.js
@@ -42,7 +42,8 @@ function pipe(path, options) {
return d.promise;
}
module.exports = pipe;
-if (module === require.main) {
+
+function main() {
if (!process.argv[4]) {
console.error('Incorrect arguments!');
process.exit(-1);
@@ -52,3 +53,8 @@ if (module === require.main) {
serve: process.argv[3] == 'server'
});
}
+module.exports.main = main;
+
+if (module === require.main) {
+ main();
+}
diff --git a/node_modules/windosu/lib/windosu.js b/node_modules/windosu/lib/windosu.js
index 6502812..dd0391a 100644
--- a/node_modules/windosu/lib/windosu.js
+++ b/node_modules/windosu/lib/windosu.js
@@ -16,7 +16,9 @@ module.exports.exec = function (command, options, callback) {
temp: temp,
command: command,
cliWidth: cliWidth(),
- pipe: '"' + process.execPath + '" "' + path.join(__dirname, 'pipe.js') + '"',
+ pipe: process.pkg
+ ? '"' + process.execPath + '" pkgExec "' + path.join(__dirname, 'pipe.js') + '::main"'
+ : '"' + process.execPath + '" "' + path.join(__dirname, 'pipe.js') + '"',
input: inputName = id + '-in',
output: outputName = id + '-out',
stderr_redir: process.stdout.isTTY ? '2>&1' : '2> %ERROR%'

View File

@ -6,6 +6,10 @@ upstream:
url: 'https://github.com/balena-io/balena-sdk'
- repo: 'balena-config-json'
url: 'https://github.com/balena-io-modules/balena-config-json'
- repo: 'balena-image-fs'
url: 'https://github.com/balena-io-modules/balena-image-fs'
- repo: 'balena-device-init'
url: 'https://github.com/balena-io-modules/balena-device-init'
- repo: 'balena-image-manager'
url: 'https://github.com/balena-io-modules/balena-image-manager'
- repo: 'balena-preload'

View File

@ -34,18 +34,14 @@ export const setupSentry = onceAsync(async () => {
const config = await import('./config');
const Sentry = await import('@sentry/node');
Sentry.init({
autoSessionTracking: false,
dsn: config.sentryDsn,
release: packageJSON.version,
});
Sentry.configureScope((scope) => {
scope.setExtras({
is_pkg: !!(process as any).pkg,
node_version: process.version,
platform: process.platform,
});
Sentry.getCurrentScope().setExtras({
is_pkg: !!(process as any).pkg,
node_version: process.version,
platform: process.platform,
});
return Sentry.getCurrentHub();
});
async function checkNodeVersion() {
@ -159,18 +155,12 @@ async function oclifRun(command: string[], options: AppOptions) {
/** CLI entrypoint. Called by the `bin/run.js` and `bin/dev.js` scripts. */
export async function run(cliArgs = process.argv, options: AppOptions) {
try {
const { setOfflineModeEnvVars, normalizeEnvVars, pkgExec } = await import(
const { setOfflineModeEnvVars, normalizeEnvVars } = await import(
'./utils/bootstrap'
);
setOfflineModeEnvVars();
normalizeEnvVars();
// The 'pkgExec' special/internal command provides a Node.js interpreter
// for use of the standalone zip package. See pkgExec function.
if (cliArgs.length > 3 && cliArgs[2] === 'pkgExec') {
return pkgExec(cliArgs[3], cliArgs.slice(4));
}
await init();
// Look for commands that have been removed and if so, exit with a notice

View File

@ -17,7 +17,16 @@
import { Args, Command } from '@oclif/core';
import { ExpectedError } from '../../errors';
import { getBalenaSdk, stripIndent } from '../../utils/lazy';
import { getBalenaSdk, getCliForm, stripIndent } from '../../utils/lazy';
import {
formatDuration,
intervalToDuration,
isValid,
parseISO,
} from 'date-fns';
// In days
const durations = [1, 7, 30, 90];
async function isLoggedInWithJwt() {
const balena = getBalenaSdk();
@ -41,13 +50,21 @@ export default class GenerateCmd extends Command {
This key can be used to log into the CLI using 'balena login --token <key>',
or to authenticate requests to the API with an 'Authorization: Bearer <key>' header.
`;
public static examples = ['$ balena api-key generate "Jenkins Key"'];
public static examples = [
'$ balena api-key generate "Jenkins Key"',
'$ balena api-key generate "Jenkins Key" 2025-10-30',
'$ balena api-key generate "Jenkins Key" never',
];
public static args = {
name: Args.string({
description: 'the API key name',
required: true,
}),
expiryDate: Args.string({
description:
'the expiry date of the API key as an ISO date string, or "never" for no expiry',
}),
};
public static authenticated = true;
@ -55,9 +72,61 @@ export default class GenerateCmd extends Command {
public async run() {
const { args: params } = await this.parse(GenerateCmd);
let expiryDateResponse: string | number | undefined = params.expiryDate;
let key;
try {
key = await getBalenaSdk().models.apiKey.create(params.name);
if (!expiryDateResponse) {
expiryDateResponse = await getCliForm().ask({
message: 'Please pick an expiry date for the API key',
type: 'list',
choices: [...durations, 'custom', 'never'].map((duration) => ({
name:
duration === 'never'
? 'No expiration'
: typeof duration === 'number'
? formatDuration(
intervalToDuration({
start: 0,
end: duration * 24 * 60 * 60 * 1000,
}),
)
: 'Custom expiration',
value: duration,
})),
});
}
let expiryDate: Date | null;
if (expiryDateResponse === 'never') {
expiryDate = null;
} else if (expiryDateResponse === 'custom') {
do {
expiryDate = parseISO(
await getCliForm().ask({
message:
'Please enter an expiry date for the API key as an ISO date string',
type: 'input',
}),
);
if (!isValid(expiryDate)) {
console.error('Invalid date format');
}
} while (!isValid(expiryDate));
} else if (typeof expiryDateResponse === 'string') {
expiryDate = parseISO(expiryDateResponse);
if (!isValid(expiryDate)) {
throw new Error(
'Invalid date format, please use a valid ISO date string',
);
}
} else {
expiryDate = new Date(
Date.now() + expiryDateResponse * 24 * 60 * 60 * 1000,
);
}
key = await getBalenaSdk().models.apiKey.create({
name: params.name,
expiryDate: expiryDate === null ? null : expiryDate.toISOString(),
});
} catch (e) {
if (e.name === 'BalenaNotLoggedIn') {
if (await isLoggedInWithJwt()) {

View File

@ -64,7 +64,12 @@ export default class ConfigInjectCmd extends Command {
);
const config = await import('balena-config-json');
await config.write(drive, '', configJSON);
await config.write(
drive,
// Will be removed in the next major of balena-config-json
undefined,
configJSON,
);
console.info('Done');
}

View File

@ -54,7 +54,7 @@ export default class ConfigReadCmd extends Command {
await safeUmount(drive);
const config = await import('balena-config-json');
const configJSON = await config.read(drive, '');
const configJSON = await config.read(drive);
if (options.json) {
console.log(JSON.stringify(configJSON, null, 4));

View File

@ -62,7 +62,7 @@ export default class ConfigReconfigureCmd extends Command {
await safeUmount(drive);
const config = await import('balena-config-json');
const { uuid } = await config.read(drive, '');
const { uuid } = await config.read(drive);
await safeUmount(drive);
if (!uuid) {

View File

@ -64,14 +64,19 @@ export default class ConfigWriteCmd extends Command {
await safeUmount(drive);
const config = await import('balena-config-json');
const configJSON = await config.read(drive, '');
const configJSON = await config.read(drive);
console.info(`Setting ${params.key} to ${params.value}`);
ConfigWriteCmd.updateConfigJson(configJSON, params.key, params.value);
await denyMount(drive, async () => {
await safeUmount(drive);
await config.write(drive, '', configJSON);
await config.write(
drive,
// Will be removed in the next major of balena-config-json
undefined,
configJSON,
);
});
console.info('Done');

View File

@ -368,6 +368,7 @@ ${dockerignoreHelp}
!opts.shouldUploadLogs,
composeOpts.projectPath,
opts.createAsDraft,
project.descriptors,
);
}

View File

@ -77,45 +77,59 @@ export default class DeviceCmd extends Command {
const balena = getBalenaSdk();
const device = (await balena.models.device.get(
params.uuid,
options.json
? {
$expand: {
device_tag: {
$select: ['tag_key', 'value'],
},
...expandForAppName.$expand,
let device: ExtendedDevice;
if (options.json) {
const [deviceBase, deviceComputed] = await Promise.all([
balena.models.device.get(params.uuid, {
$expand: {
device_tag: {
$select: ['tag_key', 'value'],
},
}
: {
$select: [
'device_name',
'id',
'overall_status',
'is_online',
'ip_address',
'mac_address',
'last_connectivity_event',
'uuid',
'supervisor_version',
'is_web_accessible',
'note',
'os_version',
'memory_usage',
'memory_total',
'public_address',
'storage_block_device',
'storage_usage',
'storage_total',
'cpu_usage',
'cpu_temp',
'cpu_id',
'is_undervolted',
],
...expandForAppName,
...expandForAppName.$expand,
},
)) as ExtendedDevice;
}),
balena.models.device.get(params.uuid, {
$select: [
'overall_status',
'overall_progress',
'should_be_running__release',
],
}),
]);
device = {
...deviceBase,
...deviceComputed,
} as ExtendedDevice;
} else {
device = (await balena.models.device.get(params.uuid, {
$select: [
'device_name',
'id',
'overall_status',
'is_online',
'ip_address',
'mac_address',
'last_connectivity_event',
'uuid',
'supervisor_version',
'is_web_accessible',
'note',
'os_version',
'memory_usage',
'memory_total',
'public_address',
'storage_block_device',
'storage_usage',
'storage_total',
'cpu_usage',
'cpu_temp',
'cpu_id',
'is_undervolted',
],
...expandForAppName,
})) as ExtendedDevice;
}
if (options.view) {
const open = await import('open');

View File

@ -16,7 +16,6 @@
*/
import { Args, Command } from '@oclif/core';
import { promisify } from 'util';
import { stripIndent } from '../../utils/lazy';
export default class LocalConfigureCmd extends Command {
@ -237,7 +236,7 @@ export default class LocalConfigureCmd extends Command {
const bootPartition = await getBootPartition(target);
const files = await imagefs.interact(target, bootPartition, async (_fs) => {
return await promisify(_fs.readdir)(this.CONNECTIONS_FOLDER);
return await _fs.promises.readdir(this.CONNECTIONS_FOLDER);
});
let connectionFileName;
@ -246,13 +245,14 @@ export default class LocalConfigureCmd extends Command {
} else if (_.includes(files, 'resin-sample.ignore')) {
// Fresh image, new mode, accoding to https://github.com/balena-os/meta-balena/pull/770/files
await imagefs.interact(target, bootPartition, async (_fs) => {
const readFileAsync = promisify(_fs.readFile);
const writeFileAsync = promisify(_fs.writeFile);
const contents = await readFileAsync(
const contents = await _fs.promises.readFile(
`${this.CONNECTIONS_FOLDER}/resin-sample.ignore`,
{ encoding: 'utf8' },
);
await writeFileAsync(`${this.CONNECTIONS_FOLDER}/resin-wifi`, contents);
await _fs.promises.writeFile(
`${this.CONNECTIONS_FOLDER}/resin-wifi`,
contents,
);
});
} else if (_.includes(files, 'resin-sample')) {
// Legacy mode, to be removed later
@ -266,7 +266,7 @@ export default class LocalConfigureCmd extends Command {
} else {
// In case there's no file at all (shouldn't happen normally, but the file might have been removed)
await imagefs.interact(target, bootPartition, async (_fs) => {
await promisify(_fs.writeFile)(
await _fs.promises.writeFile(
`${this.CONNECTIONS_FOLDER}/resin-wifi`,
this.CONNECTION_FILE,
);

View File

@ -18,7 +18,6 @@
import { Flags, Args, Command } from '@oclif/core';
import type { Interfaces } from '@oclif/core';
import type * as BalenaSdk from 'balena-sdk';
import { promisify } from 'util';
import * as _ from 'lodash';
import { ExpectedError } from '../../errors';
import * as cf from '../../utils/common-flags';
@ -292,7 +291,7 @@ export default class OsConfigureCmd extends Command {
for (const { name, content } of files) {
await imagefs.interact(image, bootPartition, async (_fs) => {
await promisify(_fs.writeFile)(
await _fs.promises.writeFile(
path.join(CONNECTIONS_FOLDER, name),
content,
);

View File

@ -37,6 +37,7 @@ import type {
Release,
} from 'balena-sdk';
import type { Preloader } from 'balena-preload';
import type * as Fs from 'fs';
export default class PreloadCmd extends Command {
public static description = stripIndent`
@ -161,6 +162,42 @@ Can be repeated to add multiple certificates.\
);
}
// Verify that image is not enabled for secure boot. First, confirm it is
// a secure boot image with a .sig file in the /opt directory of the rootA
// partition. For example, below are contents for generic-amd64 device type:
// $ ls -l opt
// total 864696
// -rw-r--r-- 1 root root 2378170368 Mar 26 09:14 balena-image-generic-amd64.balenaos-img
// -rw-r--r-- 1 root root 512 Mar 9 2018 balena-image-generic-amd64.balenaos-img.sig
const { explorePartition, BalenaPartition } = await import(
'../../utils/image-contents'
);
const isSecureBoot = await explorePartition<boolean>(
params.image,
BalenaPartition.ROOTA,
async (fs: typeof Fs): Promise<boolean> => {
try {
const files = await fs.promises.readdir('/opt');
return files.some((el) => el.endsWith('balenaos-img.sig'));
} catch {
// Typically one of:
// - Error: No such file or directory
// - Error: Unsupported filesystem.
// - ErrnoException: node_ext2fs_open ENOENT (44) args: [5261576,5268064,"r",0]
return false;
}
return false;
},
);
// Next verify that config.json enables secureboot.
if (isSecureBoot) {
const { read } = await import('balena-config-json');
const config = await read(params.image);
if (config.installer?.secureboot === true) {
throw new ExpectedError("Can't preload image with secure boot enabled");
}
}
// balena-preload currently does not work with numerical app IDs
// Load app here, and use app slug from hereon
const fleetSlug: string | undefined = options.fleet
@ -295,7 +332,7 @@ Can be repeated to add multiple certificates.\
owns__release: {
$select: ['id', 'commit', 'end_timestamp', 'composition'],
$expand: {
contains__image: {
release_image: {
$select: ['image'],
$expand: {
image: {

View File

@ -38,11 +38,11 @@ import { stripIndent } from './utils/lazy';
export async function trackCommand(commandSignature: string) {
try {
let Sentry: typeof import('@sentry/node');
let scope: import('@sentry/node').Scope;
if (!process.env.BALENARC_NO_SENTRY) {
Sentry = await import('@sentry/node');
Sentry.configureScope((scope) => {
scope.setExtra('command', commandSignature);
});
scope = Sentry.getCurrentScope();
scope.setExtra('command', commandSignature);
}
const { getCachedUsername } = await import('./utils/bootstrap');
let username: string | undefined;
@ -52,11 +52,9 @@ export async function trackCommand(commandSignature: string) {
// ignore
}
if (!process.env.BALENARC_NO_SENTRY) {
Sentry!.configureScope((scope) => {
scope.setUser({
id: username,
username,
});
scope!.setUser({
id: username,
username,
});
}
if (

View File

@ -83,43 +83,6 @@ export function setOfflineModeEnvVars() {
}
}
/**
* Implements the 'pkgExec' command, used as a way to provide a Node.js
* interpreter for child_process.spawn()-like operations when the CLI is
* executing as a standalone zip package (built-in Node interpreter) and
* the system may not have a separate Node.js installation. A present use
* case is a patched version of the 'windosu' package that requires a
* Node.js interpreter to spawn a privileged child process.
*
* @param modFunc Path to a JS module that will be executed via require().
* The modFunc argument may optionally contain a function name separated
* by '::', for example '::main' in:
* 'C:\\snapshot\\balena-cli\\node_modules\\windosu\\lib\\pipe.js::main'
* in which case that function is executed in the require'd module.
* @param args Optional arguments to passed through process.argv and as
* arguments to the function specified via modFunc.
*/
export async function pkgExec(modFunc: string, args: string[]) {
const [modPath, funcName] = modFunc.split('::');
let replacedModPath = modPath;
const match = modPath
.replace(/\\/g, '/')
.match(/\/snapshot\/balena-cli\/(.+)/);
if (match) {
replacedModPath = `../${match[1]}`;
}
process.argv = [process.argv[0], process.argv[1], ...args];
try {
const mod: any = await import(replacedModPath);
if (funcName) {
await mod[funcName](...args);
}
} catch (err) {
console.error(`Error executing pkgExec "${modFunc}" [${args.join()}]`);
console.error(err);
}
}
export interface CachedUsername {
token: string;
username: string;

View File

@ -128,6 +128,7 @@ export const createRelease = async function (
draft: boolean,
semver: string | undefined,
contract: import('@balena/compose/dist/release/models').ReleaseModel['contract'],
imgDescriptors: ImageDescriptor[],
): Promise<Release> {
const _ = require('lodash') as typeof import('lodash');
const crypto = require('crypto') as typeof import('crypto');
@ -167,6 +168,7 @@ export const createRelease = async function (
semver,
is_final: !draft,
contract,
imgDescriptors,
});
return {
@ -240,7 +242,7 @@ export const getPreviousRepos = (
status: 'success',
},
$expand: {
contains__image: {
release_image: {
$select: 'image',
$expand: { image: { $select: 'is_stored_at__image_location' } },
},
@ -252,7 +254,7 @@ export const getPreviousRepos = (
.then(function (release) {
// grab all images from the latest release, return all image locations in the registry
if (release.length > 0) {
const images = release[0].contains__image as Array<{
const images = release[0].release_image as Array<{
image: [SDK.Image];
}>;
const { getRegistryAndName } =

View File

@ -1322,6 +1322,9 @@ async function pushAndUpdateServiceImages(
}
}
// Error messages are limited to 300KB characters in the API, so we truncate longer ones.
const MAX_ERROR_MESSAGE_LENGTH = 300_000;
async function pushServiceImages(
docker: Dockerode,
logger: Logger,
@ -1344,23 +1347,34 @@ async function pushServiceImages(
delete serviceImage.build_log;
}
await releaseMod.updateImage(
pineClient,
serviceImage.id,
// These are the only update-able image fields in bC atm, and passing
// the whole image object in v7+ would result the allowlist to reject the request.
_.pick(serviceImage, [
'end_timestamp',
'project_type',
'error_message',
'build_log',
'push_timestamp',
'status',
'content_hash',
'dockerfile',
'image_size',
]),
);
// These are the only update-able image fields in bC atm, and passing
// the whole image object in v7+ would result the allowlist to reject the request.
const imagePayload = _.pick(serviceImage, [
'end_timestamp',
'project_type',
'error_message',
'build_log',
'push_timestamp',
'status',
'content_hash',
'dockerfile',
'image_size',
]);
if (
typeof imagePayload.error_message === 'string' &&
imagePayload.error_message.length > MAX_ERROR_MESSAGE_LENGTH
) {
logger.logDebug(
`Truncating error message of image ${serviceImage.is_stored_at__image_location} to ${MAX_ERROR_MESSAGE_LENGTH} characters.`,
);
imagePayload.error_message = imagePayload.error_message.substring(
0,
MAX_ERROR_MESSAGE_LENGTH,
);
}
await releaseMod.updateImage(pineClient, serviceImage.id, imagePayload);
},
);
}
@ -1375,6 +1389,7 @@ export async function deployProject(
skipLogUpload: boolean,
projectPath: string,
isDraft: boolean,
imgDescriptors: ImageDescriptor[],
): Promise<import('@balena/compose/dist/release/models').ReleaseModel> {
const releaseMod = await import('@balena/compose/dist/release');
const { createRelease, tagServiceImages } = await import('./compose');
@ -1405,6 +1420,7 @@ export async function deployProject(
isDraft,
contract?.version,
contract,
imgDescriptors,
),
);
const { client: pineClient, release, serviceImages } = $release;
@ -1594,7 +1610,9 @@ function buildProgressAdapter(inline: boolean) {
return;
}
if (!str.startsWith('Successfully tagged ')) {
// We want to keep the regex match instead of startsWith as it also works with buffers
// eslint-disable-next-line @typescript-eslint/prefer-string-starts-ends-with
if (!/^Successfully tagged /.test(str)) {
const match = stepRegex.exec(str);
if (match) {
step = match[1];

View File

@ -14,7 +14,6 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import type * as BalenaSdk from 'balena-sdk';
import * as semver from 'balena-semver';
import { getBalenaSdk, stripIndent } from './lazy';
export interface ImgConfig {
@ -122,16 +121,10 @@ export function generateDeviceConfig(
// os.getConfig always returns a config for an app
delete config.apiKey;
if (deviceApiKey == null && semver.satisfies(options.version, '<2.0.3')) {
config.apiKey = await sdk.models.application.generateApiKey(
application.id,
);
} else {
config.deviceApiKey =
typeof deviceApiKey === 'string' && deviceApiKey
? deviceApiKey
: await sdk.models.device.generateDeviceKey(device.uuid);
}
config.deviceApiKey =
typeof deviceApiKey === 'string' && deviceApiKey
? deviceApiKey
: await sdk.models.device.generateDeviceKey(device.uuid);
return config;
})

View File

@ -19,7 +19,7 @@ import { getVisuals } from './lazy';
import { promisify } from 'util';
import type * as Dockerode from 'dockerode';
import type Logger = require('./logger');
import type { Request } from 'request';
import type got from 'got';
const getBuilderPushEndpoint = function (
baseUrl: string,
@ -75,7 +75,10 @@ const showPushProgress = function (message: string) {
return progressBar;
};
const uploadToPromise = (uploadRequest: Request, logger: Logger) =>
const uploadToPromise = (
uploadRequest: ReturnType<typeof got.stream.post>,
logger: Logger,
) =>
new Promise<{ buildId: number }>(function (resolve, reject) {
uploadRequest.on('error', reject).on('data', function handleMessage(data) {
let obj;
@ -106,10 +109,7 @@ const uploadToPromise = (uploadRequest: Request, logger: Logger) =>
});
});
/**
* @returns {Promise<{ buildId: number }>}
*/
const uploadImage = function (
const uploadImage = async function (
imageStream: NodeJS.ReadableStream & { length: number },
token: string,
username: string,
@ -117,10 +117,9 @@ const uploadImage = function (
appName: string,
logger: Logger,
): Promise<{ buildId: number }> {
const request = require('request') as typeof import('request');
const progressStream =
require('progress-stream') as typeof import('progress-stream');
const zlib = require('zlib') as typeof import('zlib');
const { default: got } = await import('got');
const progressStream = await import('progress-stream');
const zlib = await import('zlib');
// Need to strip off the newline
const progressMessage = logger
@ -141,25 +140,26 @@ const uploadImage = function (
),
);
const uploadRequest = request.post({
url: getBuilderPushEndpoint(url, username, appName),
headers: {
'Content-Encoding': 'gzip',
const uploadRequest = got.stream.post(
getBuilderPushEndpoint(url, username, appName),
{
headers: {
'Content-Encoding': 'gzip',
Authorization: `Bearer ${token}`,
},
body: streamWithProgress.pipe(
zlib.createGzip({
level: 6,
}),
),
throwHttpErrors: false,
},
auth: {
bearer: token,
},
body: streamWithProgress.pipe(
zlib.createGzip({
level: 6,
}),
),
});
);
return uploadToPromise(uploadRequest, logger);
};
const uploadLogs = function (
const uploadLogs = async function (
logs: string,
token: string,
url: string,
@ -167,14 +167,14 @@ const uploadLogs = function (
username: string,
appName: string,
) {
const request = require('request') as typeof import('request');
return request.post({
json: true,
url: getBuilderLogPushEndpoint(url, buildId, username, appName),
auth: {
bearer: token,
const { default: got } = await import('got');
return got.post(getBuilderLogPushEndpoint(url, buildId, username, appName), {
headers: {
Authorization: `Bearer ${token}`,
},
body: Buffer.from(logs),
responseType: 'json',
throwHttpErrors: false,
});
};
@ -232,7 +232,7 @@ export const deployLegacy = async function (
username,
appName,
]);
uploadLogs(...args);
await uploadLogs(...args);
}
return buildId;

View File

@ -15,12 +15,12 @@
* limitations under the License.
*/
import * as _ from 'lodash';
import * as request from 'request';
import type * as Stream from 'stream';
import { retry } from '../helpers';
import Logger = require('../logger');
import * as ApiErrors from './errors';
import { getBalenaSdk } from '../lazy';
import type { BalenaSDK } from 'balena-sdk';
export interface DeviceResponse {
[key: string]: any;
@ -80,9 +80,9 @@ export class DeviceAPI {
}
// Either return nothing, or throw an error with the info
public async setTargetState(state: any): Promise<void> {
public async setTargetState(state: Record<string, any>) {
const url = this.getUrlForAction('setTargetState');
return DeviceAPI.promisifiedRequest(
await DeviceAPI.sendRequest(
{
method: 'POST',
url,
@ -96,37 +96,37 @@ export class DeviceAPI {
public async getTargetState() {
const url = this.getUrlForAction('getTargetState');
return DeviceAPI.promisifiedRequest(
return await DeviceAPI.sendRequest(
{
method: 'GET',
url,
json: true,
},
this.logger,
).then((body) => {
return body.state;
).then(({ state }: { state: Record<string, any> }) => {
return state;
});
}
public async getDeviceInformation(): Promise<DeviceInfo> {
public async getDeviceInformation() {
const url = this.getUrlForAction('getDeviceInformation');
return DeviceAPI.promisifiedRequest(
return await DeviceAPI.sendRequest(
{
method: 'GET',
url,
json: true,
},
this.logger,
).then((body) => {
return body.info;
).then(({ info }: { info: DeviceInfo }) => {
return info;
});
}
public async getContainerId(serviceName: string): Promise<string> {
const url = this.getUrlForAction('containerId');
const body = await DeviceAPI.promisifiedRequest(
const body = await DeviceAPI.sendRequest(
{
method: 'GET',
url,
@ -146,10 +146,10 @@ export class DeviceAPI {
return body.containerId;
}
public async ping(): Promise<void> {
public async ping() {
const url = this.getUrlForAction('ping');
return DeviceAPI.promisifiedRequest(
await DeviceAPI.sendRequest(
{
method: 'GET',
url,
@ -158,10 +158,10 @@ export class DeviceAPI {
);
}
public getVersion(): Promise<string> {
public async getVersion(): Promise<string> {
const url = this.getUrlForAction('version');
return DeviceAPI.promisifiedRequest({
return await DeviceAPI.sendRequest({
method: 'GET',
url,
json: true,
@ -176,10 +176,10 @@ export class DeviceAPI {
});
}
public getStatus(): Promise<Status> {
public async getStatus() {
const url = this.getUrlForAction('status');
return DeviceAPI.promisifiedRequest({
return await DeviceAPI.sendRequest({
method: 'GET',
url,
json: true,
@ -194,96 +194,60 @@ export class DeviceAPI {
});
}
public getLogStream(): Promise<Stream.Readable> {
public async getLogStream() {
const url = this.getUrlForAction('logs');
const sdk = getBalenaSdk();
// Don't use the promisified version here as we want to stream the output
return new Promise((resolve, reject) => {
const req = request.get(url);
req.on('error', reject).on('response', (res) => {
if (res.statusCode !== 200) {
reject(
new ApiErrors.DeviceAPIError(
'Non-200 response from log streaming endpoint',
),
);
return;
}
try {
res.socket.setKeepAlive(true, 1000);
} catch (error) {
reject(error as Error);
}
resolve(res);
});
const stream = await sdk.request.stream({ url });
stream.on('response', (res) => {
if (res.statusCode !== 200) {
throw new ApiErrors.DeviceAPIError(
'Non-200 response from log streaming endpoint',
);
}
res.socket.setKeepAlive(true, 1000);
});
return stream;
}
private getUrlForAction(action: keyof typeof deviceEndpoints): string {
private getUrlForAction(action: keyof typeof deviceEndpoints) {
return `${this.deviceAddress}${deviceEndpoints[action]}`;
}
// A helper method for promisifying general (non-streaming) requests. Streaming
// requests should use a seperate setup
private static async promisifiedRequest<
T extends Parameters<typeof request>[0],
>(opts: T, logger?: Logger): Promise<any> {
interface ObjectWithUrl {
url?: string;
}
if (logger != null) {
let url: string | null = null;
if (_.isObject(opts) && (opts as ObjectWithUrl).url != null) {
// the `as string` shouldn't be necessary, but the type system
// is getting a little confused
url = (opts as ObjectWithUrl).url!;
} else if (typeof opts === 'string') {
url = opts;
}
if (url != null) {
logger.logDebug(`Sending request to ${url}`);
}
private static async sendRequest(
opts: Parameters<BalenaSDK['request']['send']>[number],
logger?: Logger,
) {
if (logger != null && opts.url != null) {
logger.logDebug(`Sending request to ${opts.url}`);
}
const sdk = getBalenaSdk();
const doRequest = async () => {
return await new Promise((resolve, reject) => {
return request(opts, (err, response, body) => {
if (err) {
reject(err as Error);
return;
}
switch (response.statusCode) {
case 200: {
resolve(body);
return;
}
case 400: {
reject(new ApiErrors.BadRequestDeviceAPIError(body.message));
return;
}
case 503: {
reject(new ApiErrors.ServiceUnavailableAPIError(body.message));
return;
}
default: {
reject(new ApiErrors.DeviceAPIError(body.message));
return;
}
}
});
});
const response = await sdk.request.send(opts);
const bodyError =
typeof response.body === 'string'
? response.body
: response.body.message;
switch (response.statusCode) {
case 200:
return response.body;
case 400:
throw new ApiErrors.BadRequestDeviceAPIError(bodyError);
case 503:
throw new ApiErrors.ServiceUnavailableAPIError(bodyError);
default:
new ApiErrors.DeviceAPIError(bodyError);
}
};
return await retry({
func: doRequest,
initialDelayMs: 2000,
maxAttempts: 6,
label: `Supervisor API (${opts.method} ${(opts as any).url})`,
label: `Supervisor API (${opts.method} ${opts.url})`,
});
}
}
export default DeviceAPI;

View File

@ -603,11 +603,11 @@ function getImageNameFromTask(task: BuildTask): string {
}
export function generateTargetState(
currentTargetState: any,
currentTargetState: Record<string, any>,
composition: Composition,
buildTasks: BuildTask[],
env: ParsedEnvironment,
): any {
) {
const keyedBuildTasks = _.keyBy(buildTasks, 'serviceName');
const services: { [serviceId: string]: any } = {};

View File

@ -28,7 +28,7 @@ import { instanceOf } from '../../errors';
import Logger = require('../logger');
import { Dockerfile } from 'livepush';
import type DeviceAPI from './api';
import type { DeviceAPI } from './api';
import type { DeviceInfo, Status } from './api';
import type { DeviceDeployOptions } from './deploy';
import { generateTargetState, rebuildSingleTask } from './deploy';

View File

@ -110,6 +110,27 @@ export async function getManifest(
const init = await import('balena-device-init');
const sdk = getBalenaSdk();
const manifest = await init.getImageManifest(image);
if (manifest != null) {
const config = manifest.configuration?.config;
if (config?.partition != null) {
const { getBootPartition } = await import('balena-config-json');
// Find the device-type.json property that holds the boot partition number for
// this device type (config.partition or config.partition.primary) and overwrite it
// with the boot partition number that was found by inspecting the image.
// since it's deprecated & no longer updated for newer releases.
if (typeof config.partition === 'number') {
config.partition = await getBootPartition(image);
} else if (config.partition.primary != null) {
config.partition.primary = await getBootPartition(image);
}
// TODO: Add handling for when we no longer include a `config.partition` at all.
}
} else {
// TODO: Change this in the next major to throw, after confirming that this works for all supported OS versions.
console.error(
`[warn] Error while finding a device-type.json on the provided image path. Attempting to fetch from the API.`,
);
}
if (
manifest != null &&
manifest.slug !== deviceType &&

View File

@ -0,0 +1,69 @@
/**
* @license
* Copyright 2025 Balena Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Utilities to explore the contents in a balenaOS image.
import * as imagefs from 'balena-image-fs';
import * as filedisk from 'file-disk';
import { getPartitions } from 'partitioninfo';
import type * as Fs from 'fs';
/**
* @summary IDs for the standard balenaOS partitions
* @description Values are the base name for a partition on disk
*/
export enum BalenaPartition {
BOOT = 'boot',
ROOTA = 'rootA',
ROOTB = 'rootB',
STATE = 'state',
DATA = 'data',
}
/**
* @summary Allow a provided function to explore the contents of one of the well-known
* partitions of a balenaOS image
*
* @param {string} imagePath - pathname of image for search
* @param {BalenaPartition} partitionId - partition to find
* @param {(fs) => Promise<T>} - function for exploration
* @returns {T}
*/
export async function explorePartition<T>(
imagePath: string,
partitionId: BalenaPartition,
exploreFn: (fs: typeof Fs) => Promise<T>,
): Promise<T> {
return await filedisk.withOpenFile(imagePath, 'r', async (handle) => {
const disk = new filedisk.FileDisk(handle, true, false, false);
const partitionInfo = await getPartitions(disk, {
includeExtended: false,
getLogical: true,
});
const findResult = await imagefs.findPartition(disk, partitionInfo, [
`resin-${partitionId}`,
`flash-${partitionId}`,
`balena-${partitionId}`,
]);
if (findResult == null) {
throw new Error(`Can't find partition for ${partitionId}`);
}
return await imagefs.interact<T>(disk, findResult.index, exploreFn);
});
}

View File

@ -76,38 +76,28 @@ export const getImagePath = async (deviceType: string, version?: string) => {
};
/**
* @summary Determine if a device image is fresh
* @summary Determine if a device image is cached
*
* @description
* If the device image does not exist, return false.
*
* @param {String} deviceType - device type slug or alias
* @param {String} version - the exact balenaOS version number
* @returns {Promise<Boolean>} is image fresh
* @returns {Promise<Boolean>} is image cached
*
* @example
* isImageFresh('raspberry-pi', '1.2.3').then (isFresh) ->
* if isFresh
* console.log('The Raspberry Pi image v1.2.3 is fresh!')
* isImageCached ('raspberry-pi', '1.2.3').then (isCached) ->
* if isCached
* console.log('The Raspberry Pi image v1.2.3 is cached!')
*/
export const isImageFresh = async (deviceType: string, version: string) => {
export const isImageCached = async (deviceType: string, version: string) => {
const imagePath = await getImagePath(deviceType, version);
let createdDate;
try {
createdDate = await getFileCreatedDate(imagePath);
const createdDate = await getFileCreatedDate(imagePath);
return createdDate != null;
} catch {
// Swallow errors from getFileCreatedTime.
}
if (createdDate == null) {
return false;
}
const balena = getBalenaSdk();
const lastModifiedDate = await balena.models.os.getLastModified(
deviceType,
version,
);
return lastModifiedDate < createdDate;
};
/**
@ -286,7 +276,7 @@ export const getStream = async (
versionOrRange = 'latest';
}
const version = await resolveVersion(deviceType, versionOrRange);
const isFresh = await isImageFresh(deviceType, version);
const isFresh = await isImageCached(deviceType, version);
const $stream = isFresh
? await getImage(deviceType, version)
: await doDownload({ ...options, deviceType, version });

View File

@ -21,6 +21,7 @@ import type { Chalk } from 'chalk';
import type * as visuals from 'resin-cli-visuals';
import type * as CliForm from 'resin-cli-form';
import type { ux } from '@oclif/core';
import { version } from '../../package.json';
// Equivalent of _.once but avoiding the need to import lodash for lazy deps
const once = <T>(fn: () => T) => {
@ -43,9 +44,26 @@ export const onceAsync = <T>(fn: () => Promise<T>) => {
};
};
export const getBalenaSdk = once(() =>
(require('balena-sdk') as typeof BalenaSdk).fromSharedOptions(),
);
const cliXBalenaClientHeaderInterceptor: BalenaSdk.Interceptor = {
request($request) {
if ($request.headers['X-Balena-Client']) {
// We intentionally overwrite the sdk version string from the header
// to conserve bandwidth. We only do that when the SDK already has specified
// the X-Balena-Client header, since that signals that this is a safe url to
// include the extra header and will not cause CORS errors.
$request.headers['X-Balena-Client'] = `balena-cli/${version}`;
}
return $request;
},
};
export const getBalenaSdk = once(() => {
const sdk = (require('balena-sdk') as typeof BalenaSdk).fromSharedOptions();
if (!sdk.interceptors.includes(cliXBalenaClientHeaderInterceptor)) {
sdk.interceptors.push(cliXBalenaClientHeaderInterceptor);
}
return sdk;
});
export const getVisuals = once(
() => require('resin-cli-visuals') as typeof visuals,

View File

@ -159,9 +159,9 @@ especially discouraged in scripts (e.g. CI environments).`;
export const devModeInfo = `\
The '--dev' option is used to configure balenaOS to operate in development mode,
allowing anauthenticated root ssh access and exposing network ports such as
allowing unauthenticated root ssh access and exposing network ports such as
balenaEngine's 2375 (unencrypted). This option causes \`"developmentMode": true\`
to be inserted in the 'config.json' file in the image's boot partion. Development
to be inserted in the 'config.json' file in the image's boot partition. Development
mode (as a configurable option) is applicable to balenaOS releases from early
2022. Older releases have separate development and production balenaOS images
that cannot be reconfigured through 'config.json' or the '--dev' option. Do not

View File

@ -50,7 +50,7 @@ export function copyQemu(context: string, arch: string) {
.then(() => getQemuPath(arch))
.then(
(qemu) =>
new Promise(function (resolve, reject) {
new Promise<void>(function (resolve, reject) {
const read = fs.createReadStream(qemu);
const write = fs.createWriteStream(binPath);
@ -94,7 +94,7 @@ async function installQemu(arch: string, qemuPath: string) {
const urlVersion = encodeURIComponent(QEMU_VERSION);
const qemuUrl = `https://github.com/balena-io/qemu/releases/download/${urlVersion}/${urlFile}`;
const request = await import('request');
const { default: got } = await import('got');
const fs = await import('fs');
const zlib = await import('zlib');
const tar = await import('tar-stream');
@ -117,7 +117,8 @@ async function installQemu(arch: string, qemuPath: string) {
reject(err as Error);
}
});
request(qemuUrl)
got.stream
.get(qemuUrl)
.on('error', reject)
.pipe(zlib.createGunzip())
.on('error', reject)

View File

@ -16,7 +16,8 @@ limitations under the License.
import type { BalenaSDK } from 'balena-sdk';
import * as JSONStream from 'JSONStream';
import * as readline from 'readline';
import * as request from 'request';
import type { PlainResponse } from 'got';
import type got from 'got';
import type { RegistrySecrets } from '@balena/compose/dist/multibuild';
import type * as Stream from 'stream';
import streamToPromise = require('stream-to-promise');
@ -119,7 +120,7 @@ export async function startRemoteBuild(
} catch (err) {
console.error(err.message);
} finally {
buildRequest.abort();
buildRequest.destroy();
const sigintErr = new SIGINTError('Build aborted on SIGINT signal');
sigintErr.code = 'SIGINT';
stream.emit('error', sigintErr);
@ -337,32 +338,29 @@ async function getTarStream(build: RemoteBuild): Promise<Stream.Readable> {
/**
* Initiate a POST HTTP request to the remote builder and add some event
* listeners.
*
* ¡! Note: this function must be synchronous because of a bug in the `request`
* library that requires the following two steps to take place in the same
* iteration of Node's event loop: (1) adding a listener for the 'response'
* event and (2) calling request.pipe():
* https://github.com/request/request/issues/887
*/
function createRemoteBuildRequest(
async function createRemoteBuildRequest(
build: RemoteBuild,
tarStream: Stream.Readable,
builderUrl: string,
onError: (error: Error) => void,
): request.Request {
const zlib = require('zlib') as typeof import('zlib');
) {
const { default: got } = await import('got');
const zlib = await import('zlib');
if (DEBUG_MODE) {
console.error(`[debug] Connecting to builder at ${builderUrl}`);
}
return request
.post({
url: builderUrl,
auth: { bearer: build.auth },
headers: { 'Content-Encoding': 'gzip' },
return got.stream
.post(builderUrl, {
headers: {
Authorization: `Bearer ${build.auth}`,
'Content-Encoding': 'gzip',
},
body: tarStream.pipe(zlib.createGzip({ level: 6 })),
throwHttpErrors: false,
})
.once('error', onError) // `.once` because the handler re-emits
.once('response', (response: request.RequestResponse) => {
.once('response', (response: PlainResponse) => {
if (response.statusCode >= 100 && response.statusCode < 400) {
if (DEBUG_MODE) {
console.error(
@ -374,8 +372,8 @@ function createRemoteBuildRequest(
'Remote builder responded with HTTP error:',
`${response.statusCode} ${response.statusMessage}`,
];
if (response.body) {
msgArr.push(response.body);
if (response.rawBody) {
msgArr.push(response.rawBody.toString());
}
onError(new ExpectedError(msgArr.join('\n')));
}
@ -384,7 +382,7 @@ function createRemoteBuildRequest(
async function getRemoteBuildStream(
build: RemoteBuild,
): Promise<[request.Request, Stream.Stream]> {
): Promise<[ReturnType<typeof got.stream.post>, Stream.Stream]> {
const builderUrl = await getBuilderEndpoint(
build.baseUrl,
build.appSlug,
@ -412,7 +410,7 @@ async function getRemoteBuildStream(
}
const tarStream = await getTarStream(build);
const buildRequest = createRemoteBuildRequest(
const buildRequest = await createRemoteBuildRequest(
build,
tarStream,
builderUrl,

View File

@ -20,7 +20,7 @@ import * as chaiAsPromised from 'chai-as-promised';
import * as ejs from 'ejs';
import * as fs from 'fs';
import * as path from 'path';
import * as request from 'request';
import got from 'got';
import * as sinon from 'sinon';
import { LoginServer } from '../../build/auth/server';
@ -61,38 +61,30 @@ describe('Login server:', function () {
server.shutdown();
});
async function testLogin(opt: {
async function testLogin({
verb = 'post',
...opt
}: {
expectedBody: string;
expectedErrorMsg?: string;
expectedStatusCode: number;
expectedToken: string;
urlPath?: string;
verb?: string;
verb?: 'post' | 'put';
}) {
opt.urlPath = opt.urlPath ?? addr.urlPath;
const post = opt.verb
? ((request as any)[opt.verb] as typeof request.post)
: request.post;
await new Promise<void>((resolve, reject) => {
post(
`http://${addr.host}:${addr.port}${opt.urlPath}`,
{
form: {
token: opt.expectedToken,
},
const res = await got[verb](
`http://${addr.host}:${addr.port}${opt.urlPath}`,
{
form: {
token: opt.expectedToken,
},
function (error, response, body) {
try {
expect(error).to.not.exist;
expect(response.statusCode).to.equal(opt.expectedStatusCode);
expect(body).to.equal(opt.expectedBody);
resolve();
} catch (err) {
reject(err as Error);
}
},
);
});
throwHttpErrors: false,
},
);
expect(res.body).to.equal(opt.expectedBody);
expect(res.statusCode).to.equal(opt.expectedStatusCode);
try {
const token = await server.awaitForToken();
@ -127,7 +119,7 @@ describe('Login server:', function () {
expectedStatusCode: 404,
expectedToken: tokens.johndoe.token,
expectedErrorMsg: 'Unknown path or verb',
verb: 'get',
verb: 'put',
});
});

View File

@ -442,6 +442,93 @@ describe('balena build', function () {
});
});
it('should create the expected tar stream (docker-compose --nologs)', async () => {
const projectPath = path.join(projectsPath, 'docker-compose', 'basic');
const service1Dockerfile = (
await fs.readFile(
path.join(projectPath, 'service1', 'Dockerfile.template'),
'utf8',
)
).replace('%%BALENA_MACHINE_NAME%%', 'nuc');
const expectedFilesByService: ExpectedTarStreamFilesByService = {
service1: {
Dockerfile: {
contents: service1Dockerfile,
fileSize: service1Dockerfile.length,
type: 'file',
},
'Dockerfile.template': { fileSize: 144, type: 'file' },
'file1.sh': { fileSize: 12, type: 'file' },
},
service2: {
'Dockerfile-alt': { fileSize: 13, type: 'file' },
'file2-crlf.sh': {
fileSize: isWindows ? 12 : 14,
testStream: isWindows ? expectStreamNoCRLF : undefined,
type: 'file',
},
'src/file1.sh': { fileSize: 12, type: 'file' },
},
};
const responseFilename = 'build-POST.json';
const responseBody = await fs.readFile(
path.join(dockerResponsePath, responseFilename),
'utf8',
);
const expectedQueryParamsByService = {
service1: Object.entries(
_.merge({}, commonComposeQueryParams, {
buildargs: {
COMPOSE_ARG: 'A',
barg: 'b',
SERVICE1_VAR: 'This is a service specific variable',
},
cachefrom: ['my/img1', 'my/img2'],
}),
),
service2: Object.entries(
_.merge({}, commonComposeQueryParamsIntel, {
buildargs: {
COMPOSE_ARG: 'A',
barg: 'b',
},
cachefrom: ['my/img1', 'my/img2'],
dockerfile: 'Dockerfile-alt',
}),
),
};
const expectedResponseLines: string[] = [
...commonResponseLines[responseFilename],
...getDockerignoreWarn1(
[path.join(projectPath, 'service2', '.dockerignore')],
'build',
),
];
if (isWindows) {
expectedResponseLines.push(
`[Info] Converting line endings CRLF -> LF for file: ${path.join(
projectPath,
'service2',
'file2-crlf.sh',
)}`,
);
}
docker.expectGetInfo({});
docker.expectGetManifestNucAlpine();
docker.expectGetManifestBusybox();
await testDockerBuildStream({
commandLine: `build ${projectPath} --deviceType nuc --arch amd64 -B COMPOSE_ARG=A -B barg=b --cache-from my/img1,my/img2 --nologs`,
dockerMock: docker,
expectedFilesByService,
expectedQueryParamsByService,
expectedResponseLines,
projectPath,
responseBody,
responseCode: 200,
services: ['service1', 'service2'],
});
});
it('should create the expected tar stream (docker-compose, --multi-dockerignore)', async () => {
const projectPath = path.join(projectsPath, 'docker-compose', 'basic');
const service1Dockerfile = (

View File

@ -27,7 +27,7 @@ import * as sinon from 'sinon';
import { BalenaAPIMock } from '../nock/balena-api-mock';
import { expectStreamNoCRLF, testDockerBuildStream } from '../docker-build';
import { DockerMock, dockerResponsePath } from '../nock/docker-mock';
import { cleanOutput, runCommand, switchSentry } from '../helpers';
import { cleanOutput, runCommand } from '../helpers';
import type {
ExpectedTarStreamFiles,
ExpectedTarStreamFilesByService,
@ -262,7 +262,6 @@ describe('balena deploy', function () {
});
it('should update a release with status="failed" on error (single container)', async () => {
let sentryStatus: boolean | undefined;
const projectPath = path.join(projectsPath, 'no-docker-compose', 'basic');
const expectedFiles: ExpectedTarStreamFiles = {
'src/.dockerignore': { fileSize: 16, type: 'file' },
@ -319,7 +318,6 @@ describe('balena deploy', function () {
api.expectPostImageLabel();
try {
sentryStatus = await switchSentry(false);
sinon.stub(process, 'exit');
await testDockerBuildStream({
@ -337,9 +335,8 @@ describe('balena deploy', function () {
});
expect(failedImagePatchRequests).to.equal(maxRequestRetries);
} finally {
await switchSentry(sentryStatus);
// @ts-expect-error claims restore does not exist
process.exit.restore();
// We mock process.exit and need to force cast it to a SinonStub to restore it
(process.exit as unknown as sinon.SinonStub).restore();
}
});

View File

@ -114,6 +114,14 @@ describe('balena device', function () {
'Content-Type': 'application/json',
});
api.scope
.get(
/^\/v\d+\/device\?.+&\$select=overall_status,overall_progress,should_be_running__release$/,
)
.replyWithFile(200, path.join(apiResponsePath, 'device.json'), {
'Content-Type': 'application/json',
});
const { out, err } = await runCommand('device 27fda508c --json');
expect(err).to.be.empty;
const json = JSON.parse(out.join(''));

View File

@ -21,8 +21,6 @@ import { BalenaAPIMock } from '../../nock/balena-api-mock';
import { cleanOutput, runCommand } from '../../helpers';
import { SupervisorMock } from '../../nock/supervisor-mock';
const itS = process.env.BALENA_CLI_TEST_TYPE === 'standalone' ? it : it.skip;
describe('balena device logs', function () {
let api: BalenaAPIMock;
let supervisor: SupervisorMock;
@ -39,10 +37,7 @@ describe('balena device logs', function () {
supervisor.done();
});
// skip non-standalone tests because nock's mock socket causes the error:
// "setKeepAliveInterval expects an instance of socket as its first argument"
// in utils/device/api.ts: NetKeepalive.setKeepAliveInterval(sock, 5000);
itS('should reach the expected endpoints on a local device', async () => {
it('should reach the expected endpoints on a local device', async () => {
supervisor.expectGetPing();
supervisor.expectGetLogs();
supervisor.expectGetLogs();

View File

@ -21,6 +21,8 @@ import * as process from 'process';
import { runCommand } from '../../helpers';
import { promisify } from 'util';
import * as tmp from 'tmp';
import type * as $imagefs from 'balena-image-fs';
import * as stripIndent from 'common-tags/lib/stripIndent';
tmp.setGracefulCleanup();
const tmpNameAsync = promisify(tmp.tmpName);
@ -29,30 +31,94 @@ import { BalenaAPIMock } from '../../nock/balena-api-mock';
if (process.platform !== 'win32') {
describe('balena os configure', function () {
let imagefs: typeof $imagefs;
let api: BalenaAPIMock;
let tmpPath: string;
let tmpDummyPath: string;
let tmpMatchingDtJsonPartitionPath: string;
let tmpNonMatchingDtJsonPartitionPath: string;
beforeEach(async () => {
before(async function () {
// We conditionally import balena-image-fs, since when imported on top level then unrelated tests on win32 failed with:
// EPERM: operation not permitted, rename 'C:\Users\RUNNER~1\AppData\Local\Temp\tmp-<...>.inprogress' -> 'C:\Users\RUNNER~1\AppData\Local\Temp\tmp-<...>'
// at async Object.rename (node:internal/fs/promises:782:10) {
imagefs = await import('balena-image-fs');
tmpDummyPath = (await tmpNameAsync()) as string;
await fs.copyFile('./tests/test-data/dummy.img', tmpDummyPath);
tmpMatchingDtJsonPartitionPath = (await tmpNameAsync()) as string;
await fs.copyFile(
'./tests/test-data/mock-jetson-nano-6.0.13.with-boot-partition-12.img',
tmpMatchingDtJsonPartitionPath,
);
tmpNonMatchingDtJsonPartitionPath = (await tmpNameAsync()) as string;
// Create an image with a device-type.json that mentions a non matching boot partition.
// We copy the pre-existing image and modify it, since including a separate one
// would add 18MB more to the repository.
await fs.copyFile(
'./tests/test-data/mock-jetson-nano-6.0.13.with-boot-partition-12.img',
tmpNonMatchingDtJsonPartitionPath,
);
await imagefs.interact(
tmpNonMatchingDtJsonPartitionPath,
12,
async (_fs) => {
const dtJson = JSON.parse(
await _fs.promises.readFile('/device-type.json', {
encoding: 'utf8',
}),
);
expect(dtJson).to.have.nested.property(
'configuration.config.partition',
12,
);
dtJson.configuration.config.partition = 999;
await _fs.promises.writeFile(
'/device-type.json',
JSON.stringify(dtJson),
);
await _fs.promises.writeFile(
'/os-release',
stripIndent`
ID="balena-os"
NAME="balenaOS"
VERSION="6.1.25"
VERSION_ID="6.1.25"
PRETTY_NAME="balenaOS 6.1.25"
DISTRO_CODENAME="kirkstone"
MACHINE="jetson-nano"
META_BALENA_VERSION="6.1.25"`,
);
},
);
});
beforeEach(() => {
api = new BalenaAPIMock();
api.expectGetWhoAmI({ optional: true, persist: true });
tmpPath = (await tmpNameAsync()) as string;
await fs.copyFile('./tests/test-data/dummy.img', tmpPath);
});
afterEach(async () => {
afterEach(() => {
api.done();
await fs.unlink(tmpPath);
});
it('should inject a valid config.json file', async () => {
after(async () => {
await fs.unlink(tmpDummyPath);
await fs.unlink(tmpMatchingDtJsonPartitionPath);
await fs.unlink(tmpNonMatchingDtJsonPartitionPath);
});
it('should detect the OS version and inject a valid config.json file to a 6.0.13 image with partition 12 as boot & matching device-type.json', async () => {
api.expectGetApplication();
api.expectGetConfigDeviceTypes();
api.expectGetDeviceTypes();
// It should not reach to /config or /device-types/v1 but instead find
// everything required from the device-type.json in the image.
// api.expectGetConfigDeviceTypes();
api.expectDownloadConfig();
const command: string[] = [
`os configure ${tmpPath}`,
'--device-type raspberrypi3',
'--version 2.47.0+rev1',
`os configure ${tmpMatchingDtJsonPartitionPath}`,
'--device-type jetson-nano',
'--fleet testApp',
'--config-app-update-poll-interval 10',
'--config-network ethernet',
@ -65,9 +131,124 @@ if (process.platform !== 'win32') {
expect(err.join('')).to.equal('');
// confirm the image contains a config.json...
const imagefs = await import('balena-image-fs');
const config = await imagefs.interact(tmpPath, 1, async (_fs) => {
return await promisify(_fs.readFile)('/config.json');
const config = await imagefs.interact(
tmpMatchingDtJsonPartitionPath,
12,
async (_fs) => {
const dtJson = JSON.parse(
await _fs.promises.readFile('/device-type.json', {
encoding: 'utf8',
}),
);
// confirm that the device-type.json mentions the expected partition
expect(dtJson).to.have.nested.property(
'configuration.config.partition',
12,
);
return await _fs.promises.readFile('/config.json');
},
);
expect(config).to.not.be.empty;
// confirm the image has the correct config.json values...
const configObj = JSON.parse(config.toString('utf8'));
expect(configObj).to.have.property('deviceType', 'jetson-nano');
expect(configObj).to.have.property('initialDeviceName', 'testDeviceName');
});
it('should detect the OS version and inject a valid config.json file to a 6.1.25 image with partition 12 as boot & a non-matching device-type.json', async () => {
api.expectGetApplication();
api.expectGetDeviceTypes();
// It should not reach to /config or /device-types/v1 but instead find
// everything required from the device-type.json in the image.
// api.expectGetConfigDeviceTypes();
api.expectDownloadConfig();
const command: string[] = [
`os configure ${tmpNonMatchingDtJsonPartitionPath}`,
'--device-type jetson-nano',
'--fleet testApp',
'--config-app-update-poll-interval 10',
'--config-network ethernet',
'--initial-device-name testDeviceName',
'--provisioning-key-name testKey',
'--provisioning-key-expiry-date 2050-12-12',
];
const { err } = await runCommand(command.join(' '));
expect(err.join('')).to.equal('');
// confirm the image contains a config.json...
const config = await imagefs.interact(
tmpNonMatchingDtJsonPartitionPath,
12,
async (_fs) => {
const dtJson = JSON.parse(
await _fs.promises.readFile('/device-type.json', {
encoding: 'utf8',
}),
);
// confirm that the device-type.json mentions the expected partition
expect(dtJson).to.have.nested.property(
'configuration.config.partition',
999,
);
return await _fs.promises.readFile('/config.json');
},
);
expect(config).to.not.be.empty;
// confirm the image has the correct config.json values...
const configObj = JSON.parse(config.toString('utf8'));
expect(configObj).to.have.property('deviceType', 'jetson-nano');
expect(configObj).to.have.property('initialDeviceName', 'testDeviceName');
});
// TODO: In the next major consider just failing when we can't find a device-types.json in the image.
it('should inject a valid config.json file to a dummy image', async () => {
api.expectGetApplication();
// Since the dummy image doesn't include a device-type.json
// we have to reach to the API to fetch the manifest of the device type.
api.expectGetConfigDeviceTypes();
api.expectDownloadConfig();
const command: string[] = [
`os configure ${tmpDummyPath}`,
'--device-type raspberrypi3',
'--version 2.47.0+rev1',
'--fleet testApp',
'--config-app-update-poll-interval 10',
'--config-network ethernet',
'--initial-device-name testDeviceName',
'--provisioning-key-name testKey',
'--provisioning-key-expiry-date 2050-12-12',
];
const { err } = await runCommand(command.join(' '));
// Once we replace the dummy.img with one that includes a os-release & device-type.json
// then we should be able to change this to expect no errors.
expect(
err.flatMap((line) => line.split('\n')).filter((line) => line !== ''),
).to.deep.equal(
stripIndent`
[warn] "${tmpDummyPath}":
[warn] Found partition table with 1 partitions,
[warn] but none with a name/label in ['resin-boot', 'flash-boot', 'balena-boot'].
[warn] Will scan all partitions for contents.
[warn] "${tmpDummyPath}":
[warn] 1 partition(s) found, but none containing file "/device-type.json".
[warn] Assuming default boot partition number '1'.
[warn] "${tmpDummyPath}":
[warn] Could not find a previous "/config.json" file in partition '1'.
[warn] Proceeding anyway, but this is unexpected.
[warn] Error while finding a device-type.json on the provided image path. Attempting to fetch from the API.`.split(
'\n',
),
);
// confirm the image contains a config.json...
const config = await imagefs.interact(tmpDummyPath, 1, async (_fs) => {
return await _fs.promises.readFile('/config.json');
});
expect(config).to.not.be.empty;

View File

@ -82,7 +82,7 @@ describe('balena release', function () {
expect(err).to.be.empty;
const json = JSON.parse(out.join(''));
expect(json[0].commit).to.equal('90247b54de4fa7a0a3cbc85e73c68039');
expect(json[0].contains__image[0].image[0].start_timestamp).to.equal(
expect(json[0].release_image[0].image[0].start_timestamp).to.equal(
'2020-01-04T01:13:08.583Z',
);
});

View File

@ -17,13 +17,21 @@
import * as _ from 'lodash';
import * as path from 'path';
import * as fs from 'fs';
import { createGunzip } from 'zlib';
import * as packageJSON from '../package.json';
import { getNodeEngineVersionWarn } from '../build/utils/messages';
import { warnify } from '../build/utils/messages';
const balenaExe = process.platform === 'win32' ? 'balena.exe' : 'balena';
const standalonePath = path.resolve(__dirname, '..', 'build-bin', balenaExe);
const standalonePath = path.resolve(
__dirname,
'..',
'dist',
'balena',
'bin',
'balena',
);
export interface TestOutput {
err: string[]; // stderr
@ -164,11 +172,11 @@ async function runCommandInSubprocess(
// override default proxy exclusion to allow proxying of requests to 127.0.0.1
BALENARC_DO_PROXY: '127.0.0.1,localhost',
};
const { execFile } = await import('child_process');
const { exec } = await import('child_process');
await new Promise<void>((resolve) => {
const child = execFile(
standalonePath,
cmd.split(' ').filter((c) => c),
const child = exec(
`${standalonePath} ${cmd}`,
{ env: { ...process.env, ...addedEnvs } },
($error, $stdout, $stderr) => {
stderr = $stderr || '';
@ -213,6 +221,67 @@ ${$error}`;
};
}
async function extractTarStream() {
if (
fs.existsSync(path.join(__dirname, '..', 'dist', 'balena', 'bin', 'balena'))
) {
return;
}
const tar = await import('tar-stream');
const version = 'v' + packageJSON.version;
const arch = process.arch;
const platform =
process.platform === 'win32'
? 'windows'
: process.platform === 'darwin'
? 'macOS'
: process.platform;
const sourceFile = path.join(
__dirname,
'..',
'dist',
`balena-cli-${version}-${platform}-${arch}-standalone.tar.gz`,
);
const destinationDir = path.join(__dirname, '..', 'dist');
const extract = tar.extract();
return new Promise((resolve, reject) => {
extract.on('entry', (header, stream, next) => {
const outputPath = path.join(destinationDir, header.name);
if (header.type === 'directory') {
fs.mkdirSync(outputPath, { recursive: true });
next();
} else {
fs.mkdirSync(path.dirname(outputPath), { recursive: true });
const fileStream = fs.createWriteStream(outputPath);
stream.pipe(fileStream);
fileStream.on('close', () => {
if (header.mode) {
fs.chmodSync(outputPath, header.mode); // Set file permissions
}
next();
});
fileStream.on('error', reject);
}
});
extract.on('finish', resolve);
extract.on('error', reject);
fs.createReadStream(sourceFile)
.pipe(createGunzip())
.pipe(extract)
.on('error', reject);
});
}
/**
* Run a CLI command and capture its stdout, stderr and exit code for testing.
* If the BALENA_CLI_TEST_TYPE env var is set to 'standalone', then the command
@ -223,6 +292,7 @@ ${$error}`;
*/
export async function runCommand(cmd: string): Promise<TestOutput> {
if (process.env.BALENA_CLI_TEST_TYPE === 'standalone') {
await extractTarStream();
const semver = await import('semver');
if (semver.lt(process.version, '10.16.0')) {
throw new Error(
@ -347,15 +417,3 @@ export function deepJsonParse(data: any): any {
}
return data;
}
export async function switchSentry(
enabled: boolean | undefined,
): Promise<boolean | undefined> {
const balenaCLI = await import('../build/app');
const sentryOpts = (await balenaCLI.setupSentry()).getClient()?.getOptions();
if (sentryOpts) {
const sentryStatus = sentryOpts.enabled;
sentryOpts.enabled = enabled;
return sentryStatus;
}
}

View File

@ -61,22 +61,25 @@ export class BalenaAPIMock extends NockMock {
}
public expectDownloadConfig(opts: ScopeOpts = {}) {
this.optPost('/download-config', opts).reply(
200,
JSON.parse(`{
"applicationId":1301645,
"deviceType":"raspberrypi3",
"userId":43699,
"appUpdatePollInterval":600000,
"listenPort":48484,
"vpnPort":443,
"apiEndpoint":"https://api.balena-cloud.com",
"vpnEndpoint":"vpn.balena-cloud.com",
"registryEndpoint":"registry2.balena-cloud.com",
"deltaEndpoint":"https://delta.balena-cloud.com",
"apiKey":"nothingtoseehere"
}`),
);
this.optPost('/download-config', opts).reply(200, (_uri, body) => {
let deviceType = 'raspberrypi3';
if (typeof body === 'object' && 'deviceType' in body) {
deviceType = body.deviceType;
}
return JSON.parse(`{
"applicationId":1301645,
"deviceType":"${deviceType}",
"userId":43699,
"appUpdatePollInterval":600000,
"listenPort":48484,
"vpnPort":443,
"apiEndpoint":"https://api.balena-cloud.com",
"vpnEndpoint":"vpn.balena-cloud.com",
"registryEndpoint":"registry2.balena-cloud.com",
"deltaEndpoint":"https://delta.balena-cloud.com",
"apiKey":"nothingtoseehere"
}`);
});
}
public expectApplicationProvisioning(opts: ScopeOpts = {}) {

View File

@ -41,23 +41,18 @@ export class BuilderMock extends NockMock {
checkBuildRequestBody: (requestBody: string | Buffer) => Promise<void>;
}) {
this.optPost(/^\/v3\/build($|[(?])/, opts).reply(
async function (uri, requestBody, callback) {
let error: Error | null = null;
try {
await opts.checkURI(uri);
if (typeof requestBody === 'string') {
const gzipped = Buffer.from(requestBody, 'hex');
const gunzipped = await gunzipAsync(gzipped);
await opts.checkBuildRequestBody(gunzipped);
} else {
throw new Error(
`unexpected requestBody type "${typeof requestBody}"`,
);
}
} catch (err) {
error = err;
async function (uri, requestBody) {
await opts.checkURI(uri);
if (typeof requestBody === 'string') {
const gzipped = Buffer.from(requestBody, 'hex');
const gunzipped = await gunzipAsync(gzipped);
await opts.checkBuildRequestBody(gunzipped);
return [opts.responseCode, opts.responseBody];
} else {
throw new Error(
`unexpected requestBody type "${typeof requestBody}"`,
);
}
callback(error, [opts.responseCode, opts.responseBody]);
},
);
}

View File

@ -81,21 +81,14 @@ export class DockerMock extends NockMock {
this.optPost(
new RegExp(`^/build\\?(|.+&)${qs.stringify({ t: opts.tag })}&`),
opts,
).reply(async function (uri, requestBody, cb) {
let error: Error | null = null;
try {
await opts.checkURI(uri);
if (typeof requestBody === 'string') {
await opts.checkBuildRequestBody(requestBody);
} else {
throw new Error(
`unexpected requestBody type "${typeof requestBody}"`,
);
}
} catch (err) {
error = err;
).reply(async function (uri, requestBody) {
await opts.checkURI(uri);
if (typeof requestBody === 'string') {
await opts.checkBuildRequestBody(requestBody);
return [opts.responseCode, opts.responseBody];
} else {
throw new Error(`unexpected requestBody type "${typeof requestBody}"`);
}
cb(error, [opts.responseCode, opts.responseBody]);
});
}

View File

@ -10,7 +10,7 @@
"build_log": null,
"start_timestamp": "2021-08-25T22:18:33.624Z",
"end_timestamp": "2021-08-25T22:18:48.820Z",
"contains__image": [
"release_image": [
{
"image": [
{

View File

@ -1,382 +0,0 @@
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/app.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/app.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/help.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/utils/common-args.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/utils/common-flags.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/utils/compose_ts.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/utils/docker.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/utils/env-common.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/utils/helpers.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/utils/lazy.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/api-key/generate.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/api-key/list.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/api-key/revoke.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/app/create.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/block/create.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/index.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/config/generate.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/config/inject.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/config/read.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/config/reconfigure.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/config/write.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/deploy/index.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/deactivate.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/detect.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/identify.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/index.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/init.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/list.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/local-mode.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/logs.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/move.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/note.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/os-update.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/pin.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/public-url.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/purge.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/reboot.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/register.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/rename.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/restart.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/rm.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/shutdown.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/ssh.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/start-service.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/stop-service.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/track-fleet.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/tunnel.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device-type/list.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/env/list.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/env/rename.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/env/rm.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/env/set.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/fleet/create.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/fleet/index.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/fleet/list.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/fleet/pin.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/fleet/purge.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/fleet/rename.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/fleet/restart.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/fleet/rm.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/fleet/track-latest.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/internal/osinit.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/join/index.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/leave/index.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/local/configure.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/local/flash.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/login/index.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/logout/index.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/organization/list.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/os/build-config.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/os/configure.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/os/download.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/os/initialize.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/os/versions.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/preload/index.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/push/index.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/release/finalize.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/release/index.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/release/invalidate.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/release/list.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/release/validate.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/settings/index.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/ssh-key/add.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/ssh-key/index.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/ssh-key/list.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/ssh-key/rm.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/support/index.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/tag/list.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/tag/rm.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/tag/set.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/util/available-drives.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/version/index.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/whoami/index.js
> Warning Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules/open/xdg-open
%2: path-to-executable/xdg-open
> Warning Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules/open/xdg-open
%2: path-to-executable/xdg-open
> Warning Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules/drivelist/build/Release/drivelist.node
%2: path-to-executable/drivelist.node
> Warning Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules/drivelist/scripts/darwin.sh
%2: path-to-executable/drivelist/darwin.sh
> Warning Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules/drivelist/scripts/linux.sh
%2: path-to-executable/drivelist/linux.sh
> Warning Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules/drivelist/scripts/win32.bat
%2: path-to-executable/drivelist/win32.bat
> Warning Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules/drivelist/build/Release/drivelist.node
%2: path-to-executable/drivelist.node
> Warning Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules/drivelist/scripts/darwin.sh
%2: path-to-executable/drivelist/darwin.sh
> Warning Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules/drivelist/scripts/linux.sh
%2: path-to-executable/drivelist/linux.sh
> Warning Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules/drivelist/scripts/win32.bat
%2: path-to-executable/drivelist/win32.bat
> Warning Cannot resolve 'path'
node_modules/@balena/compose/dist/parse/schemas/index.js
Dynamic require may fail at run time, because the requested file
is unknown at compilation time and not included into executable.
Use a string literal as an argument for 'require', or leave it
as is and specify the resolved file name in 'scripts' option.
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/index.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/axios.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/utils.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/adapters/adapters.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/adapters/http.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/adapters/xhr.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/cancel/CancelToken.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/cancel/CanceledError.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/cancel/isCancel.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/core/Axios.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/core/AxiosError.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/core/AxiosHeaders.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/core/InterceptorManager.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/core/buildFullPath.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/core/dispatchRequest.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/core/mergeConfig.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/core/settle.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/core/transformData.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/defaults/index.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/defaults/transitional.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/env/data.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/helpers/AxiosTransformStream.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/helpers/AxiosURLSearchParams.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/helpers/HttpStatusCode.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/helpers/ZlibHeaderTransformStream.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/helpers/bind.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/helpers/buildURL.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/helpers/callbackify.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/helpers/combineURLs.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/helpers/cookies.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/helpers/formDataToJSON.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/helpers/formDataToStream.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/helpers/fromDataURI.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/helpers/isAbsoluteURL.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/helpers/isAxiosError.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/helpers/isURLSameOrigin.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/helpers/parseHeaders.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/helpers/parseProtocol.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/helpers/readBlob.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/helpers/speedometer.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/helpers/spread.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/helpers/throttle.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/helpers/toFormData.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/helpers/toURLEncodedForm.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/helpers/validator.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/platform/index.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/platform/common/utils.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/platform/node/index.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/platform/node/classes/FormData.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/platform/node/classes/URLSearchParams.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/form-data-encoder/lib/index.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/formdata-node/lib/form-data.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/@isaacs/cliui/node_modules/string-width/index.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/@isaacs/cliui/node_modules/strip-ansi/index.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/@isaacs/cliui/node_modules/wrap-ansi/index.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/@isaacs/cliui/node_modules/ansi-regex/index.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/@isaacs/cliui/node_modules/ansi-styles/index.js

View File

@ -1,382 +0,0 @@
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/app.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/app.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/help.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/utils/common-args.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/utils/common-flags.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/utils/compose_ts.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/utils/docker.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/utils/env-common.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/utils/helpers.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/utils/lazy.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/api-key/generate.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/api-key/list.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/api-key/revoke.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/app/create.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/block/create.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/index.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/config/generate.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/config/inject.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/config/read.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/config/reconfigure.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/config/write.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/deploy/index.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/deactivate.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/detect.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/identify.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/index.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/init.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/list.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/local-mode.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/logs.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/move.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/note.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/os-update.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/pin.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/public-url.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/purge.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/reboot.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/register.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/rename.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/restart.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/rm.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/shutdown.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/ssh.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/start-service.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/stop-service.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/track-fleet.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/tunnel.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device-type/list.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/env/list.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/env/rename.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/env/rm.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/env/set.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/fleet/create.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/fleet/index.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/fleet/list.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/fleet/pin.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/fleet/purge.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/fleet/rename.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/fleet/restart.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/fleet/rm.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/fleet/track-latest.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/internal/osinit.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/join/index.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/leave/index.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/local/configure.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/local/flash.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/login/index.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/logout/index.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/organization/list.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/os/build-config.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/os/configure.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/os/download.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/os/initialize.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/os/versions.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/preload/index.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/push/index.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/release/finalize.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/release/index.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/release/invalidate.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/release/list.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/release/validate.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/settings/index.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/ssh-key/add.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/ssh-key/index.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/ssh-key/list.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/ssh-key/rm.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/support/index.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/tag/list.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/tag/rm.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/tag/set.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/util/available-drives.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/version/index.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/whoami/index.js
> Warning Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules/open/xdg-open
%2: path-to-executable/xdg-open
> Warning Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules/open/xdg-open
%2: path-to-executable/xdg-open
> Warning Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules/drivelist/build/Release/drivelist.node
%2: path-to-executable/drivelist.node
> Warning Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules/drivelist/scripts/darwin.sh
%2: path-to-executable/drivelist/darwin.sh
> Warning Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules/drivelist/scripts/linux.sh
%2: path-to-executable/drivelist/linux.sh
> Warning Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules/drivelist/scripts/win32.bat
%2: path-to-executable/drivelist/win32.bat
> Warning Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules/drivelist/build/Release/drivelist.node
%2: path-to-executable/drivelist.node
> Warning Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules/drivelist/scripts/darwin.sh
%2: path-to-executable/drivelist/darwin.sh
> Warning Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules/drivelist/scripts/linux.sh
%2: path-to-executable/drivelist/linux.sh
> Warning Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules/drivelist/scripts/win32.bat
%2: path-to-executable/drivelist/win32.bat
> Warning Cannot resolve 'path'
node_modules/@balena/compose/dist/parse/schemas/index.js
Dynamic require may fail at run time, because the requested file
is unknown at compilation time and not included into executable.
Use a string literal as an argument for 'require', or leave it
as is and specify the resolved file name in 'scripts' option.
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/index.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/axios.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/utils.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/adapters/adapters.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/adapters/http.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/adapters/xhr.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/cancel/CancelToken.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/cancel/CanceledError.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/cancel/isCancel.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/core/Axios.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/core/AxiosError.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/core/AxiosHeaders.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/core/InterceptorManager.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/core/buildFullPath.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/core/dispatchRequest.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/core/mergeConfig.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/core/settle.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/core/transformData.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/defaults/index.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/defaults/transitional.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/env/data.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/AxiosTransformStream.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/AxiosURLSearchParams.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/HttpStatusCode.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/ZlibHeaderTransformStream.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/bind.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/buildURL.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/callbackify.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/combineURLs.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/cookies.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/formDataToJSON.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/formDataToStream.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/fromDataURI.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/isAbsoluteURL.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/isAxiosError.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/isURLSameOrigin.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/parseHeaders.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/parseProtocol.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/readBlob.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/speedometer.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/spread.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/throttle.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/toFormData.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/toURLEncodedForm.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/validator.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/platform/index.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/platform/common/utils.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/platform/node/index.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/platform/node/classes/FormData.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/platform/node/classes/URLSearchParams.js
> Warning Failed to make bytecode node20-x64 for file node_modules/form-data-encoder/lib/index.js
> Warning Failed to make bytecode node20-x64 for file node_modules/formdata-node/lib/form-data.js
> Warning Failed to make bytecode node20-x64 for file node_modules/@isaacs/cliui/node_modules/string-width/index.js
> Warning Failed to make bytecode node20-x64 for file node_modules/@isaacs/cliui/node_modules/strip-ansi/index.js
> Warning Failed to make bytecode node20-x64 for file node_modules/@isaacs/cliui/node_modules/wrap-ansi/index.js
> Warning Failed to make bytecode node20-x64 for file node_modules/@isaacs/cliui/node_modules/ansi-regex/index.js
> Warning Failed to make bytecode node20-x64 for file node_modules/@isaacs/cliui/node_modules/ansi-styles/index.js

View File

@ -1,382 +0,0 @@
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/app.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/app.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/help.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/utils/common-args.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/utils/common-flags.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/utils/compose_ts.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/utils/docker.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/utils/env-common.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/utils/helpers.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/utils/lazy.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/api-key/generate.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/api-key/list.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/api-key/revoke.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/app/create.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/block/create.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/index.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/config/generate.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/config/inject.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/config/read.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/config/reconfigure.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/config/write.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/deploy/index.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/deactivate.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/detect.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/identify.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/index.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/init.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/list.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/local-mode.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/logs.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/move.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/note.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/os-update.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/pin.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/public-url.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/purge.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/reboot.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/register.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/rename.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/restart.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/rm.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/shutdown.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/ssh.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/start-service.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/stop-service.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/track-fleet.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/tunnel.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device-type/list.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/env/list.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/env/rename.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/env/rm.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/env/set.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/fleet/create.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/fleet/index.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/fleet/list.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/fleet/pin.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/fleet/purge.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/fleet/rename.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/fleet/restart.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/fleet/rm.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/fleet/track-latest.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/internal/osinit.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/join/index.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/leave/index.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/local/configure.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/local/flash.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/login/index.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/logout/index.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/organization/list.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/os/build-config.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/os/configure.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/os/download.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/os/initialize.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/os/versions.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/preload/index.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/push/index.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/release/finalize.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/release/index.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/release/invalidate.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/release/list.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/release/validate.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/settings/index.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/ssh-key/add.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/ssh-key/index.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/ssh-key/list.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/ssh-key/rm.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/support/index.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/tag/list.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/tag/rm.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/tag/set.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/util/available-drives.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/version/index.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/whoami/index.js
> Warning Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules/open/xdg-open
%2: path-to-executable/xdg-open
> Warning Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules/open/xdg-open
%2: path-to-executable/xdg-open
> Warning Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules/drivelist/build/Release/drivelist.node
%2: path-to-executable/drivelist.node
> Warning Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules/drivelist/scripts/darwin.sh
%2: path-to-executable/drivelist/darwin.sh
> Warning Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules/drivelist/scripts/linux.sh
%2: path-to-executable/drivelist/linux.sh
> Warning Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules/drivelist/scripts/win32.bat
%2: path-to-executable/drivelist/win32.bat
> Warning Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules/drivelist/build/Release/drivelist.node
%2: path-to-executable/drivelist.node
> Warning Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules/drivelist/scripts/darwin.sh
%2: path-to-executable/drivelist/darwin.sh
> Warning Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules/drivelist/scripts/linux.sh
%2: path-to-executable/drivelist/linux.sh
> Warning Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules/drivelist/scripts/win32.bat
%2: path-to-executable/drivelist/win32.bat
> Warning Cannot resolve 'path'
node_modules/@balena/compose/dist/parse/schemas/index.js
Dynamic require may fail at run time, because the requested file
is unknown at compilation time and not included into executable.
Use a string literal as an argument for 'require', or leave it
as is and specify the resolved file name in 'scripts' option.
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/index.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/axios.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/utils.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/adapters/adapters.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/adapters/http.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/adapters/xhr.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/cancel/CancelToken.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/cancel/CanceledError.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/cancel/isCancel.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/core/Axios.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/core/AxiosError.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/core/AxiosHeaders.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/core/InterceptorManager.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/core/buildFullPath.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/core/dispatchRequest.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/core/mergeConfig.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/core/settle.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/core/transformData.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/defaults/index.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/defaults/transitional.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/env/data.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/helpers/AxiosTransformStream.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/helpers/AxiosURLSearchParams.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/helpers/HttpStatusCode.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/helpers/ZlibHeaderTransformStream.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/helpers/bind.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/helpers/buildURL.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/helpers/callbackify.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/helpers/combineURLs.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/helpers/cookies.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/helpers/formDataToJSON.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/helpers/formDataToStream.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/helpers/fromDataURI.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/helpers/isAbsoluteURL.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/helpers/isAxiosError.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/helpers/isURLSameOrigin.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/helpers/parseHeaders.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/helpers/parseProtocol.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/helpers/readBlob.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/helpers/speedometer.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/helpers/spread.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/helpers/throttle.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/helpers/toFormData.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/helpers/toURLEncodedForm.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/helpers/validator.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/platform/index.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/platform/common/utils.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/platform/node/index.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/platform/node/classes/FormData.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/platform/node/classes/URLSearchParams.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/form-data-encoder/lib/index.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/formdata-node/lib/form-data.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/@isaacs/cliui/node_modules/string-width/index.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/@isaacs/cliui/node_modules/strip-ansi/index.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/@isaacs/cliui/node_modules/wrap-ansi/index.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/@isaacs/cliui/node_modules/ansi-regex/index.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/@isaacs/cliui/node_modules/ansi-styles/index.js

View File

@ -1,382 +0,0 @@
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/app.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/app.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/help.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/utils/common-args.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/utils/common-flags.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/utils/compose_ts.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/utils/docker.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/utils/env-common.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/utils/helpers.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/utils/lazy.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/api-key/generate.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/api-key/list.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/api-key/revoke.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/app/create.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/block/create.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/index.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/config/generate.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/config/inject.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/config/read.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/config/reconfigure.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/config/write.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/deploy/index.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/deactivate.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/detect.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/identify.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/index.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/init.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/list.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/local-mode.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/logs.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/move.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/note.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/os-update.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/pin.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/public-url.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/purge.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/reboot.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/register.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/rename.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/restart.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/rm.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/shutdown.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/ssh.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/start-service.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/stop-service.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/track-fleet.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device/tunnel.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/device-type/list.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/env/list.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/env/rename.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/env/rm.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/env/set.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/fleet/create.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/fleet/index.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/fleet/list.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/fleet/pin.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/fleet/purge.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/fleet/rename.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/fleet/restart.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/fleet/rm.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/fleet/track-latest.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/internal/osinit.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/join/index.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/leave/index.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/local/configure.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/local/flash.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/login/index.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/logout/index.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/organization/list.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/os/build-config.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/os/configure.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/os/download.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/os/initialize.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/os/versions.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/preload/index.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/push/index.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/release/finalize.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/release/index.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/release/invalidate.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/release/list.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/release/validate.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/settings/index.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/ssh-key/add.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/ssh-key/index.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/ssh-key/list.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/ssh-key/rm.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/support/index.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/tag/list.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/tag/rm.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/tag/set.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/util/available-drives.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/version/index.js
> Warning Entry 'main' not found in %1
%1: node_modules/@oclif/core/package.json
%2: build/commands/whoami/index.js
> Warning Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules/open/xdg-open
%2: path-to-executable/xdg-open
> Warning Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules/open/xdg-open
%2: path-to-executable/xdg-open
> Warning Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules/drivelist/build/Release/drivelist.node
%2: path-to-executable/drivelist.node
> Warning Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules/drivelist/scripts/darwin.sh
%2: path-to-executable/drivelist/darwin.sh
> Warning Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules/drivelist/scripts/linux.sh
%2: path-to-executable/drivelist/linux.sh
> Warning Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules/drivelist/scripts/win32.bat
%2: path-to-executable/drivelist/win32.bat
> Warning Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules/drivelist/build/Release/drivelist.node
%2: path-to-executable/drivelist.node
> Warning Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules/drivelist/scripts/darwin.sh
%2: path-to-executable/drivelist/darwin.sh
> Warning Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules/drivelist/scripts/linux.sh
%2: path-to-executable/drivelist/linux.sh
> Warning Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules/drivelist/scripts/win32.bat
%2: path-to-executable/drivelist/win32.bat
> Warning Cannot resolve 'path'
node_modules/@balena/compose/dist/parse/schemas/index.js
Dynamic require may fail at run time, because the requested file
is unknown at compilation time and not included into executable.
Use a string literal as an argument for 'require', or leave it
as is and specify the resolved file name in 'scripts' option.
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/index.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/axios.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/utils.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/adapters/adapters.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/adapters/http.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/adapters/xhr.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/cancel/CancelToken.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/cancel/CanceledError.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/cancel/isCancel.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/core/Axios.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/core/AxiosError.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/core/AxiosHeaders.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/core/InterceptorManager.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/core/buildFullPath.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/core/dispatchRequest.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/core/mergeConfig.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/core/settle.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/core/transformData.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/defaults/index.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/defaults/transitional.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/env/data.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/AxiosTransformStream.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/AxiosURLSearchParams.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/HttpStatusCode.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/ZlibHeaderTransformStream.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/bind.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/buildURL.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/callbackify.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/combineURLs.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/cookies.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/formDataToJSON.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/formDataToStream.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/fromDataURI.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/isAbsoluteURL.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/isAxiosError.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/isURLSameOrigin.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/parseHeaders.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/parseProtocol.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/readBlob.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/speedometer.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/spread.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/throttle.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/toFormData.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/toURLEncodedForm.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/validator.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/platform/index.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/platform/common/utils.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/platform/node/index.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/platform/node/classes/FormData.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/platform/node/classes/URLSearchParams.js
> Warning Failed to make bytecode node20-x64 for file node_modules/form-data-encoder/lib/index.js
> Warning Failed to make bytecode node20-x64 for file node_modules/formdata-node/lib/form-data.js
> Warning Failed to make bytecode node20-x64 for file node_modules/@isaacs/cliui/node_modules/string-width/index.js
> Warning Failed to make bytecode node20-x64 for file node_modules/@isaacs/cliui/node_modules/strip-ansi/index.js
> Warning Failed to make bytecode node20-x64 for file node_modules/@isaacs/cliui/node_modules/wrap-ansi/index.js
> Warning Failed to make bytecode node20-x64 for file node_modules/@isaacs/cliui/node_modules/ansi-regex/index.js
> Warning Failed to make bytecode node20-x64 for file node_modules/@isaacs/cliui/node_modules/ansi-styles/index.js

View File

@ -1,382 +0,0 @@
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\app.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\app.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\help.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\utils\common-args.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\utils\common-flags.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\utils\compose_ts.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\utils\docker.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\utils\env-common.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\utils\helpers.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\utils\lazy.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\commands\api-key\generate.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\commands\api-key\list.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\commands\api-key\revoke.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\commands\app\create.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\commands\block\create.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\index.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\commands\config\generate.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\commands\config\inject.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\commands\config\read.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\commands\config\reconfigure.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\commands\config\write.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\commands\deploy\index.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\commands\device\deactivate.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\commands\device\detect.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\commands\device\identify.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\commands\device\index.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\commands\device\init.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\commands\device\list.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\commands\device\local-mode.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\commands\device\logs.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\commands\device\move.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\commands\device\note.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\commands\device\os-update.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\commands\device\pin.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\commands\device\public-url.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\commands\device\purge.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\commands\device\reboot.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\commands\device\register.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\commands\device\rename.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\commands\device\restart.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\commands\device\rm.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\commands\device\shutdown.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\commands\device\ssh.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\commands\device\start-service.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\commands\device\stop-service.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\commands\device\track-fleet.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\commands\device\tunnel.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\commands\device-type\list.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\commands\env\list.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\commands\env\rename.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\commands\env\rm.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\commands\env\set.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\commands\fleet\create.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\commands\fleet\index.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\commands\fleet\list.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\commands\fleet\pin.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\commands\fleet\purge.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\commands\fleet\rename.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\commands\fleet\restart.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\commands\fleet\rm.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\commands\fleet\track-latest.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\commands\internal\osinit.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\commands\join\index.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\commands\leave\index.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\commands\local\configure.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\commands\local\flash.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\commands\login\index.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\commands\logout\index.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\commands\organization\list.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\commands\os\build-config.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\commands\os\configure.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\commands\os\download.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\commands\os\initialize.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\commands\os\versions.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\commands\preload\index.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\commands\push\index.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\commands\release\finalize.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\commands\release\index.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\commands\release\invalidate.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\commands\release\list.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\commands\release\validate.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\commands\settings\index.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\commands\ssh-key\add.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\commands\ssh-key\index.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\commands\ssh-key\list.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\commands\ssh-key\rm.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\commands\support\index.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\commands\tag\list.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\commands\tag\rm.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\commands\tag\set.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\commands\util\available-drives.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\commands\version\index.js
> Warning Entry 'main' not found in %1
%1: node_modules\@oclif\core\package.json
%2: build\commands\whoami\index.js
> Warning Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules\open\xdg-open
%2: path-to-executable/xdg-open
> Warning Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules\open\xdg-open
%2: path-to-executable/xdg-open
> Warning Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules\drivelist\build\Release\drivelist.node
%2: path-to-executable/drivelist.node
> Warning Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules\drivelist\scripts\darwin.sh
%2: path-to-executable/drivelist/darwin.sh
> Warning Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules\drivelist\scripts\linux.sh
%2: path-to-executable/drivelist/linux.sh
> Warning Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules\drivelist\scripts\win32.bat
%2: path-to-executable/drivelist/win32.bat
> Warning Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules\drivelist\build\Release\drivelist.node
%2: path-to-executable/drivelist.node
> Warning Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules\drivelist\scripts\darwin.sh
%2: path-to-executable/drivelist/darwin.sh
> Warning Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules\drivelist\scripts\linux.sh
%2: path-to-executable/drivelist/linux.sh
> Warning Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules\drivelist\scripts\win32.bat
%2: path-to-executable/drivelist/win32.bat
> Warning Cannot resolve 'path'
node_modules\@balena\compose\dist\parse\schemas\index.js
Dynamic require may fail at run time, because the requested file
is unknown at compilation time and not included into executable.
Use a string literal as an argument for 'require', or leave it
as is and specify the resolved file name in 'scripts' option.
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\index.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\axios.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\utils.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\adapters\adapters.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\adapters\http.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\adapters\xhr.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\cancel\CanceledError.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\cancel\CancelToken.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\cancel\isCancel.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\core\Axios.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\core\AxiosError.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\core\AxiosHeaders.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\core\buildFullPath.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\core\dispatchRequest.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\core\InterceptorManager.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\core\mergeConfig.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\core\settle.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\core\transformData.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\defaults\index.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\defaults\transitional.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\env\data.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\helpers\AxiosTransformStream.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\helpers\AxiosURLSearchParams.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\helpers\bind.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\helpers\buildURL.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\helpers\callbackify.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\helpers\combineURLs.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\helpers\cookies.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\helpers\formDataToJSON.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\helpers\formDataToStream.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\helpers\fromDataURI.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\helpers\HttpStatusCode.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\helpers\isAbsoluteURL.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\helpers\isAxiosError.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\helpers\isURLSameOrigin.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\helpers\parseHeaders.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\helpers\parseProtocol.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\helpers\readBlob.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\helpers\speedometer.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\helpers\spread.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\helpers\throttle.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\helpers\toFormData.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\helpers\toURLEncodedForm.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\helpers\validator.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\helpers\ZlibHeaderTransformStream.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\platform\index.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\platform\common\utils.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\platform\node\index.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\platform\node\classes\FormData.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\platform\node\classes\URLSearchParams.js
> Warning Failed to make bytecode node20-x64 for file node_modules\form-data-encoder\lib\index.js
> Warning Failed to make bytecode node20-x64 for file node_modules\formdata-node\lib\form-data.js
> Warning Failed to make bytecode node20-x64 for file node_modules\@isaacs\cliui\node_modules\string-width\index.js
> Warning Failed to make bytecode node20-x64 for file node_modules\@isaacs\cliui\node_modules\strip-ansi\index.js
> Warning Failed to make bytecode node20-x64 for file node_modules\@isaacs\cliui\node_modules\wrap-ansi\index.js
> Warning Failed to make bytecode node20-x64 for file node_modules\@isaacs\cliui\node_modules\ansi-regex\index.js
> Warning Failed to make bytecode node20-x64 for file node_modules\@isaacs\cliui\node_modules\ansi-styles\index.js

View File

@ -63,7 +63,7 @@ describe('detectEncoding() function', function () {
it('should correctly detect the encoding of a few selected files', async () => {
const sampleBinary = [
'drivelist/build/Release/drivelist.node',
'mountutils/build/Release/MountUtils.node',
'mountutils/prebuilds/linux-x64/mountutils.node',
];
const sampleText = [
'node_modules/.bin/mocha',

View File

@ -42,7 +42,7 @@ describe('image-manager', function () {
describe('given the image is fresh', function () {
beforeEach(function () {
this.cacheIsImageFresh = stub(imageManager, 'isImageFresh');
this.cacheIsImageFresh = stub(imageManager, 'isImageCached');
return this.cacheIsImageFresh.resolves(true);
});
@ -56,7 +56,7 @@ describe('image-manager', function () {
void imageManager.getStream('raspberry-pi').then(function (stream) {
let result = '';
stream.on('data', (chunk) => (result += chunk.toString()));
stream.on('data', (chunk: string) => (result += chunk.toString()));
return stream.on('end', function () {
expect(result).to.equal('Cache image');
@ -68,7 +68,7 @@ describe('image-manager', function () {
describe('given the image is not fresh', function () {
beforeEach(function () {
this.cacheIsImageFresh = stub(imageManager, 'isImageFresh');
this.cacheIsImageFresh = stub(imageManager, 'isImageCached');
return this.cacheIsImageFresh.resolves(false);
});
@ -91,7 +91,7 @@ describe('image-manager', function () {
void imageManager.getStream('raspberry-pi').then((stream) => {
let result = '';
stream.on('data', (chunk) => (result += chunk));
stream.on('data', (chunk: string) => (result += chunk));
stream.on('end', async () => {
expect(result).to.equal('Download image');
@ -280,7 +280,7 @@ describe('image-manager', function () {
});
});
describe('.isImageFresh()', () => {
describe('.isImageCached()', () => {
describe('given the raspberry-pi manifest', function () {
beforeEach(function () {
this.getDeviceTypeManifestBySlugStub = stub(
@ -314,78 +314,8 @@ describe('image-manager', function () {
});
it('should return false', async function () {
expect(await imageManager.isImageFresh('raspberry-pi', '1.2.3')).to.be
.false;
});
});
describe('given a fixed created time', function () {
beforeEach(function () {
this.utilsGetFileCreatedDate = stub(
imageManager,
'getFileCreatedDate',
);
this.utilsGetFileCreatedDate.resolves(
new Date('2014-01-01T00:00:00.000Z'),
);
});
afterEach(function () {
this.utilsGetFileCreatedDate.restore();
});
describe('given the file was created before the os last modified time', function () {
beforeEach(function () {
this.osGetLastModified = stub(balena.models.os, 'getLastModified');
this.osGetLastModified.resolves(
new Date('2014-02-01T00:00:00.000Z'),
);
});
afterEach(function () {
this.osGetLastModified.restore();
});
it('should return false', function () {
const promise = imageManager.isImageFresh('raspberry-pi', '1.2.3');
return expect(promise).to.eventually.be.false;
});
});
describe('given the file was created after the os last modified time', function () {
beforeEach(function () {
this.osGetLastModified = stub(balena.models.os, 'getLastModified');
this.osGetLastModified.resolves(
new Date('2013-01-01T00:00:00.000Z'),
);
});
afterEach(function () {
this.osGetLastModified.restore();
});
it('should return true', function () {
const promise = imageManager.isImageFresh('raspberry-pi', '1.2.3');
return expect(promise).to.eventually.be.true;
});
});
describe('given the file was created just at the os last modified time', function () {
beforeEach(function () {
this.osGetLastModified = stub(balena.models.os, 'getLastModified');
this.osGetLastModified.resolves(
new Date('2014-00-01T00:00:00.000Z'),
);
});
afterEach(function () {
this.osGetLastModified.restore();
});
it('should return false', function () {
const promise = imageManager.isImageFresh('raspberry-pi', '1.2.3');
return expect(promise).to.eventually.be.false;
});
expect(await imageManager.isImageCached('raspberry-pi', '1.2.3')).to
.be.false;
});
});
});
@ -412,7 +342,7 @@ describe('image-manager', function () {
.then(function (stream) {
let result = '';
stream.on('data', (chunk: string) => (result += chunk));
stream.on('data', (chunk) => (result += chunk as string));
stream.on('end', function () {
expect(result).to.equal('Lorem ipsum dolor sit amet');

View File

@ -1,105 +0,0 @@
/**
* @license
* Copyright 2019 Balena Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
declare module 'balena-device-init' {
import type { DeviceTypeJson } from 'balena-sdk';
interface OperationState {
operation:
| CopyOperation
| ReplaceOperation
| RunScriptOperation
| BurnOperation;
percentage: number;
}
interface Operation {
command: string;
}
interface CopyOperation extends Operation {
command: 'copy';
from: { path: string };
to: { path: string };
}
interface ReplaceOperation extends Operation {
command: 'replace';
copy: string;
replace: string;
file: {
path: string;
};
}
interface RunScriptOperation extends Operation {
command: 'run-script';
script: string;
arguments?: string[];
}
interface BurnOperation extends Operation {
command: 'burn';
image?: string;
}
interface BurnProgress {
type: 'write' | 'check';
percentage: number;
transferred: number;
length: number;
remaining: number;
eta: number;
runtime: number;
delta: number;
speed: number;
}
interface InitializeEmitter {
on(event: 'stdout' | 'stderr', callback: (msg: string) => void): void;
on(event: 'state', callback: (state: OperationState) => void): void;
on(event: 'burn', callback: (state: BurnProgress) => void): void;
on(event: 'end', callback: () => void): void;
on(event: 'error', callback: (error: Error) => void): void;
}
// As of writing this, these are Bluebird promises, but we are typing then
// as normal Promises so that we do not rely on Bluebird specific methods,
// so that the CLI will not require any change once the package drops Bluebird.
export function configure(
image: string,
manifest: DeviceTypeJson.DeviceType,
config: object,
options?: object,
): Promise<InitializeEmitter>;
export function initialize(
image: string,
manifest: DeviceTypeJson.DeviceType,
config: object,
): Promise<InitializeEmitter>;
export function getImageOsVersion(
image: string,
manifest: DeviceTypeJson.DeviceType,
): Promise<string | null>;
export function getImageManifest(
image: string,
): Promise<DeviceTypeJson.DeviceType | null>;
}