Compare commits

...

108 Commits

Author SHA1 Message Date
7ad9e685f6 v15.1.3 2023-04-05 08:06:56 +00:00
c778aaffaf Merge pull request #2607 from balena-io/update-balena-sdk-16.28.2
devices supported: Fix showing types without a valid & finalized release
2023-04-05 08:06:05 +00:00
b98047cacf devices supported: Fix showing types without a valid & finalized release
Update balena-sdk from 16.28.0 to 16.28.2

Resolves: #2524
Change-type: patch
2023-04-05 10:19:39 +03:00
03ace6e4b2 v15.1.2 2023-03-27 15:14:47 +00:00
9b4701bcb7 Merge pull request #2601 from balena-io/use-satisfies
Improve type checking by using the satisfies operator
2023-03-27 18:13:56 +03:00
174312977a Improve type checking by using the satisfies operator
Change-type: patch
2023-03-27 16:39:09 +03:00
963d9af817 v15.1.1 2023-03-17 10:20:03 +00:00
af5ec51232 Merge pull request #2600 from balena-io/bump-ts
Update TypeScript to 5.0.2
2023-03-17 12:19:13 +02:00
1cd9fbf6a0 Update TypeScript to 5.0.2
Change-type: patch
2023-03-16 20:53:08 +02:00
72639e9e59 v15.1.0 2023-03-14 20:19:08 +00:00
447dcc1480 Merge pull request #2599 from balena-io/kyle/balena-compose-v2.2.x
Update balena-compose to v2.2.1
2023-03-14 16:18:19 -04:00
564716faa7 Update balena-compose to v2.2.1
Update balena-compose from 2.1.1 to 2.2.1

Change-type: minor
Signed-off-by: Kyle Harding <kyle@balena.io>
2023-03-14 14:59:52 -04:00
3e5b4457c2 v15.0.6 2023-03-13 14:03:48 +00:00
793e70d909 Merge pull request #2597 from balena-io/explicitly-select-devices-fields
Devices: explicitly fetches only used fields
2023-03-13 11:02:51 -03:00
5761a306be Devices: explicitly fetches only used fields
Change-type: patch
2023-03-13 09:35:43 -03:00
adff0f2a0a v15.0.5 2023-03-10 16:25:40 +00:00
4ec45a0c43 Merge pull request #2596 from balena-io/fix-is-legacy-check
Fix isLegacy check which should always relay on the slug
2023-03-10 18:24:48 +02:00
ecf4b046b5 Fix application isLegacy check for rename and deploy
Change-type: patch
2023-03-10 16:33:00 +01:00
b0cae93ac9 v15.0.4 2023-02-21 07:24:19 +00:00
53b66678d4 Merge pull request #2583 from balena-io/hraftery-patch-1-1
Clarify update rate of update-notifier info
2023-02-21 09:23:30 +02:00
0b9b65ef88 patch: Clarify update rate of update notifier info
If the cli has not been run in a while, it will show old update information. It's not obvious why, and this might lead to confusion. So this commit just adds a comment to clarify that out-of-date update notifier info is expected behaviour, and why.
2023-01-26 14:15:43 +11:00
8a84d9d792 v15.0.3 2023-01-18 16:16:39 +00:00
c535b8e1ea Merge pull request #2582 from balena-io/https-npm
Use https for the npm deprecation check, avoiding a redirect
2023-01-18 16:15:01 +00:00
234fb6cd39 Use https for the npm deprecation check, avoiding a redirect
Change-type: patch
2023-01-18 13:11:31 +00:00
8714830b48 v15.0.2 2023-01-14 07:35:13 +00:00
0e07b36691 Merge pull request #2580 from balena-io/joshbwlng/fix-typo
Fix push --nolive doc typo
2023-01-14 09:33:56 +02:00
ba80d3c38c Fix push --nolive doc typo
Change-type: patch
2023-01-13 13:36:44 +09:00
e65dc82cfe v15.0.1 2023-01-10 13:43:24 +00:00
bc727521c6 Merge pull request #2571 from balena-io/nodejs-14
Update to Node 14
2023-01-10 08:41:54 -05:00
a8c0c884d3 Extra linting 2023-01-03 16:08:10 -03:00
b11c7157d3 Update to node 14 2023-01-03 16:04:24 -03:00
578de7bcd4 Process livepush build logs inline
When using livepush, the CLI parses the build logs to obtain the stage
image ids, which are necessary for properly running livepush.

This process used to store the full log output in memory before parsing
the logs for obtaining the stage ids. We have seen this cause issues
before because of the excessive memory usage and it is one the suspects
of #2165, which is blocking the update to Node 14

Change-type: patch
2023-01-03 12:29:54 -03:00
cfc6b3ce9e v15.0.0 2023-01-02 15:21:59 +00:00
1c7a354fe7 Merge pull request #2573 from balena-io/balena-preload-13
Upgrade balena-preload to 13.0.0
2023-01-02 10:20:01 -05:00
40a0941ca3 preload: Drops ability to preload Intel Edison (EOL 2017)
Upgrade balena-preload from 12.2.0 to 13.0.0

Change-type: major
Signed-off-by: Edwin Joassart <edwin.joassart@balena.io>
2023-01-02 15:34:32 +01:00
0ab4760272 v14.5.18 2022-12-29 07:20:50 +00:00
42b2269e81 Merge pull request #2576 from balena-io/flowzone-npm-ci
Update flowzone tests to use npm ci
2022-12-29 02:19:24 -05:00
c818d846b3 Update flowzone tests to use npm ci
Will also make sure that the shrinkwrap is
matching the committed package.json.

Change-type: patch
2022-12-29 08:24:24 +02:00
3328f40416 v14.5.17 2022-12-28 23:56:12 +00:00
58d10c1908 Merge pull request #2575 from balena-io/drop-balena-sync
Stop using the deprecated balena-sync module
2022-12-29 01:54:48 +02:00
2fd0ca6a02 Stop using the deprecated balena-sync module
Change-type: patch
2022-12-29 01:05:51 +02:00
173028fd0d v14.5.16 2022-12-28 23:01:25 +00:00
62d5bf4436 Merge pull request #2574 from balena-io/align-package-json-shrinkwrap
Update the npm-shrinkwrap.json dependencies to match the package.json
2022-12-29 01:00:11 +02:00
63a0d19770 Update the npm-shrinkwrap.json dependencies to match the package.json
Change-type: patch
2022-12-28 21:22:48 +02:00
8244636bf2 v14.5.15 2022-12-12 13:41:15 +00:00
6a01fb361c Merge pull request #2570 from balena-io/aethernet-preload-12.2.0
patch: update balena-preload to 12.2.0
2022-12-12 08:39:46 -05:00
ca637b3fb6 patch: update balena-preload to 12.2.0 2022-12-12 13:16:22 +01:00
006293bd01 v14.5.14 2022-12-11 21:46:38 +00:00
338b5d79d3 Merge pull request #2535 from balena-io/multicast-dns-bump
Bump multicast-dns to rebased commit (again)
2022-12-11 16:45:14 -05:00
60dd0daae5 Bump multicast-dns to rebased commit (again)
A recent PR reverted the multicast-dns commit bump from PR #2401. This means that
under some conditions, `npm install` will fail.

See: https://github.com/balena-io-modules/multicast-dns/pull/1
See: https://github.com/balena-io/balena-cli/pull/2401

Change-type: patch
2022-12-11 12:45:49 -08:00
662b8283a6 v14.5.13 2022-12-08 14:00:28 +00:00
cfc866cf41 Merge pull request #2569 from balena-io/gh-runners
Specify gh runner versions for compatibility reasons
2022-12-08 13:58:56 +00:00
e566badfff Build on macos-11 for library compatibility reasons
Change-type: patch
2022-12-08 10:58:40 +00:00
69834c417e Build on ubuntu-20.04 for library compatibility reasons
Change-type: patch
2022-12-08 10:58:25 +00:00
8aa9c62afd v14.5.12 2022-11-21 18:46:49 +00:00
4f29e37fe7 Merge pull request #2565 from balena-io/ab77/operational
Move GH publishing to FZ core
2022-11-21 18:45:25 +00:00
99e8a36bb5 Move GH publishing to FZ core
Change-type: patch
2022-11-21 09:48:09 -08:00
669cbe227f v14.5.11 2022-11-17 18:32:48 +00:00
e9156d77f1 Merge pull request #2532 from balena-io/nvmrc
Adding .nvmrc so we can use nvm use instead of hunting for version
2022-11-17 18:31:28 +00:00
767216c842 Adding .nvmrc so we can use nvm use instead of hunting for version
Change-type: patch
2022-11-16 17:54:42 -08:00
d3018f9061 v14.5.10 2022-11-11 11:24:21 +00:00
37c6ad855b Merge pull request #2557 from balena-io/surface-sdk-incompatible-dt-errors
Surface sdk incompatible dt errors
2022-11-11 11:23:05 +00:00
ca97678358 Fix surfacing incompatible device type errors as not recognized
Change-type: patch
Signed-off-by: Thodoris Greasidis <thodoris@balena.io>
2022-11-10 16:52:14 -08:00
3bb0036ba8 v14.5.9 2022-11-11 00:49:26 +00:00
ac9e2a9e7e Merge pull request #2562 from balena-io/ab77/operational
Prevent git from existing with 141
2022-11-11 00:47:34 +00:00
52e95e6d0a Prevent git from existing with 141
Change-type: patch
2022-11-10 15:52:13 -08:00
c5d2aa7eec v14.5.8 2022-11-10 23:32:21 +00:00
683220e303 Merge pull request #2561 from balena-io/ab77/operational
Replace missing input
2022-11-10 23:30:51 +00:00
44f09b32fa Replace missing input
Change-type: patch
2022-11-10 14:33:13 -08:00
d1a0660a3d v14.5.7 2022-11-10 22:19:22 +00:00
ee1987f188 Merge pull request #2560 from balena-io/ab77/operational
Just ignore errors during publish
2022-11-10 22:17:59 +00:00
39e9997d9e Just ignore errors during publish
Change-type: patch
2022-11-10 13:22:29 -08:00
97b8c75043 v14.5.6 2022-11-10 21:07:35 +00:00
7cb8349f29 Merge pull request #2559 from balena-io/ab77/operational
Ignore PIPE signal
2022-11-10 21:06:18 +00:00
6063f4c776 Ignore PIPE signal
Change-type: patch
2022-11-10 12:13:03 -08:00
4899d545f1 v14.5.5 2022-11-10 20:07:12 +00:00
115bf6433d Merge pull request #2558 from balena-io/ab77/operational
Don't pipefail
2022-11-10 20:05:33 +00:00
e5ce1ade89 Don't pipefail
Change-type: patch
2022-11-10 11:13:37 -08:00
9c4174ea8a v14.5.4 2022-11-10 18:31:21 +00:00
cf16957195 Merge pull request #2556 from balena-io/2537-error-on-incompatible-resolved-device-types
Error when the device type and image parameters do not match
2022-11-10 18:30:05 +00:00
4de369ff95 Error when the device type and image parameters do not match
Resolves: #2537
Change-type: patch
Signed-off-by: Thodoris Greasidis <thodoris@balena.io>
2022-11-10 09:37:22 -08:00
ac3ebff8ee v14.5.3 2022-11-10 17:20:19 +00:00
76b01d92d3 Merge pull request #2555 from balena-io/ab77/operational
Switch to Flowzone
2022-11-10 17:18:49 +00:00
19144163ee Switch to Flowzone
Change-type: patch
2022-11-08 20:56:47 -08:00
535ffccbad v14.5.2 2022-10-21 20:15:35 +03:00
6f5ada9692 Merge pull request #2553 from balena-io/stop-waiting-for-the-analytics-response
Stop waiting for the analytics response
2022-10-21 17:09:08 +00:00
1c7d9255ae Stop waiting for the analytics response
Change-type: patch
See: https://balena.zulipchat.com/#narrow/stream/345884-aspect.2Fanalytics/topic/Balena.20CLI.20analytics-performance
Signed-off-by: Thodoris Greasidis <thodoris@balena.io>
2022-10-21 19:07:39 +03:00
807e6ea2ad v14.5.1 2022-10-21 15:48:13 +03:00
c76f019fd0 Merge pull request #2552 from balena-io/bump-parse-link-header-2.0.0
Bump parse-link-header from 1.0.1 to 2.0.0
2022-10-21 12:45:48 +00:00
3c2c925eed Bump parse-link-header from 1.0.1 to 2.0.0
Bumps [parse-link-header](https://github.com/thlorenz/parse-link-header) from 1.0.1 to 2.0.0.
- [Release notes](https://github.com/thlorenz/parse-link-header/releases)
- [Commits](https://github.com/thlorenz/parse-link-header/compare/v1.0.1...v2.0.0)

---
updated-dependencies:
- dependency-name: parse-link-header
  dependency-type: direct:development
...

Change-type: patch
Signed-off-by: dependabot[bot] <support@github.com>
2022-10-20 20:10:53 +03:00
14b54be15e v14.5.0 2022-10-18 15:17:13 +03:00
7fb82f7447 Merge pull request #2539 from balena-io/send-tracking-to-analytics-backend
changes analytics endpoint to analytics-backend
2022-10-18 12:14:05 +00:00
4a5d44a0f1 Merge branch 'master' into send-tracking-to-analytics-backend 2022-10-18 08:15:33 -03:00
1cba0284df v14.4.4 2022-10-18 13:36:52 +03:00
6e4fe229bf Merge pull request #2546 from balena-io/update-simple-git
Update simple git
2022-10-18 10:33:17 +00:00
7033075900 Update simple-git to 3.14.1
Change-type: patch
Signed-off-by: Thodoris Greasidis <thodoris@balena.io>
2022-10-18 09:45:24 +03:00
ded268ff3c automation/check-doc: Convert to typescript 2022-10-18 09:45:24 +03:00
a366f0b7eb automation/check-doc: Rename to .ts 2022-10-18 09:45:24 +03:00
507c8a1bfd v14.4.3 2022-10-18 00:24:29 +03:00
1fb46bfa5d Merge pull request #2545 from balena-io/config-generate-incompatible-dt-error
config generate: Fix the incompatible arch errors showing as not found
2022-10-17 21:20:21 +00:00
2e115968d5 config generate: Fix the incompatible arch errors showing as not found
Change-type: patch
Signed-off-by: Thodoris Greasidis <thodoris@balena.io>
2022-10-17 23:44:08 +03:00
83020797b0 v14.4.2 2022-10-17 21:15:25 +03:00
0c4647e980 Merge pull request #2544 from balena-io/no-device-type-json-arch-aliases
Stop relying on device-type.json for resolving the cpu architecture
2022-10-17 18:06:05 +00:00
a20d2a04a8 Stop relying on device-type.json for resolving the device type aliases
Resolves: #2541
Change-type: patch
Signed-off-by: Thodoris Greasidis <thodoris@balena.io>
2022-10-17 19:09:09 +03:00
57b0dccc7d Stop relying on device-type.json for resolving the cpu architecture
Resolves: #2542
Change-type: patch
Signed-off-by: Thodoris Greasidis <thodoris@balena.io>
2022-10-17 19:09:09 +03:00
d1e3bdf29a keeps events loggiging with default message
change-type: minor
2022-10-17 10:07:51 -03:00
bdf7fedd7a uses amplitude data events format
Change-type: minor
2022-10-14 10:50:12 -03:00
c163662f4a changes analytics endpoint to analytics-backend
change-type: minor
2022-10-13 19:32:55 -03:00
52 changed files with 2845 additions and 1130 deletions

130
.github/actions/publish/action.yml vendored Normal file
View File

@ -0,0 +1,130 @@
---
name: package and draft GitHub release
# https://github.com/product-os/flowzone/tree/master/.github/actions
inputs:
json:
description: "JSON stringified object containing all the inputs from the calling workflow"
required: true
secrets:
description: "JSON stringified object containing all the secrets from the calling workflow"
required: true
# --- custom environment
XCODE_APP_LOADER_EMAIL:
type: string
default: "accounts+apple@balena.io"
NODE_VERSION:
type: string
default: "14.x"
VERBOSE:
type: string
default: "true"
runs:
# https://docs.github.com/en/actions/creating-actions/creating-a-composite-action
using: "composite"
steps:
- name: Download custom source artifact
uses: actions/download-artifact@v3
with:
name: custom-${{ github.event.pull_request.head.sha || github.event.head_commit.id }}-${{ runner.os }}
path: ${{ runner.temp }}
- name: Extract custom source artifact
shell: pwsh
working-directory: .
run: tar -xf ${{ runner.temp }}/custom.tgz
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: ${{ inputs.NODE_VERSION }}
cache: npm
- name: Install additional tools
if: runner.os == 'Windows'
shell: bash
run: |
choco install yq
- name: Install additional tools
if: runner.os == 'macOS'
shell: bash
run: |
brew install coreutils
# https://www.electron.build/code-signing.html
# https://github.com/Apple-Actions/import-codesign-certs
- name: Import Apple code signing certificate
if: runner.os == 'macOS'
uses: apple-actions/import-codesign-certs@v1
with:
p12-file-base64: ${{ fromJSON(inputs.secrets).APPLE_SIGNING }}
p12-password: ${{ fromJSON(inputs.secrets).APPLE_SIGNING_PASSWORD }}
- name: Import Windows code signing certificate
if: runner.os == 'Windows'
shell: powershell
run: |
Set-Content -Path ${{ runner.temp }}/certificate.base64 -Value $env:WINDOWS_CERTIFICATE
certutil -decode ${{ runner.temp }}/certificate.base64 ${{ runner.temp }}/certificate.pfx
Remove-Item -path ${{ runner.temp }} -include certificate.base64
Import-PfxCertificate `
-FilePath ${{ runner.temp }}/certificate.pfx `
-CertStoreLocation Cert:\CurrentUser\My `
-Password (ConvertTo-SecureString -String $env:WINDOWS_CERTIFICATE_PASSWORD -Force -AsPlainText)
env:
WINDOWS_CERTIFICATE: ${{ fromJSON(inputs.secrets).WINDOWS_SIGNING }}
WINDOWS_CERTIFICATE_PASSWORD: ${{ fromJSON(inputs.secrets).WINDOWS_SIGNING_PASSWORD }}
# https://github.com/product-os/scripts/tree/master/shared
# https://github.com/product-os/balena-concourse/blob/master/pipelines/github-events/template.yml
- name: Package release
shell: bash
run: |
set -ea
[[ '${{ inputs.VERBOSE }}' =~ on|On|Yes|yes|true|True ]] && set -x
runner_os="$(echo "${RUNNER_OS}" | tr '[:upper:]' '[:lower:]')"
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_KEYCHAIN=signing_temp
CSC_LINK=${{ fromJSON(inputs.secrets).APPLE_SIGNING }}
elif [[ $runner_os =~ windows|win ]]; then
CSC_KEY_PASSWORD=${{ fromJSON(inputs.secrets).WINDOWS_SIGNING_PASSWORD }}
CSC_LINK='${{ runner.temp }}\certificate.pfx'
# patches/all/oclif.patch
MSYSSHELLPATH="$(which bash)"
MSYSTEM=MSYS
# (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}"
fi
npm run package
find dist -type f -maxdepth 1
env:
# https://github.blog/2020-08-03-github-actions-improvements-for-fork-and-pull-request-workflows/#improvements-for-public-repository-forks
# https://docs.github.com/en/actions/managing-workflow-runs/approving-workflow-runs-from-public-forks#about-workflow-runs-from-public-forks
CSC_FOR_PULL_REQUEST: true
# https://sectigo.com/resource-library/time-stamping-server
TIMESTAMP_SERVER: http://timestamp.sectigo.com
# Apple notarization (automation/build-bin.ts)
XCODE_APP_LOADER_EMAIL: ${{ inputs.XCODE_APP_LOADER_EMAIL }}
XCODE_APP_LOADER_PASSWORD: ${{ fromJSON(inputs.secrets).XCODE_APP_LOADER_PASSWORD }}
- name: Upload artifacts
uses: actions/upload-artifact@v3
with:
name: gh-release-${{ github.event.pull_request.head.sha || github.event.head_commit.id }}
path: dist
retention-days: 1

56
.github/actions/test/action.yml vendored Normal file
View File

@ -0,0 +1,56 @@
---
name: test release
# https://github.com/product-os/flowzone/tree/master/.github/actions
inputs:
json:
description: "JSON stringified object containing all the inputs from the calling workflow"
required: true
secrets:
description: "JSON stringified object containing all the secrets from the calling workflow"
required: true
# --- custom environment
NODE_VERSION:
type: string
default: "14.x"
VERBOSE:
type: string
default: "true"
runs:
# https://docs.github.com/en/actions/creating-actions/creating-a-composite-action
using: "composite"
steps:
# https://github.com/actions/setup-node#caching-global-packages-data
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: ${{ inputs.NODE_VERSION }}
cache: npm
- name: Test release
shell: bash
run: |
set -ea
[[ '${{ inputs.VERBOSE }}' =~ on|On|Yes|yes|true|True ]] && set -x
if [[ -e package-lock.json ]] || [[ -e npm-shrinkwrap.json ]]; then
npm ci
else
npm i
fi
npm run build
npm run test
- name: Compress custom source
shell: pwsh
run: tar -acf ${{ runner.temp }}/custom.tgz .
- name: Upload custom artifact
uses: actions/upload-artifact@v3
with:
name: custom-${{ github.event.pull_request.head.sha || github.event.head_commit.id }}-${{ runner.os }}
path: ${{ runner.temp }}/custom.tgz
retention-days: 1

16
.github/workflows/flowzone.yml vendored Normal file
View File

@ -0,0 +1,16 @@
name: Flowzone
on:
pull_request:
types: [opened, synchronize, closed]
branches:
- "main"
- "master"
jobs:
flowzone:
name: Flowzone
uses: product-os/flowzone/.github/workflows/flowzone.yml@master
secrets: inherit
with:
tests_run_on: '["ubuntu-20.04","macos-11","windows-2019"]'

1
.gitignore vendored
View File

@ -10,7 +10,6 @@
*.seed
/.idea/
/.lock-wscript
/.nvmrc
/.nyc_output/
/.vscode/
/coverage/

1
.nvmrc Normal file
View File

@ -0,0 +1 @@
12

View File

@ -1,20 +0,0 @@
---
npm:
platforms:
- name: linux
os: ubuntu
architecture: x86_64
node_versions:
- "12"
- "14"
##
## Temporarily skip Alpine tests until the following issues are resolved:
## * https://github.com/concourse/concourse/issues/7905
## * https://github.com/product-os/balena-concourse/issues/631
##
# - name: linux
# os: alpine
# architecture: x86_64
# node_versions:
# - "12"
# - "14"

View File

@ -1,3 +1,663 @@
- commits:
- subject: "devices supported: Fix showing types without a valid & finalized
release"
hash: b98047cacf12929a64bcda7bf253da6102179b63
body: |
Update balena-sdk from 16.28.0 to 16.28.2
footer:
Resolves: "#2524"
resolves: "#2524"
Change-type: patch
change-type: patch
author: Thodoris Greasidis
nested:
- commits:
- subject: Update tests to run on node 18
hash: 1838f590aaf27da8cc84952ffb9ea96b48e0f5b3
body: ""
footer:
Change-type: patch
change-type: patch
Signed-off-by: Thodoris Greasidis <thodoris@balena.io>
signed-off-by: Thodoris Greasidis <thodoris@balena.io>
author: Thodoris Greasidis
nested: []
- subject: "deviceType.getAllSupported: Require a valid & final release to exist"
hash: a32e4666ba7e4ea273606854f1c16c99df6a97d6
body: ""
footer:
Change-type: patch
change-type: patch
See: https://balena.zulipchat.com/#narrow/stream/350505-aspect.2Fcommunication/topic/Device-type.20listings.20on.20Docs.20.26.20Hub.20Conflicts
see: https://balena.zulipchat.com/#narrow/stream/350505-aspect.2Fcommunication/topic/Device-type.20listings.20on.20Docs.20.26.20Hub.20Conflicts
Signed-off-by: Thodoris Greasidis <thodoris@balena.io>
signed-off-by: Thodoris Greasidis <thodoris@balena.io>
author: Thodoris Greasidis
nested: []
version: balena-sdk-16.28.2
title: ""
date: 2022-10-27T15:33:07.297Z
- commits:
- subject: "flowzone: Run the node tests using the latest LTS version"
hash: d6e497829f5b687ab45d2e473d888a76b9996064
body: ""
footer:
Change-type: patch
change-type: patch
Signed-off-by: Thodoris Greasidis <thodoris@balena.io>
signed-off-by: Thodoris Greasidis <thodoris@balena.io>
author: Thodoris Greasidis
nested: []
version: balena-sdk-16.28.1
title: ""
date: 2022-10-14T18:17:33.333Z
version: 15.1.3
title: ""
date: 2023-04-05T08:06:53.629Z
- commits:
- subject: Improve type checking by using the satisfies operator
hash: 174312977a52836b12a799d0e2b8ea39c942883a
body: ""
footer:
Change-type: patch
change-type: patch
author: Thodoris Greasidis
nested: []
version: 15.1.2
title: ""
date: 2023-03-27T15:14:45.270Z
- commits:
- subject: Update TypeScript to 5.0.2
hash: 1cd9fbf6a0db345b90ca8341f956f65688b9f30e
body: ""
footer:
Change-type: patch
change-type: patch
author: Thodoris Greasidis
nested: []
version: 15.1.1
title: ""
date: 2023-03-17T10:20:00.978Z
- commits:
- subject: Update balena-compose to v2.2.1
hash: 564716faa7fcff91f83b2e43de770a7e72b6e5d5
body: |
Update balena-compose from 2.1.1 to 2.2.1
footer:
Change-type: minor
change-type: minor
Signed-off-by: Kyle Harding <kyle@balena.io>
signed-off-by: Kyle Harding <kyle@balena.io>
author: Kyle Harding
nested:
- commits:
- subject: Ignore references to build stages when evaluating manifests
hash: 367081fb0c3d7d029b55cd887b60385868248815
body: ""
footer:
Change-type: patch
change-type: patch
Signed-off-by: Kyle Harding <kyle@balena.io>
signed-off-by: Kyle Harding <kyle@balena.io>
author: Kyle Harding
nested: []
version: balena-compose-2.2.1
title: ""
date: 2023-03-14T17:07:03.458Z
- commits:
- subject: OCI Image Index should allow platform opts
hash: 4178f93696438bc89415bbc260d3caf90a0b82bc
body: |
Similar to Manifest v2, OCI Image Index manifest types
support the platform arg, and if the default host
platform is not avilable in the manfiest they will
actually fail to pull.
footer:
Change-type: minor
change-type: minor
Signed-off-by: Kyle Harding <kyle@balena.io>
signed-off-by: Kyle Harding <kyle@balena.io>
author: Kyle Harding
nested: []
version: balena-compose-2.2.0
title: ""
date: 2023-03-13T19:00:05.420Z
- commits:
- subject: Write to debug log when using platform option
hash: 1db846fa5026105c9e78fdfbae23047e14764eb2
body: ""
footer:
Change-type: patch
change-type: patch
Signed-off-by: Kyle Harding <kyle@balena.io>
signed-off-by: Kyle Harding <kyle@balena.io>
author: Kyle Harding
nested: []
version: balena-compose-2.1.4
title: ""
date: 2023-03-13T14:58:49.392Z
- commits:
- subject: Fixup tests to use recent debian:bullseye-slim images
hash: 3ed4ae940fc207866ca4b532cf7539b8e177ef1f
body: ""
footer:
Change-type: patch
change-type: patch
Signed-off-by: Kyle Harding <kyle@balena.io>
signed-off-by: Kyle Harding <kyle@balena.io>
author: Kyle Harding
nested: []
version: balena-compose-2.1.3
title: ""
date: 2023-03-01T18:00:46.411Z
- commits:
- subject: "test/multibuild: Use 127.0.0.1 for the extra_hosts test"
hash: a91d59ff1dbfebf2a0c543523e94107f881ca5db
body: |
That's b/c flowzone limit network access to
just internal networks.
footer:
Change-type: patch
change-type: patch
Signed-off-by: Ken Bannister <kb2ma@runbox.com>
signed-off-by: Ken Bannister <kb2ma@runbox.com>
author: Ken Bannister
nested: []
- subject: Output error text to aid test debugging
hash: 2094b3e75e13422614bbc31d34719b66dce6fa14
body: ""
footer:
Change-type: patch
change-type: patch
Signed-off-by: Ken Bannister <kb2ma@runbox.com>
signed-off-by: Ken Bannister <kb2ma@runbox.com>
author: Ken Bannister
nested: []
- subject: Replace balenaCI & circleCI with flowzone
hash: 663683427156f8413c6ffc2679e0befd93c914fc
body: ""
footer:
Change-type: patch
change-type: patch
author: Thodoris Greasidis
nested: []
- subject: Pin dockerode to v3.3.3 to avoid regression
hash: 2883800a018d89ca748194370c9c795c8e48cd33
body: >
The problem is rework to buildImage() in v3.3.4 that hangs balena-compose
use of it.
See Issue: https://github.com/apocas/dockerode/issues/696
footer:
Change-type: patch
change-type: patch
Signed-off-by: Ken Bannister <kb2ma@runbox.com>
signed-off-by: Ken Bannister <kb2ma@runbox.com>
author: Ken Bannister
nested: []
- subject: Prettify fixup
hash: 9606f358e16e60774df6656d87612cd17e8b4b87
body: ""
footer:
Change-type: patch
change-type: patch
Signed-off-by: Ken Bannister <kb2ma@runbox.com>
signed-off-by: Ken Bannister <kb2ma@runbox.com>
author: Ken Bannister
nested: []
- subject: Fix underspecified generics in release/models
hash: 57107eb5c89f51bd36e10cb8f9340bab63723348
body: ""
footer:
Change-type: patch
change-type: patch
Signed-off-by: Ken Bannister <kb2ma@runbox.com>
signed-off-by: Ken Bannister <kb2ma@runbox.com>
author: Ken Bannister
nested: []
version: balena-compose-2.1.2
title: ""
date: 2022-10-17T08:10:36.440Z
version: 15.1.0
title: ""
date: 2023-03-14T20:19:05.334Z
- commits:
- subject: "Devices: explicitly fetches only used fields"
hash: 5761a306be9b135886a6d9c0f3515d1ef4550468
body: ""
footer:
Change-type: patch
change-type: patch
author: Otávio Jacobi
nested: []
version: 15.0.6
title: ""
date: 2023-03-13T14:03:45.516Z
- commits:
- subject: Fix application isLegacy check for rename and deploy
hash: ecf4b046b5d30c6e726b61f1e2b1a39cc91b8e53
body: ""
footer:
Change-type: patch
change-type: patch
author: JSReds
nested: []
version: 15.0.5
title: ""
date: 2023-03-10T16:25:37.691Z
- commits:
- subject: "patch: Clarify update rate of update notifier info"
hash: 0b9b65ef886b1ea0bd285a6a1900aae0c7fac281
body: If the cli has not been run in a while, it will show old update
information. It's not obvious why, and this might lead to confusion. So
this commit just adds a comment to clarify that out-of-date update
notifier info is expected behaviour, and why.
footer: {}
author: Heath Raftery
nested: []
version: 15.0.4
title: ""
date: 2023-02-21T07:24:18.046Z
- commits:
- subject: Use https for the npm deprecation check, avoiding a redirect
hash: 234fb6cd39fe0a935f73e84a2ddecf2d77e257aa
body: ""
footer:
Change-type: patch
change-type: patch
author: Pagan Gazzard
nested: []
version: 15.0.3
title: ""
date: 2023-01-18T16:16:37.596Z
- commits:
- subject: Fix push --nolive doc typo
hash: ba80d3c38c89b86abfcf6ee7ef4c4113a2049bb1
body: ""
footer:
Change-type: patch
change-type: patch
author: Josh Bowling
nested: []
version: 15.0.2
title: ""
date: 2023-01-14T07:35:11.117Z
- commits:
- subject: Process livepush build logs inline
hash: 578de7bcd4d1ec6a106251d19305c99c250458c1
body: |
When using livepush, the CLI parses the build logs to obtain the stage
image ids, which are necessary for properly running livepush.
This process used to store the full log output in memory before parsing
the logs for obtaining the stage ids. We have seen this cause issues
before because of the excessive memory usage and it is one the suspects
of #2165, which is blocking the update to Node 14
footer:
Change-type: patch
change-type: patch
author: Felipe Lalanne
nested: []
version: 15.0.1
title: ""
date: 2023-01-10T13:43:22.577Z
- commits:
- subject: "preload: Drops ability to preload Intel Edison (EOL 2017) Upgrade
balena-preload from 12.2.0 to 13.0.0"
hash: 40a0941ca30d7a997300231fc43385ce7bdb5e68
body: ""
footer:
Change-type: major
change-type: major
Signed-off-by: Edwin Joassart <edwin.joassart@balena.io>
signed-off-by: Edwin Joassart <edwin.joassart@balena.io>
author: JOASSART Edwin
nested: []
version: 15.0.0
title: ""
date: 2023-01-02T15:21:57.099Z
- commits:
- subject: Update flowzone tests to use npm ci
hash: c818d846b368cf9c634757581faca15074100e8a
body: |
Will also make sure that the shrinkwrap is
matching the committed package.json.
footer:
Change-type: patch
change-type: patch
author: Thodoris Greasidis
nested: []
version: 14.5.18
title: ""
date: 2022-12-29T07:20:47.915Z
- commits:
- subject: Stop using the deprecated balena-sync module
hash: 2fd0ca6a0203c30639cc981cf572bf2aa375b881
body: ""
footer:
Change-type: patch
change-type: patch
author: Thodoris Greasidis
nested: []
version: 14.5.17
title: ""
date: 2022-12-28T23:56:10.845Z
- commits:
- subject: Update the npm-shrinkwrap.json dependencies to match the package.json
hash: 63a0d1977031ba633d3be7d108320c111c6bdf49
body: ""
footer:
Change-type: patch
change-type: patch
author: Thodoris Greasidis
nested: []
version: 14.5.16
title: ""
date: 2022-12-28T23:01:23.125Z
- commits:
- subject: "patch: update balena-preload to 12.2.0"
hash: ca637b3fb669cd8997ceb70201d4cabe0c621ecf
body: ""
footer: {}
author: Edwin Joassart
nested: []
version: 14.5.15
title: ""
date: 2022-12-12T13:41:11.847Z
- commits:
- subject: Bump multicast-dns to rebased commit (again)
hash: 60dd0daae5682c797ad5ac6fec94ccb7b91c5264
body: >
A recent PR reverted the multicast-dns commit bump from PR #2401. This
means that
under some conditions, `npm install` will fail.
See: https://github.com/balena-io-modules/multicast-dns/pull/1
See: https://github.com/balena-io/balena-cli/pull/2401
footer:
Change-type: patch
change-type: patch
author: pipex
nested: []
version: 14.5.14
title: ""
date: 2022-12-11T21:46:37.025Z
- commits:
- subject: Build on macos-11 for library compatibility reasons
hash: e566badfffbe54a44f8fdd627fc8a78a5ecc204f
body: ""
footer:
Change-type: patch
change-type: patch
author: Page-
nested: []
- subject: Build on ubuntu-20.04 for library compatibility reasons
hash: 69834c417e2aa2d2c20a9749319fc72bb6e563fa
body: ""
footer:
Change-type: patch
change-type: patch
author: Page-
nested: []
version: 14.5.13
title: ""
date: 2022-12-08T14:00:25.894Z
- commits:
- subject: Move GH publishing to FZ core
hash: 99e8a36bb581ac84619ecba452c5afa3d56dae94
body: ""
footer:
Change-type: patch
change-type: patch
author: ab77
nested: []
version: 14.5.12
title: ""
date: 2022-11-21T18:46:45.663Z
- commits:
- subject: Adding .nvmrc so we can use nvm use instead of hunting for version
hash: 767216c842569a523540b7d4d32133c4e53c7596
body: ""
footer:
Change-type: patch
change-type: patch
author: zoobot
nested: []
version: 14.5.11
title: ""
date: 2022-11-17T18:32:46.270Z
- commits:
- subject: Fix surfacing incompatible device type errors as not recognized
hash: ca9767835852da53758f8e9713db85357f22ba8b
body: ""
footer:
Change-type: patch
change-type: patch
Signed-off-by: Thodoris Greasidis <thodoris@balena.io>
signed-off-by: Thodoris Greasidis <thodoris@balena.io>
author: Thodoris Greasidis
nested: []
version: 14.5.10
title: ""
date: 2022-11-11T11:24:19.344Z
- commits:
- subject: Prevent git from existing with 141
hash: 52e95e6d0a96cfb07c111b927f3f8b0607063b99
body: ""
footer:
Change-type: patch
change-type: patch
author: ab77
nested: []
version: 14.5.9
title: ""
date: 2022-11-11T00:49:23.691Z
- commits:
- subject: Replace missing input
hash: 44f09b32fac79c387681f6988e6c621fb0e1ad15
body: ""
footer:
Change-type: patch
change-type: patch
author: ab77
nested: []
version: 14.5.8
title: ""
date: 2022-11-10T23:32:18.629Z
- commits:
- subject: Just ignore errors during publish
hash: 39e9997d9e0a8622d0fc255afe508131a33a9123
body: ""
footer:
Change-type: patch
change-type: patch
author: ab77
nested: []
version: 14.5.7
title: ""
date: 2022-11-10T22:19:20.861Z
- commits:
- subject: Ignore PIPE signal
hash: 6063f4c7762140731a42dd1e5515ce3326b4cb91
body: ""
footer:
Change-type: patch
change-type: patch
author: ab77
nested: []
version: 14.5.6
title: ""
date: 2022-11-10T21:07:32.419Z
- commits:
- subject: Don't pipefail
hash: e5ce1ade892ddddd8a34209b83dcafaeb53a0051
body: ""
footer:
Change-type: patch
change-type: patch
author: ab77
nested: []
version: 14.5.5
title: ""
date: 2022-11-10T20:07:10.573Z
- commits:
- subject: Error when the device type and image parameters do not match
hash: 4de369ff956a4da2a34ddb8f54cf3fcef10a9ec2
body: ""
footer:
Resolves: "#2537"
resolves: "#2537"
Change-type: patch
change-type: patch
Signed-off-by: Thodoris Greasidis <thodoris@balena.io>
signed-off-by: Thodoris Greasidis <thodoris@balena.io>
author: Thodoris Greasidis
nested: []
version: 14.5.4
title: ""
date: 2022-11-10T18:31:18.648Z
- commits:
- subject: Switch to Flowzone
hash: 19144163eeed93a6b68b91715d87e043879a8d51
body: ""
footer:
Change-type: patch
change-type: patch
author: ab77
nested: []
version: 14.5.3
title: ""
date: 2022-11-10T17:20:17.608Z
- commits:
- subject: Stop waiting for the analytics response
hash: 1c7d9255ae5333ff717b9f32ef7adf1690cbb163
body: ""
footer:
Change-type: patch
change-type: patch
See: https://balena.zulipchat.com/#narrow/stream/345884-aspect.2Fanalytics/topic/Balena.20CLI.20analytics-performance
see: https://balena.zulipchat.com/#narrow/stream/345884-aspect.2Fanalytics/topic/Balena.20CLI.20analytics-performance
Signed-off-by: Thodoris Greasidis <thodoris@balena.io>
signed-off-by: Thodoris Greasidis <thodoris@balena.io>
author: Thodoris Greasidis
nested: []
version: 14.5.2
title: "'Stop waiting for the analytics response'"
date: 2022-10-21T16:18:42.222Z
- commits:
- subject: Bump parse-link-header from 1.0.1 to 2.0.0
hash: 3c2c925eed81ed61e1326437038cda1059b1a0ba
body: >
Bumps [parse-link-header](https://github.com/thlorenz/parse-link-header)
from 1.0.1 to 2.0.0.
- [Release notes](https://github.com/thlorenz/parse-link-header/releases)
- [Commits](https://github.com/thlorenz/parse-link-header/compare/v1.0.1...v2.0.0)
---
updated-dependencies:
- dependency-name: parse-link-header
dependency-type: direct:development
...
footer:
Change-type: patch
change-type: patch
Signed-off-by: dependabot[bot] <support@github.com>
signed-off-by: dependabot[bot] <support@github.com>
author: dependabot[bot]
nested: []
version: 14.5.1
title: "'Bump parse-link-header from 1.0.1 to 2.0.0'"
date: 2022-10-20T17:14:00.057Z
- commits:
- subject: keeps events loggiging with default message
hash: d1e3bdf29a4cbe976f6d2feff0eb0f8553b3865a
body: ""
footer:
change-type: minor
author: Otávio Jacobi
nested: []
- subject: uses amplitude data events format
hash: bdf7fedd7aa596834243590cf914f8f366088867
body: ""
footer:
Change-type: minor
change-type: minor
author: Otávio Jacobi
nested: []
- subject: changes analytics endpoint to analytics-backend
hash: c163662f4a63e1a3b0621ef28c8720f6f4a1edcd
body: ""
footer:
change-type: minor
author: Otávio Jacobi
nested: []
version: 14.5.0
title: "'changes analytics endpoint to analytics-backend'"
date: 2022-10-18T11:18:18.257Z
- commits:
- subject: Update simple-git to 3.14.1
hash: 70330759007bfdba81986e6c7db1f5c2cb0d7d5f
body: ""
footer:
Change-type: patch
change-type: patch
Signed-off-by: Thodoris Greasidis <thodoris@balena.io>
signed-off-by: Thodoris Greasidis <thodoris@balena.io>
author: Thodoris Greasidis
nested: []
version: 14.4.4
title: "'Update simple git'"
date: 2022-10-18T10:00:35.080Z
- commits:
- subject: "config generate: Fix the incompatible arch errors showing as not found"
hash: 2e115968d5dce98fe05ab0607e1c04bd9f4c67c8
body: ""
footer:
Change-type: patch
change-type: patch
Signed-off-by: Thodoris Greasidis <thodoris@balena.io>
signed-off-by: Thodoris Greasidis <thodoris@balena.io>
author: Thodoris Greasidis
nested: []
version: 14.4.3
title: "'config generate: Fix the incompatible arch errors showing as not found'"
date: 2022-10-17T20:46:59.653Z
- commits:
- subject: Stop relying on device-type.json for resolving the device type aliases
hash: a20d2a04a86797d77819c63e556d8ec7d4c128ca
body: ""
footer:
Resolves: "#2541"
resolves: "#2541"
Change-type: patch
change-type: patch
Signed-off-by: Thodoris Greasidis <thodoris@balena.io>
signed-off-by: Thodoris Greasidis <thodoris@balena.io>
author: Thodoris Greasidis
nested: []
- subject: Stop relying on device-type.json for resolving the cpu architecture
hash: 57b0dccc7d12197dc78c2b8fd4f3cdb6329ec510
body: ""
footer:
Resolves: "#2542"
resolves: "#2542"
Change-type: patch
change-type: patch
Signed-off-by: Thodoris Greasidis <thodoris@balena.io>
signed-off-by: Thodoris Greasidis <thodoris@balena.io>
author: Thodoris Greasidis
nested: []
version: 14.4.2
title: "'Stop relying on device-type.json for resolving the cpu architecture'"
date: 2022-10-17T16:15:07.388Z
- commits:
- subject: "balena os initialize: Clarify that the process includes flashing"
hash: e46902e6839eeb2f59f445aeef94500bd34b8c14
@ -843,8 +1503,8 @@
- subject: "patch: bump browserify from 14.5.0 to 17.0.0"
hash: 2ee532e8dcc3eda0c54296f468f7f9a9e637071a
body: >
Bumps [browserify](https://github.com/browserify/browserify)
from 14.5.0 to 17.0.0.
Bumps [browserify](https://github.com/browserify/browserify) from 14.5.0
to 17.0.0.
- [Release notes](https://github.com/browserify/browserify/releases)
@ -873,8 +1533,7 @@
- subject: "patch: bump tmp from 0.0.31 to 0.2.1"
hash: e905a6a8054297c89e75447e5ff48ca92e13bd49
body: >
Bumps [tmp](https://github.com/raszi/node-tmp) from 0.0.31 to
0.2.1.
Bumps [tmp](https://github.com/raszi/node-tmp) from 0.0.31 to 0.2.1.
- [Release notes](https://github.com/raszi/node-tmp/releases)
@ -957,8 +1616,7 @@
- subject: "patch: bump mocha from 3.5.3 to 10.0.0"
hash: 548996665b7e6159e5e209aa4a10987e071da024
body: >
Bumps [mocha](https://github.com/mochajs/mocha) from 3.5.3 to
10.0.0.
Bumps [mocha](https://github.com/mochajs/mocha) from 3.5.3 to 10.0.0.
- [Release notes](https://github.com/mochajs/mocha/releases)
@ -1001,8 +1659,8 @@
- subject: "patch: bump mockttp from 0.9.1 to 2.7.0"
hash: fa44187e4e510171666f046d6a3a658f59956fd4
body: >-
Bumps [mockttp](https://github.com/httptoolkit/mockttp) from
0.9.1 to 2.7.0.
Bumps [mockttp](https://github.com/httptoolkit/mockttp) from 0.9.1 to
2.7.0.
- [Release notes](https://github.com/httptoolkit/mockttp/releases)
@ -1075,8 +1733,8 @@
- subject: "patch: bump superagent from 3.8.3 to 7.1.2"
hash: ae3974af1965386bf236b7ae295e4a9ecc285f0c
body: >
Bumps [superagent](https://github.com/visionmedia/superagent)
from 3.8.3 to 7.1.2.
Bumps [superagent](https://github.com/visionmedia/superagent) from 3.8.3
to 7.1.2.
- [Release notes](https://github.com/visionmedia/superagent/releases)
@ -1105,8 +1763,7 @@
- subject: "patch: bump dotenv from 4.0.0 to 16.0.0"
hash: b2ddda64df84d5a109b2adc1ee847ff5aef17000
body: >
Bumps [dotenv](https://github.com/motdotla/dotenv) from 4.0.0 to
16.0.0.
Bumps [dotenv](https://github.com/motdotla/dotenv) from 4.0.0 to 16.0.0.
- [Release notes](https://github.com/motdotla/dotenv/releases)
@ -1245,8 +1902,8 @@
- subject: "minor: Add trying SDK in the browser"
hash: 50a6ca1844869eaccaf3275361a4016f7a284c05
body: >
Add information about using SDK in the browser as a partial.
Solving: https://github.com/balena-io/docs/issues/2205
Add information about using SDK in the browser as a partial. Solving:
https://github.com/balena-io/docs/issues/2205
footer:
Signed-off-by: Vipul Gupta (@vipulgupta2048) <vipul@balena.io>
signed-off-by: Vipul Gupta (@vipulgupta2048) <vipul@balena.io>
@ -1333,8 +1990,7 @@
- subject: Remove unnecessary vpn address filtering when fetching local addresses
hash: 12266a3c9349e5d944ba203e56f2fe80b5e97970
body: >
This has been handled by the supervisor since v2.2.0 / balenaOS
v1.14
This has been handled by the supervisor since v2.2.0 / balenaOS v1.14
from 2016-09-23 and is not relevant for any supported devices
footer:
@ -1704,8 +2360,8 @@
- subject: Add support for building images with progress
hash: e072408ee951d3caf46af5050d0b71991d114614
body: >
Using build instead of pull allows to add metadata (e.g. labels)
to pulled images in an
Using build instead of pull allows to add metadata (e.g. labels) to pulled
images in an
atomic way. This commit adds the `DockerProgres.build()` method to
@ -2794,8 +3450,7 @@
- subject: Allow more lenient gzip decompression
hash: 9c7bc3051b279c9d09ec501a78dbe9f506d65650
body: >
Be more lenient with decoding compressed
responses, since (very rarely)
Be more lenient with decoding compressed responses, since (very rarely)
servers send slightly invalid gzip responses that are still accepted
@ -4468,8 +5123,8 @@
- subject: Improve directory scan speed prior to tarballing
hash: 257dd514ed7c0f6988b8a47219991cc4f61b4529
body: >
This changes improves the speed that the project is tarballed by
switching from
This changes improves the speed that the project is tarballed by switching
from
`klaw` to `recursive-fs` and not running `lstat` on files that are ignored.
@ -4980,8 +5635,7 @@
- subject: Allow more lenient gzip decompression
hash: 9c7bc3051b279c9d09ec501a78dbe9f506d65650
body: >
Be more lenient with decoding compressed responses,
since (very rarely)
Be more lenient with decoding compressed responses, since (very rarely)
servers send slightly invalid gzip responses that are still accepted
@ -5279,8 +5933,7 @@
- subject: Add balena.yml handling and `--draft` to `balena deploy` release creation
hash: 7d568a928b4297671e3776b72f64a6e2845d5f72
body: >
This change allows use of a contract and release semver when doing a
push,
This change allows use of a contract and release semver when doing a push,
and is part of the larger feature to use the builder as part of a CI/CD pipeline.
footer:
@ -6650,8 +7303,7 @@
- subject: "docker: Improve handling of Docker-in-Docker errors"
hash: 9036ce9af373eb8d328f105839163db0cae38ae6
body: >
The `local` logging driver captures output from containers
stdout/stderr
The `local` logging driver captures output from containers stdout/stderr
and writes them to an internal storage that is optimized for performance and disk use.
@ -10310,8 +10962,7 @@
- commits:
- author: Thodoris Greasidis
body: >-
Didn't convert the source, so that we don't end
up
Didn't convert the source, so that we don't end up
having conflicts with other ongoing PRs.
footers:
@ -17937,8 +18588,7 @@
subject: "dependencies: bump etcher-sdk to pull in fixes"
- author: Gergely Imreh
body: >-
To fix the same error as here
https://github.com/nodejs/node/issues/20285
To fix the same error as here https://github.com/nodejs/node/issues/20285
Task changes as described at https://fettblog.eu/gulp-4-parallel-and-series/
footers:
@ -19481,11 +20131,11 @@
subject: Improve `selectFromList` function signature to be much more reusable
- author: Akis Kesoglou
body: >-
Both commands work with local devices by remotely invoking the
`os-config` executable via SSH. This requires an as of yet unreleased
resinOS (that will most likely be v2.14) and the commands ascertain
compatibility merely by looking for the `os-config` executable in the
device, and bail out if its not present.
Both commands work with local devices by remotely invoking the `os-config`
executable via SSH. This requires an as of yet unreleased resinOS (that
will most likely be v2.14) and the commands ascertain compatibility
merely by looking for the `os-config` executable in the device, and bail
out if its not present.
`join` and `leave` accept a couple of optional arguments and implement a wizard-style interface if these are not given. They allow to interactively select the device and the application to promote to. If the user has no apps, `join` will offer the user to create one. `join` will also offer the user to login or create an account if theyre not logged in already without exiting the wizard.
@ -20151,9 +20801,9 @@
subject: Fix invoking undefined method
- author: Akis Kesoglou
body: >-
Legacy behaviour is mostly retained. The most notable change in
behaviour is that invoking `resin deploy` without options is now allowed
(see help string how it behaves).
Legacy behaviour is mostly retained. The most notable change in behaviour
is that invoking `resin deploy` without options is now allowed (see help
string how it behaves).
In this commit there are also the following notable changes:

View File

@ -4,6 +4,186 @@ 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/).
## 15.1.3 - 2023-04-05
<details>
<summary> devices supported: Fix showing types without a valid & finalized release [Thodoris Greasidis] </summary>
> ### balena-sdk-16.28.2 - 2022-10-27
>
> * Update tests to run on node 18 [Thodoris Greasidis]
> * deviceType.getAllSupported: Require a valid & final release to exist [Thodoris Greasidis]
>
> ### balena-sdk-16.28.1 - 2022-10-14
>
> * flowzone: Run the node tests using the latest LTS version [Thodoris Greasidis]
>
</details>
## 15.1.2 - 2023-03-27
* Improve type checking by using the satisfies operator [Thodoris Greasidis]
## 15.1.1 - 2023-03-17
* Update TypeScript to 5.0.2 [Thodoris Greasidis]
## 15.1.0 - 2023-03-14
<details>
<summary> Update balena-compose to v2.2.1 [Kyle Harding] </summary>
> ### balena-compose-2.2.1 - 2023-03-14
>
> * Ignore references to build stages when evaluating manifests [Kyle Harding]
>
> ### balena-compose-2.2.0 - 2023-03-13
>
> * OCI Image Index should allow platform opts [Kyle Harding]
>
> ### balena-compose-2.1.4 - 2023-03-13
>
> * Write to debug log when using platform option [Kyle Harding]
>
> ### balena-compose-2.1.3 - 2023-03-01
>
> * Fixup tests to use recent debian:bullseye-slim images [Kyle Harding]
>
> ### balena-compose-2.1.2 - 2022-10-17
>
> * test/multibuild: Use 127.0.0.1 for the extra_hosts test [Ken Bannister]
> * Output error text to aid test debugging [Ken Bannister]
> * Replace balenaCI & circleCI with flowzone [Thodoris Greasidis]
> * Pin dockerode to v3.3.3 to avoid regression [Ken Bannister]
> * Prettify fixup [Ken Bannister]
> * Fix underspecified generics in release/models [Ken Bannister]
>
</details>
## 15.0.6 - 2023-03-13
* Devices: explicitly fetches only used fields [Otávio Jacobi]
## 15.0.5 - 2023-03-10
* Fix application isLegacy check for rename and deploy [JSReds]
## 15.0.4 - 2023-02-21
* patch: Clarify update rate of update notifier info [Heath Raftery]
## 15.0.3 - 2023-01-18
* Use https for the npm deprecation check, avoiding a redirect [Pagan Gazzard]
## 15.0.2 - 2023-01-14
* Fix push --nolive doc typo [Josh Bowling]
## 15.0.1 - 2023-01-10
* Process livepush build logs inline [Felipe Lalanne]
## 15.0.0 - 2023-01-02
* preload: Drops ability to preload Intel Edison (EOL 2017) Upgrade balena-preload from 12.2.0 to 13.0.0 [JOASSART Edwin]
## 14.5.18 - 2022-12-29
* Update flowzone tests to use npm ci [Thodoris Greasidis]
## 14.5.17 - 2022-12-28
* Stop using the deprecated balena-sync module [Thodoris Greasidis]
## 14.5.16 - 2022-12-28
* Update the npm-shrinkwrap.json dependencies to match the package.json [Thodoris Greasidis]
## 14.5.15 - 2022-12-12
* patch: update balena-preload to 12.2.0 [Edwin Joassart]
## 14.5.14 - 2022-12-11
* Bump multicast-dns to rebased commit (again) [pipex]
## 14.5.13 - 2022-12-08
* Build on macos-11 for library compatibility reasons [Page-]
* Build on ubuntu-20.04 for library compatibility reasons [Page-]
## 14.5.12 - 2022-11-21
* Move GH publishing to FZ core [ab77]
## 14.5.11 - 2022-11-17
* Adding .nvmrc so we can use nvm use instead of hunting for version [zoobot]
## 14.5.10 - 2022-11-11
* Fix surfacing incompatible device type errors as not recognized [Thodoris Greasidis]
## 14.5.9 - 2022-11-11
* Prevent git from existing with 141 [ab77]
## 14.5.8 - 2022-11-10
* Replace missing input [ab77]
## 14.5.7 - 2022-11-10
* Just ignore errors during publish [ab77]
## 14.5.6 - 2022-11-10
* Ignore PIPE signal [ab77]
## 14.5.5 - 2022-11-10
* Don't pipefail [ab77]
## 14.5.4 - 2022-11-10
* Error when the device type and image parameters do not match [Thodoris Greasidis]
## 14.5.3 - 2022-11-10
* Switch to Flowzone [ab77]
## 14.5.2 - 2022-10-21
* Stop waiting for the analytics response [Thodoris Greasidis]
## 14.5.1 - 2022-10-20
* Bump parse-link-header from 1.0.1 to 2.0.0 [dependabot[bot]]
## 14.5.0 - 2022-10-18
* keeps events loggiging with default message [Otávio Jacobi]
* uses amplitude data events format [Otávio Jacobi]
* changes analytics endpoint to analytics-backend [Otávio Jacobi]
## 14.4.4 - 2022-10-18
* Update simple-git to 3.14.1 [Thodoris Greasidis]
## 14.4.3 - 2022-10-17
* config generate: Fix the incompatible arch errors showing as not found [Thodoris Greasidis]
## 14.4.2 - 2022-10-17
* Stop relying on device-type.json for resolving the device type aliases [Thodoris Greasidis]
* Stop relying on device-type.json for resolving the cpu architecture [Thodoris Greasidis]
## 14.4.1 - 2022-10-12
* balena os initialize: Clarify that the process includes flashing [Heath Raftery]

View File

@ -78,8 +78,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 12 (min 12.8.0).**
> **Versions 13 and later are not yet fully supported.**
> **The balena CLI currently requires Node.js version 14.**
> **Versions 15 and later are not yet fully supported.**
### Install development tools
@ -89,7 +89,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 12
$ nvm install 14
```
The `curl` command line above uses
@ -106,14 +106,14 @@ recommended.
```sh
$ curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.38.0/install.sh | bash
$ . ~/.bashrc
$ nvm install 12
$ nvm install 14
```
#### **Windows** (not WSL)
Install:
* Node.js v12 from the [Nodejs.org releases page](https://nodejs.org/en/download/releases/).
* Node.js v14 from the [Nodejs.org releases page](https://nodejs.org/en/download/releases/).
* If you'd like the ability to switch between Node.js versions, install
[nvm-windows](https://github.com/coreybutler/nvm-windows#node-version-manager-nvm-for-windows)
instead.

View File

@ -45,8 +45,6 @@ const execFileAsync = promisify(execFile);
export const packageJSON = loadPackageJson();
export const version = 'v' + packageJSON.version;
const arch = process.arch;
const MSYS2_BASH =
process.env.MSYSSHELLPATH || 'C:\\msys64\\usr\\bin\\bash.exe';
function dPath(...paths: string[]) {
return path.join(ROOT, 'dist', ...paths);
@ -425,20 +423,28 @@ async function renameInstallerFiles() {
/**
* If the CSC_LINK and CSC_KEY_PASSWORD env vars are set, digitally sign the
* executable installer by running the balena-io/scripts/shared/sign-exe.sh
* script (which must be in the PATH) using a MSYS2 bash shell.
* executable installer using Microsoft SignTool.exe (Sign Tool)
* https://learn.microsoft.com/en-us/dotnet/framework/tools/signtool-exe
*/
async function signWindowsInstaller() {
if (process.env.CSC_LINK && process.env.CSC_KEY_PASSWORD) {
const exeName = renamedOclifInstallers[process.platform];
console.log(`Signing installer "${exeName}"`);
await execFileAsync(MSYS2_BASH, [
'sign-exe.sh',
// trust ...
await execFileAsync('signtool.exe', [
'sign',
'-t',
process.env.TIMESTAMP_SERVER || 'http://timestamp.comodoca.com',
'-f',
exeName,
process.env.CSC_LINK,
'-p',
process.env.CSC_KEY_PASSWORD,
'-d',
`balena-cli ${version}`,
exeName,
]);
// ... but verify
await execFileAsync('signtool.exe', ['verify', '-pa', '-v', exeName]);
} else {
console.log(
'Skipping installer signing step because CSC_* env vars are not set',
@ -450,14 +456,21 @@ async function signWindowsInstaller() {
* Wait for Apple Installer Notarization to continue
*/
async function notarizeMacInstaller(): Promise<void> {
const appleId = 'accounts+apple@balena.io';
const { notarize } = await import('electron-notarize');
await notarize({
appBundleId: 'io.balena.etcher',
appPath: renamedOclifInstallers.darwin,
appleId,
appleIdPassword: '@keychain:CLI_PASSWORD',
});
const appleId =
process.env.XCODE_APP_LOADER_EMAIL || 'accounts+apple@balena.io';
const appBundleId = packageJSON.oclif.macos.identifier || 'io.balena.cli';
const appleIdPassword = process.env.XCODE_APP_LOADER_PASSWORD;
if (appleIdPassword) {
const { notarize } = await import('electron-notarize');
// https://github.com/electron/notarize/blob/main/README.md
await notarize({
appBundleId,
appPath: renamedOclifInstallers.darwin,
appleId,
appleIdPassword,
});
}
}
/**

View File

@ -15,11 +15,12 @@
* limitations under the License.
*/
const stripIndent = require('common-tags/lib/stripIndent');
const _ = require('lodash');
const { promises: fs } = require('fs');
const path = require('path');
const simplegit = require('simple-git/promise');
// tslint:disable-next-line:import-blacklist
import { stripIndent } from 'common-tags';
import * as _ from 'lodash';
import { promises as fs } from 'fs';
import * as path from 'path';
import { simpleGit } from 'simple-git';
const ROOT = path.normalize(path.join(__dirname, '..'));
@ -31,7 +32,7 @@ const ROOT = path.normalize(path.join(__dirname, '..'));
* using `touch`.
*/
async function checkBuildTimestamps() {
const git = simplegit(ROOT);
const git = simpleGit(ROOT);
const docFile = path.join(ROOT, 'docs', 'balena-cli.md');
const [docStat, gitStatus] = await Promise.all([
fs.stat(docFile),
@ -81,4 +82,5 @@ async function run() {
}
}
// tslint:disable-next-line:no-floating-promises
run();

View File

@ -2788,7 +2788,7 @@ used (usually $HOME/.balena/secrets.yml|.json)
Don't run a live session on this push. The filesystem will not be monitored,
and changes will not be synchronized to any running containers. Note that both
this flag and --detached and required to cause the process to end once the
this flag and --detached are required to cause the process to end once the
initial build has completed.
#### -d, --detached

View File

@ -175,26 +175,26 @@ export default class ConfigGenerateCmd extends Command {
const deviceType = options.deviceType || resourceDeviceType;
const deviceManifest = await balena.models.device.getManifestBySlug(
deviceType,
);
// Check compatibility if application and deviceType provided
if (options.fleet && options.deviceType) {
const appDeviceManifest = await balena.models.device.getManifestBySlug(
resourceDeviceType,
);
const helpers = await import('../../utils/helpers');
if (
!helpers.areDeviceTypesCompatible(appDeviceManifest, deviceManifest)
!(await helpers.areDeviceTypesCompatible(
resourceDeviceType,
deviceType,
))
) {
throw new balena.errors.BalenaInvalidDeviceType(
const { ExpectedError } = await import('../../errors');
throw new ExpectedError(
`Device type ${options.deviceType} is incompatible with fleet ${options.fleet}`,
);
}
}
const deviceManifest = await balena.models.device.getManifestBySlug(
deviceType,
);
// Prompt for values
// Pass params as an override: if there is any param with exactly the same name as a
// required option, that value is used (and the corresponding question is not asked)

View File

@ -340,7 +340,7 @@ ${dockerignoreHelp}
);
let release: Release | ComposeReleaseInfo['release'];
if (appType?.is_legacy) {
if (appType.slug === 'legacy-v1' || appType.slug === 'legacy-v2') {
const { deployLegacy } = require('../utils/deploy-legacy');
const msg = getChalk().yellow(

View File

@ -21,6 +21,7 @@ import type {
BalenaSDK,
Device,
DeviceType,
PineOptions,
PineTypedResult,
} from 'balena-sdk';
import Command from '../../command';
@ -153,7 +154,7 @@ export default class DeviceMoveCmd extends Command {
$select: 'slug',
},
},
} as const;
} satisfies PineOptions<DeviceType>;
const deviceTypes = (await balena.models.deviceType.getAllSupported(
deviceTypeOptions,
)) as Array<PineTypedResult<DeviceType, typeof deviceTypeOptions>>;

View File

@ -22,7 +22,7 @@ import { expandForAppName } from '../../utils/helpers';
import { getBalenaSdk, getVisuals, stripIndent } from '../../utils/lazy';
import { applicationIdInfo, jsonInfo } from '../../utils/messages';
import type { Application } from 'balena-sdk';
import type { Application, Device, PineOptions } from 'balena-sdk';
interface ExtendedDevice extends DeviceWithDeviceType {
dashboard_url?: string;
@ -36,6 +36,18 @@ interface FlagsDef {
json: boolean;
}
const devicesSelectFields = {
$select: [
'id',
'uuid',
'device_name',
'status',
'is_online',
'supervisor_version',
'os_version',
],
} satisfies PineOptions<Device>;
export default class DevicesCmd extends Command {
public static description = stripIndent`
List all devices.
@ -70,6 +82,7 @@ export default class DevicesCmd extends Command {
const { flags: options } = this.parse<FlagsDef, {}>(DevicesCmd);
const balena = getBalenaSdk();
const devicesOptions = { ...devicesSelectFields, ...expandForAppName };
let devices;
@ -78,11 +91,11 @@ export default class DevicesCmd extends Command {
const application = await getApplication(balena, options.fleet);
devices = (await balena.models.device.getAllByApplication(
application.id,
expandForAppName,
devicesOptions,
)) as ExtendedDevice[];
} else {
devices = (await balena.models.device.getAll(
expandForAppName,
devicesOptions,
)) as ExtendedDevice[];
}

View File

@ -15,6 +15,7 @@
* limitations under the License.
*/
import { flags } from '@oclif/command';
import type * as BalenaSdk from 'balena-sdk';
import * as _ from 'lodash';
import Command from '../../command';
@ -59,36 +60,38 @@ export default class DevicesSupportedCmd extends Command {
public async run() {
const { flags: options } = this.parse<FlagsDef, {}>(DevicesSupportedCmd);
const [dts, configDTs] = await Promise.all([
getBalenaSdk().models.deviceType.getAllSupported({
$expand: { is_of__cpu_architecture: { $select: 'slug' } },
$select: ['slug', 'name'],
}),
getBalenaSdk().models.config.getDeviceTypes(),
]);
const dtsBySlug = _.keyBy(dts, (dt) => dt.slug);
const configDTsBySlug = _.keyBy(configDTs, (dt) => dt.slug);
const pineOptions = {
$select: ['slug', 'name'],
$expand: {
is_of__cpu_architecture: { $select: 'slug' },
device_type_alias: {
$select: 'is_referenced_by__alias',
$orderby: { is_referenced_by__alias: 'asc' },
},
},
} satisfies BalenaSdk.PineOptions<BalenaSdk.DeviceType>;
const dts = (await getBalenaSdk().models.deviceType.getAllSupported(
pineOptions,
)) as Array<
BalenaSdk.PineTypedResult<BalenaSdk.DeviceType, typeof pineOptions>
>;
interface DT {
slug: string;
aliases: string[];
arch: string;
name: string;
}
let deviceTypes: DT[] = [];
for (const slug of Object.keys(dtsBySlug)) {
const configDT: Partial<typeof configDTs[0]> =
configDTsBySlug[slug] || {};
const aliases = (configDT.aliases || []).filter(
(alias) => alias !== slug,
);
const dt: Partial<typeof dts[0]> = dtsBySlug[slug] || {};
deviceTypes.push({
slug,
let deviceTypes = dts.map((dt): DT => {
const aliases = dt.device_type_alias
.map((dta) => dta.is_referenced_by__alias)
.filter((alias) => alias !== dt.slug);
return {
slug: dt.slug,
aliases: options.json ? aliases : [aliases.join(', ')],
arch: (dt.is_of__cpu_architecture as any)?.[0]?.slug || 'n/a',
arch: dt.is_of__cpu_architecture[0]?.slug || 'n/a',
name: dt.name || 'N/A',
});
}
};
});
const fields = ['slug', 'aliases', 'arch', 'name'];
deviceTypes = _.sortBy(deviceTypes, fields);
if (options.json) {

View File

@ -80,7 +80,7 @@ export default class FleetRenameCmd extends Command {
const application = await getApplication(balena, params.fleet, {
$expand: {
application_type: {
$select: ['is_legacy'],
$select: ['slug'],
},
},
});
@ -92,7 +92,7 @@ export default class FleetRenameCmd extends Command {
// Check app supports renaming
const appType = (application.application_type as ApplicationType[])?.[0];
if (appType.is_legacy) {
if (appType.slug === 'legacy-v1' || appType.slug === 'legacy-v2') {
throw new ExpectedError(
`Fleet ${params.fleet} is of 'legacy' type, and cannot be renamed.`,
);

View File

@ -215,7 +215,7 @@ export default class OsConfigureCmd extends Command {
is_for__device_type: { $select: 'slug' },
},
})) as ApplicationWithDeviceType;
await checkDeviceTypeCompatibility(balena, options, app);
await checkDeviceTypeCompatibility(options, app);
deviceTypeSlug =
options['device-type'] || app.is_for__device_type[0].slug;
}
@ -361,17 +361,17 @@ async function getOsVersionFromImage(
* @param app Balena SDK Application model object
*/
async function checkDeviceTypeCompatibility(
sdk: BalenaSdk.BalenaSDK,
options: FlagsDef,
app: ApplicationWithDeviceType,
) {
if (options['device-type']) {
const [appDeviceType, optionDeviceType] = await Promise.all([
sdk.models.device.getManifestBySlug(app.is_for__device_type[0].slug),
sdk.models.device.getManifestBySlug(options['device-type']),
]);
const helpers = await import('../../utils/helpers');
if (!helpers.areDeviceTypesCompatible(appDeviceType, optionDeviceType)) {
if (
!(await helpers.areDeviceTypesCompatible(
app.is_for__device_type[0].slug,
options['device-type'],
))
) {
throw new ExpectedError(
`Device type ${options['device-type']} is incompatible with fleet ${options.fleet}`,
);

View File

@ -187,7 +187,7 @@ Can be repeated to add multiple certificates.\
: undefined;
const progressBars: {
[key: string]: ReturnType<typeof getVisuals>['Progress'];
[key: string]: InstanceType<ReturnType<typeof getVisuals>['Progress']>;
} = {};
const progressHandler = function (event: {
@ -201,7 +201,7 @@ Can be repeated to add multiple certificates.\
};
const spinners: {
[key: string]: ReturnType<typeof getVisuals>['Spinner'];
[key: string]: InstanceType<ReturnType<typeof getVisuals>['Spinner']>;
} = {};
const spinnerHandler = function (event: { name: string; action: string }) {

View File

@ -178,7 +178,7 @@ export default class PushCmd extends Command {
description: stripIndent`
Don't run a live session on this push. The filesystem will not be monitored,
and changes will not be synchronized to any running containers. Note that both
this flag and --detached and required to cause the process to end once the
this flag and --detached are required to cause the process to end once the
initial build has completed.`,
default: false,
}),

View File

@ -16,7 +16,6 @@
*/
import { flags } from '@oclif/command';
import type { LocalBalenaOsDevice } from 'balena-sync';
import Command from '../command';
import * as cf from '../utils/common-flags';
import { getCliUx, stripIndent } from '../utils/lazy';
@ -72,7 +71,7 @@ export default class ScanCmd extends Command {
public async run() {
const _ = await import('lodash');
const { discover } = await import('balena-sync');
const { discoverLocalBalenaOsDevices } = await import('../utils/discover');
const prettyjson = await import('prettyjson');
const dockerUtils = await import('../utils/docker');
@ -88,8 +87,7 @@ export default class ScanCmd extends Command {
const ux = getCliUx();
ux.action.start('Scanning for local balenaOS devices');
const localDevices: LocalBalenaOsDevice[] =
await discover.discoverLocalBalenaOsDevices(discoverTimeout);
const localDevices = await discoverLocalBalenaOsDevices(discoverTimeout);
const engineReachableDevices: boolean[] = await Promise.all(
localDevices.map(async ({ address }: { address: string }) => {
const docker = await dockerUtils.createClient({
@ -106,7 +104,7 @@ export default class ScanCmd extends Command {
}),
);
const developmentDevices: LocalBalenaOsDevice[] = localDevices.filter(
const developmentDevices = localDevices.filter(
(_localDevice, index) => engineReachableDevices[index],
);
@ -116,18 +114,15 @@ export default class ScanCmd extends Command {
_.isEqual,
);
const productionDevicesInfo = _.map(
productionDevices,
(device: LocalBalenaOsDevice) => {
return {
host: device.host,
address: device.address,
osVariant: 'production',
dockerInfo: undefined,
dockerVersion: undefined,
};
},
);
const productionDevicesInfo = productionDevices.map((device) => {
return {
host: device.host,
address: device.address,
osVariant: 'production',
dockerInfo: undefined,
dockerVersion: undefined,
};
});
// Query devices for info
const devicesInfo = await Promise.all(

View File

@ -86,7 +86,7 @@ export class DeprecationChecker {
* @param version Semver without 'v' prefix, e.g. '12.0.0.'
*/
protected getNpmUrl(version: string) {
return `http://registry.npmjs.org/balena-cli/${version}`;
return `https://registry.npmjs.org/balena-cli/${version}`;
}
/**

View File

@ -177,7 +177,16 @@ const messages: {
Looks like the session token has expired.
Try logging in again with the "balena login" command.`,
BalenaInvalidDeviceType: (error: Error & { deviceTypeSlug?: string }) => {
BalenaInvalidDeviceType: (
error: Error & { deviceTypeSlug?: string; type?: string },
) => {
// TODO: The SDK should be throwing a different Error for this case.
if (
typeof error.type === 'string' &&
error.type.startsWith('Incompatible ')
) {
return error.type;
}
const slug = error.deviceTypeSlug ? `"${error.deviceTypeSlug}"` : 'slug';
return stripIndent`
Device type ${slug} not recognized. Perhaps misspelled?

View File

@ -73,38 +73,52 @@ export async function trackCommand(commandSignature: string) {
}
}
const TIMEOUT = 4000;
/**
* Make the event tracking HTTPS request to balenaCloud's '/mixpanel' endpoint.
*/
async function sendEvent(balenaUrl: string, event: string, username?: string) {
const { default: got } = await import('got');
const trackData = {
event,
properties: {
arch: process.arch,
balenaUrl, // e.g. 'balena-cloud.com' or 'balena-staging.com'
distinct_id: username,
mp_lib: 'node',
node: process.version,
platform: process.platform,
token: 'balena-main',
version: packageJSON.version,
},
};
const url = `https://api.${balenaUrl}/mixpanel/track`;
const searchParams = {
ip: 0,
verbose: 0,
data: Buffer.from(JSON.stringify(trackData)).toString('base64'),
api_key: 'balena-main',
events: [
{
event_type: event,
user_id: username,
version_name: packageJSON.version,
event_properties: {
balenaUrl, // e.g. 'balena-cloud.com' or 'balena-staging.com'
arch: process.arch,
platform: process.platform,
node: process.version,
},
},
],
};
const url = `https://data.${balenaUrl}/amplitude/2/httpapi`;
try {
await got(url, { searchParams, retry: 0, timeout: 4000 });
await got.post(url, {
json: trackData,
retry: 0,
timeout: {
// Starts when the request is initiated.
request: TIMEOUT,
// Starts when request has been flushed.
// Exits the request as soon as it's sent.
response: 0,
},
});
} catch (e) {
if (process.env.DEBUG) {
console.error(`[debug] Event tracking error: ${e.message || e}`);
}
if (e instanceof got.TimeoutError) {
if (
e instanceof got.TimeoutError &&
TIMEOUT < (e.timings.phases.total ?? 0)
) {
console.error(stripIndent`
Timeout submitting analytics event to balenaCloud/openBalena.
If you are using the balena CLI in an air-gapped environment with a filtered

View File

@ -91,7 +91,7 @@ export default class BalenaHelp extends Help {
.map((pc) => {
return commands.find((c) => c.id === pc.replace(' ', ':'));
})
.filter((c): c is typeof commands[0] => !!c);
.filter((c): c is (typeof commands)[0] => !!c);
let usageLength = 0;
for (const cmd of primaryCommands) {

View File

@ -107,16 +107,6 @@ export const getDeviceAndMaybeAppFromUUID = _.memoize(
(_sdk, deviceUUID) => deviceUUID,
);
/** Given a device type alias like 'nuc', return the actual slug like 'intel-nuc'. */
export const unaliasDeviceType = _.memoize(async function (
sdk: SDK.BalenaSDK,
deviceType: string,
): Promise<string> {
return (
(await sdk.models.device.getManifestBySlug(deviceType)).slug || deviceType
);
});
/**
* Download balenaOS image for the specified `deviceType`.
* `OSVersion` may be one of:
@ -255,8 +245,8 @@ export async function getOsVersions(
);
// if slug is an alias, fetch the real slug
if (!versions.length) {
// unaliasDeviceType() produces a nice error msg if slug is invalid
slug = await unaliasDeviceType(sdk, slug);
// unalias device type slug
slug = (await sdk.models.deviceType.get(slug, { $select: 'slug' })).slug;
if (slug !== deviceType) {
versions = await sdk.models.os.getAvailableOsVersions(slug);
}

View File

@ -209,9 +209,9 @@ export async function deployToDevice(opts: DeviceDeployOptions): Promise<void> {
globalLogger.logDebug('Fetching device information...');
const deviceInfo = await api.getDeviceInformation();
let buildLogs: Dictionary<string> | undefined;
let imageIds: Dictionary<string[]> | undefined;
if (!opts.nolive) {
buildLogs = {};
imageIds = {};
}
const { awaitInterruptibleTask } = await import('../helpers');
@ -223,7 +223,7 @@ export async function deployToDevice(opts: DeviceDeployOptions): Promise<void> {
deviceInfo,
globalLogger,
opts,
buildLogs,
imageIds,
);
globalLogger.outputDeferredMessages();
@ -265,7 +265,7 @@ export async function deployToDevice(opts: DeviceDeployOptions): Promise<void> {
docker,
logger: globalLogger,
composition: project.composition,
buildLogs: buildLogs!,
imageIds: imageIds!,
deployOpts: opts,
});
promises.push(livepush.init());
@ -312,6 +312,14 @@ function connectToDocker(host: string, port: number): Docker {
});
}
function extractDockerArrowMessage(outputLine: string): string | undefined {
const arrowTest = /^.*\s*-+>\s*(.+)/i;
const match = arrowTest.exec(outputLine);
if (match != null) {
return match[1];
}
}
async function performBuilds(
composition: Composition,
tarStream: Readable,
@ -319,7 +327,7 @@ async function performBuilds(
deviceInfo: DeviceInfo,
logger: Logger,
opts: DeviceDeployOptions,
buildLogs?: Dictionary<string>,
imageIds?: Dictionary<string[]>,
): Promise<BuildTask[]> {
const multibuild = await import('@balena/compose/dist/multibuild');
@ -345,14 +353,29 @@ async function performBuilds(
// If we're passed a build logs object make sure to set it
// up properly
let logHandlers: ((serviceName: string, line: string) => void) | undefined;
if (buildLogs != null) {
const lastArrowMessage: Dictionary<string> = {};
if (imageIds != null) {
for (const task of buildTasks) {
if (!task.external) {
buildLogs[task.serviceName] = '';
imageIds[task.serviceName] = [];
}
}
logHandlers = (serviceName: string, line: string) => {
buildLogs[serviceName] += `${line}\n`;
// If this was a from line, take the last found
// image id and save it
if (
/step \d+(?:\/\d+)?\s*:\s*FROM/i.test(line) &&
lastArrowMessage[serviceName] != null
) {
imageIds[serviceName].push(lastArrowMessage[serviceName]);
} else {
const msg = extractDockerArrowMessage(line);
if (msg != null) {
lastArrowMessage[serviceName] = msg;
}
}
};
}
@ -413,12 +436,26 @@ export async function rebuildSingleTask(
// the logs, so any calller who wants to keep track of
// this should provide the following callback
containerIdCb?: (id: string) => void,
): Promise<string> {
): Promise<string[]> {
const multibuild = await import('@balena/compose/dist/multibuild');
// First we run the build task, to get the new image id
let buildLogs = '';
const stageIds = [] as string[];
let lastArrowMessage: string | undefined;
const logHandler = (_s: string, line: string) => {
buildLogs += `${line}\n`;
// If this was a FROM line, take the last found
// image id and save it as a stage id
if (
/step \d+(?:\/\d+)?\s*:\s*FROM/i.test(line) &&
lastArrowMessage != null
) {
stageIds.push(lastArrowMessage);
} else {
const msg = extractDockerArrowMessage(line);
if (msg != null) {
lastArrowMessage = msg;
}
}
if (containerIdCb != null) {
const match = line.match(/^\s*--->\s*Running\s*in\s*([a-f0-9]*)\s*$/i);
@ -477,7 +514,7 @@ export async function rebuildSingleTask(
]);
}
return buildLogs;
return stageIds;
}
function assignOutputHandlers(

View File

@ -52,7 +52,6 @@ interface MonitoredContainer {
containerId: string;
}
type BuildLogs = Dictionary<string>;
type StageImageIDs = Dictionary<string[]>;
export interface LivepushOpts {
@ -62,7 +61,7 @@ export interface LivepushOpts {
docker: Dockerode;
api: DeviceAPI;
logger: Logger;
buildLogs: BuildLogs;
imageIds: StageImageIDs;
deployOpts: DeviceDeployOptions;
}
@ -97,7 +96,7 @@ export class LivepushManager {
this.api = opts.api;
this.logger = opts.logger;
this.deployOpts = opts.deployOpts;
this.imageIds = LivepushManager.getMultistageImageIDs(opts.buildLogs);
this.imageIds = opts.imageIds;
}
public async init(): Promise<void> {
@ -297,33 +296,6 @@ export class LivepushManager {
return new Dockerfile(content).generateLiveDockerfile();
}
private static getMultistageImageIDs(buildLogs: BuildLogs): StageImageIDs {
const stageIds: StageImageIDs = {};
_.each(buildLogs, (log, serviceName) => {
stageIds[serviceName] = [];
const lines = log.split(/\r?\n/);
let lastArrowMessage: string | undefined;
for (const line of lines) {
// If this was a from line, take the last found
// image id and save it
if (
/step \d+(?:\/\d+)?\s*:\s*FROM/i.test(line) &&
lastArrowMessage != null
) {
stageIds[serviceName].push(lastArrowMessage);
} else {
const msg = LivepushManager.extractDockerArrowMessage(line);
if (msg != null) {
lastArrowMessage = msg;
}
}
}
});
return stageIds;
}
private async awaitDeviceStateSettle(): Promise<void> {
// Cache the state to avoid unnecessary calls
this.lastDeviceStatus = await this.api.getStatus();
@ -405,9 +377,9 @@ export class LivepushManager {
);
}
let buildLog: string;
let stageImages: string[];
try {
buildLog = await rebuildSingleTask(
stageImages = await rebuildSingleTask(
serviceName,
this.docker,
this.logger,
@ -466,17 +438,13 @@ export class LivepushManager {
);
}
const buildLogs: Dictionary<string> = {};
buildLogs[serviceName] = buildLog;
const stageImages = LivepushManager.getMultistageImageIDs(buildLogs);
const dockerfile = new Dockerfile(buildTask.dockerfile!);
instance.livepush = await Livepush.init({
dockerfile,
context: buildTask.context!,
containerId: container.containerId,
stageImages: stageImages[serviceName],
stageImages,
docker: this.docker,
});
this.assignLivepushOutputHandlers(serviceName, instance.livepush);
@ -536,16 +504,6 @@ export class LivepushManager {
});
}
private static extractDockerArrowMessage(
outputLine: string,
): string | undefined {
const arrowTest = /^.*\s*-+>\s*(.+)/i;
const match = arrowTest.exec(outputLine);
if (match != null) {
return match[1];
}
}
private getDockerfilePathFromTask(task: BuildTask): string[] {
switch (task.projectType) {
case 'Standard Dockerfile':

40
lib/utils/discover.ts Normal file
View File

@ -0,0 +1,40 @@
import { enumerateServices, findServices } from 'resin-discoverable-services';
interface LocalBalenaOsDevice {
address: string;
host: string;
osVariant?: string;
port: number;
}
// Although we only check for 'balena-ssh', we know, implicitly, that balenaOS
// devices come with 'rsync' installed that can be used over SSH.
const avahiBalenaSshTag = 'resin-ssh';
export async function discoverLocalBalenaOsDevices(
timeout = 4000,
): Promise<LocalBalenaOsDevice[]> {
const availableServices = await enumerateServices();
const serviceDefinitions = Array.from(availableServices)
.filter((s) => Array.from(s.tags).includes(avahiBalenaSshTag))
.map((s) => s.service);
if (serviceDefinitions.length === 0) {
throw new Error(
`Could not find any available '${avahiBalenaSshTag}' services`,
);
}
const services = await findServices(serviceDefinitions, timeout);
return services.map(function (service) {
// User referer address to get device IP. This will work fine assuming that
// a device only advertises own services.
const {
referer: { address },
host,
port,
} = service;
return { address, host, port };
});
}

View File

@ -107,21 +107,50 @@ export async function getManifest(
deviceType: string,
): Promise<BalenaSdk.DeviceTypeJson.DeviceType> {
const init = await import('balena-device-init');
const sdk = getBalenaSdk();
const manifest = await init.getImageManifest(image);
if (manifest != null) {
return manifest;
if (
manifest != null &&
manifest.slug !== deviceType &&
manifest.slug !== (await sdk.models.deviceType.get(deviceType)).slug
) {
const { ExpectedError } = await import('../errors');
throw new ExpectedError(
`The device type of the provided OS image ${manifest.slug}, does not match the expected device type ${deviceType}`,
);
}
return getBalenaSdk().models.device.getManifestBySlug(deviceType);
return manifest ?? (await sdk.models.device.getManifestBySlug(deviceType));
}
export const areDeviceTypesCompatible = (
appDeviceType: BalenaSdk.DeviceTypeJson.DeviceType,
osDeviceType: BalenaSdk.DeviceTypeJson.DeviceType,
) =>
getBalenaSdk().models.os.isArchitectureCompatibleWith(
osDeviceType.arch,
appDeviceType.arch,
) && !!appDeviceType.isDependent === !!osDeviceType.isDependent;
export const areDeviceTypesCompatible = async (
appDeviceTypeSlug: string,
osDeviceTypeSlug: string,
) => {
if (appDeviceTypeSlug === osDeviceTypeSlug) {
return true;
}
const sdk = getBalenaSdk();
const pineOptions = {
$select: 'is_of__cpu_architecture',
$expand: {
is_of__cpu_architecture: {
$select: 'slug',
},
},
} satisfies BalenaSdk.PineOptions<BalenaSdk.DeviceType>;
const [appDeviceType, osDeviceType] = await Promise.all(
[appDeviceTypeSlug, osDeviceTypeSlug].map(
(dtSlug) =>
sdk.models.deviceType.get(dtSlug, pineOptions) as Promise<
BalenaSdk.PineTypedResult<BalenaSdk.DeviceType, typeof pineOptions>
>,
),
);
return sdk.models.os.isArchitectureCompatibleWith(
osDeviceType.is_of__cpu_architecture[0].slug,
appDeviceType.is_of__cpu_architecture[0].slug,
);
};
export async function osProgressHandler(step: InitializeEmitter) {
step.on('stdout', process.stdout.write.bind(process.stdout));
@ -155,7 +184,7 @@ export async function getAppWithArch(
const options: BalenaSdk.PineOptions<BalenaSdk.Application> = {
$expand: {
application_type: {
$select: ['name', 'slug', 'supports_multicontainer', 'is_legacy'],
$select: ['name', 'slug', 'supports_multicontainer'],
},
is_for__device_type: {
$select: 'slug',
@ -410,11 +439,11 @@ export function getProxyConfig(): ProxyConfig | undefined {
export const expandForAppName = {
$expand: {
belongs_to__application: { $select: ['app_name', 'slug'] as any },
belongs_to__application: { $select: ['app_name', 'slug'] },
is_of__device_type: { $select: 'slug' },
is_running__release: { $select: 'commit' },
},
} as const;
} satisfies BalenaSdk.PineOptions<BalenaSdk.Device>;
export const expandForAppNameAndCpuArch = {
$expand: {
@ -428,7 +457,7 @@ export const expandForAppNameAndCpuArch = {
},
},
},
} as const;
} satisfies BalenaSdk.PineOptions<BalenaSdk.Device>;
/**
* Use the `readline` library on Windows to install SIGINT handlers.

View File

@ -163,12 +163,61 @@ async function getOsVersion(deviceIp: string): Promise<string> {
return match[1];
}
const dockerPort = 2375;
const dockerTimeout = 2000;
async function selectLocalBalenaOsDevice(timeout = 4000): Promise<string> {
const { discoverLocalBalenaOsDevices } = await import('../utils/discover');
const { SpinnerPromise } = getVisuals();
const devices = await new SpinnerPromise({
promise: discoverLocalBalenaOsDevices(timeout),
startMessage: 'Discovering local balenaOS devices..',
stopMessage: 'Reporting discovered devices',
});
const responsiveDevices: typeof devices = [];
const Docker = await import('docker-toolbelt');
await Promise.all(
devices.map(async function (device) {
const address = device?.address;
if (!address) {
return;
}
try {
const docker = new Docker({
host: address,
port: dockerPort,
timeout: dockerTimeout,
});
await docker.ping();
responsiveDevices.push(device);
} catch {
return;
}
}),
);
if (!responsiveDevices.length) {
throw new Error('Could not find any local balenaOS devices');
}
return getCliForm().ask({
message: 'select a device',
type: 'list',
default: devices[0].address,
choices: responsiveDevices.map((device) => ({
name: `${device.host || 'untitled'} (${device.address})`,
value: device.address,
})),
});
}
async function selectLocalDevice(): Promise<string> {
const { forms } = await import('balena-sync');
let hostnameOrIp;
try {
hostnameOrIp = await forms.selectLocalBalenaOsDevice();
const hostnameOrIp = await selectLocalBalenaOsDevice();
console.error(`==> Selected device: ${hostnameOrIp}`);
return hostnameOrIp;
} catch (e) {
if (e.message.toLowerCase().includes('could not find any')) {
throw new ExpectedError(e);
@ -176,8 +225,6 @@ async function selectLocalDevice(): Promise<string> {
throw e;
}
}
return hostnameOrIp;
}
async function selectAppFromList(
@ -198,31 +245,37 @@ async function selectAppFromList(
async function getOrSelectApplication(
sdk: BalenaSdk.BalenaSDK,
deviceType: string,
deviceTypeSlug: string,
appName?: string,
): Promise<ApplicationWithDeviceType> {
const _ = await import('lodash');
const pineOptions = {
$select: 'slug',
$expand: {
is_of__cpu_architecture: {
$select: 'slug',
},
},
} satisfies BalenaSdk.PineOptions<BalenaSdk.DeviceType>;
const [deviceType, allDeviceTypes] = await Promise.all([
sdk.models.deviceType.get(deviceTypeSlug, pineOptions) as Promise<
BalenaSdk.PineTypedResult<BalenaSdk.DeviceType, typeof pineOptions>
>,
sdk.models.deviceType.getAllSupported(pineOptions) as Promise<
Array<BalenaSdk.PineTypedResult<BalenaSdk.DeviceType, typeof pineOptions>>
>,
]);
const allDeviceTypes = await sdk.models.config.getDeviceTypes();
const deviceTypeManifest = _.find(allDeviceTypes, { slug: deviceType });
if (!deviceTypeManifest) {
throw new ExpectedError(`"${deviceType}" is not a valid device type`);
}
const compatibleDeviceTypes = _(allDeviceTypes)
.filter(
(dt) =>
sdk.models.os.isArchitectureCompatibleWith(
deviceTypeManifest.arch,
dt.arch,
) &&
!!dt.isDependent === !!deviceTypeManifest.isDependent &&
dt.state !== 'DISCONTINUED',
const compatibleDeviceTypes = allDeviceTypes
.filter((dt) =>
sdk.models.os.isArchitectureCompatibleWith(
deviceType.is_of__cpu_architecture[0].slug,
dt.is_of__cpu_architecture[0].slug,
),
)
.map((type) => type.slug)
.value();
.map((type) => type.slug);
if (!appName) {
return createOrSelectApp(sdk, compatibleDeviceTypes, deviceType);
return createOrSelectApp(sdk, compatibleDeviceTypes, deviceTypeSlug);
}
const options: BalenaSdk.PineOptions<BalenaSdk.Application> = {
@ -257,13 +310,13 @@ async function getOrSelectApplication(
undefined,
true,
);
return await createApplication(sdk, deviceType, name);
return await createApplication(sdk, deviceTypeSlug, name);
}
// We've found at least one fleet with the given name.
// Filter out fleets for non-matching device types and see what we're left with.
const validApplications = applications.filter((app) =>
_.includes(compatibleDeviceTypes, app.is_for__device_type[0].slug),
compatibleDeviceTypes.includes(app.is_for__device_type[0].slug),
);
if (validApplications.length === 0) {

View File

@ -151,23 +151,23 @@ export async function runRemoteCommand({
let exitCode: number | undefined;
let exitSignal: NodeJS.Signals | undefined;
try {
[exitCode, exitSignal] = await new Promise<[number, NodeJS.Signals]>(
(resolve, reject) => {
const ps = spawn(program, args, { stdio })
.on('error', reject)
.on('close', (code, signal) => resolve([code, signal]));
[exitCode, exitSignal] = await new Promise((resolve, reject) => {
const ps = spawn(program, args, { stdio })
.on('error', reject)
.on('close', (code, signal) =>
resolve([code ?? undefined, signal ?? undefined]),
);
if (ps.stdin && stdin && typeof stdin !== 'string') {
stdin.pipe(ps.stdin);
}
if (ps.stdout && stdout && typeof stdout !== 'string') {
ps.stdout.pipe(stdout);
}
if (ps.stderr && stderr && typeof stderr !== 'string') {
ps.stderr.pipe(stderr);
}
},
);
if (ps.stdin && stdin && typeof stdin !== 'string') {
stdin.pipe(ps.stdin);
}
if (ps.stdout && stdout && typeof stdout !== 'string') {
ps.stdout.pipe(stdout);
}
if (ps.stderr && stderr && typeof stderr !== 'string') {
ps.stderr.pipe(stderr);
}
});
} catch (error) {
const msg = [
`ssh failed with exit code=${exitCode} signal=${exitSignal}:`,

View File

@ -19,8 +19,10 @@ import * as UpdateNotifier from 'update-notifier';
import packageJSON = require('../../package.json');
// Check for an update once a day. 1 day granularity should be
// enough, rather than every run.
// Check for an update at most once a day. 1 day granularity should be
// enough, rather than every run. Note because we show the information
// from the *last* time we ran, if the cli has not been run for a while
// the update info can be out of date.
const balenaUpdateInterval = 1000 * 60 * 60 * 24 * 1;
let notifier: UpdateNotifier.UpdateNotifier;

1286
npm-shrinkwrap.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
{
"name": "balena-cli",
"version": "14.4.1",
"version": "15.1.3",
"description": "The official balena Command Line Interface",
"main": "./build/app.js",
"homepage": "https://github.com/balena-io/balena-cli",
@ -27,7 +27,6 @@
"scripts": [
"build/**/*.js",
"node_modules/balena-sdk/es2018/index.js",
"node_modules/balena-sync/build/**/*.js",
"node_modules/pinejs-client-request/node_modules/pinejs-client-core/es2018/index.js",
"node_modules/@balena/compose/dist/parse/schemas/*.json"
],
@ -90,12 +89,11 @@
"author": "Balena Inc. (https://balena.io/)",
"license": "Apache-2.0",
"engines": {
"node": ">=12.8.0 <13.0.0",
"npm": "<7.0.0"
"node": ">=14 <16"
},
"husky": {
"hooks": {
"pre-commit": "node automation/check-npm-version.js && node automation/check-doc.js"
"pre-commit": "node automation/check-npm-version.js && ts-node automation/check-doc.ts"
}
},
"oclif": {
@ -115,7 +113,7 @@
]
},
"devDependencies": {
"@balena/lint": "^6.2.0",
"@balena/lint": "^6.2.2",
"@oclif/config": "^1.18.2",
"@oclif/parser": "^3.8.6",
"@octokit/plugin-throttling": "^3.5.1",
@ -147,7 +145,7 @@
"@types/ndjson": "^2.0.1",
"@types/net-keepalive": "^0.4.1",
"@types/nock": "^11.1.0",
"@types/node": "^12.20.42",
"@types/node": "^14.18.36",
"@types/node-cleanup": "^2.1.2",
"@types/parse-link-header": "^1.0.1",
"@types/prettyjson": "^0.0.30",
@ -184,17 +182,17 @@
"mocha": "^8.4.0",
"mock-require": "^3.0.3",
"nock": "^13.2.1",
"parse-link-header": "^1.0.1",
"parse-link-header": "^2.0.0",
"pkg": "^5.5.1",
"publish-release": "^1.6.1",
"rewire": "^5.0.0",
"simple-git": "^2.48.0",
"simple-git": "^3.14.1",
"sinon": "^11.1.2",
"ts-node": "^10.4.0",
"typescript": "^4.6.4"
"typescript": "^5.0.2"
},
"dependencies": {
"@balena/compose": "^2.1.1",
"@balena/compose": "^2.2.1",
"@balena/dockerignore": "^1.0.2",
"@balena/es-version": "^1.0.1",
"@oclif/command": "^1.8.16",
@ -208,12 +206,11 @@
"balena-errors": "^4.7.1",
"balena-image-fs": "^7.0.6",
"balena-image-manager": "^8.0.0",
"balena-preload": "^12.1.0",
"balena-sdk": "^16.28.0",
"balena-preload": "^13.0.0",
"balena-sdk": "^16.28.2",
"balena-semver": "^2.3.0",
"balena-settings-client": "^4.0.7",
"balena-settings-storage": "^7.0.0",
"balena-sync": "^11.0.2",
"bluebird": "^3.7.2",
"body-parser": "^1.19.1",
"chalk": "^3.0.0",
@ -226,6 +223,7 @@
"denymount": "^2.3.0",
"docker-modem": "3.0.0",
"docker-progress": "^5.1.3",
"docker-toolbelt": "^3.3.10",
"dockerode": "^3.3.1",
"ejs": "^3.1.6",
"etcher-sdk": "^6.2.1",
@ -263,6 +261,7 @@
"request": "^2.88.2",
"resin-cli-form": "^2.0.2",
"resin-cli-visuals": "^1.8.0",
"resin-discoverable-services": "^2.0.3",
"resin-doodles": "^0.2.0",
"resin-stream-logger": "^0.1.2",
"rimraf": "^3.0.2",
@ -285,6 +284,6 @@
"windosu": "^0.3.0"
},
"versionist": {
"publishedAt": "2022-10-12T13:55:51.707Z"
"publishedAt": "2023-04-05T08:06:55.314Z"
}
}

View File

@ -10,8 +10,6 @@ upstream:
url: 'https://github.com/balena-io-modules/balena-image-manager'
- repo: 'balena-preload'
url: 'https://github.com/balena-io-modules/balena-preload'
- repo: 'balena-sync'
url: 'https://github.com/balena-io-modules/balena-sync'
- repo: 'etcher-sdk'
url: 'https://github.com/balena-io-modules/etcher-sdk/'
- repo: 'balena-compose'

View File

@ -38,7 +38,7 @@ describe('balena devices', function () {
it('should list devices from own and collaborator apps', async () => {
api.scope
.get(
'/v6/device?$orderby=device_name%20asc&$expand=belongs_to__application($select=app_name,slug),is_of__device_type($select=slug),is_running__release($select=commit)',
'/v6/device?$orderby=device_name%20asc&$select=id,uuid,device_name,status,is_online,supervisor_version,os_version&$expand=belongs_to__application($select=app_name,slug),is_of__device_type($select=slug),is_running__release($select=commit)',
)
.replyWithFile(200, path.join(apiResponsePath, 'devices.json'), {
'Content-Type': 'application/json',

View File

@ -44,7 +44,6 @@ describe('balena devices supported', function () {
it('should list currently supported devices, with correct filtering', async () => {
api.expectGetDeviceTypes();
api.expectGetConfigDeviceTypes();
const { out, err } = await runCommand('devices supported');
@ -54,7 +53,7 @@ describe('balena devices supported', function () {
expect(lines).to.have.lengthOf.at.least(2);
expect(lines).to.contain('intel-nuc nuc amd64 Intel NUC');
expect(lines).to.contain(
'odroid-xu4 odroid-ux3, odroid-u3+ armv7hf ODROID-XU4',
'odroid-xu4 odroid-u3+, odroid-ux3 armv7hf ODROID-XU4',
);
expect(err).to.eql([]);
});

View File

@ -178,7 +178,7 @@ async function startMockSshServer(): Promise<[Server, number]> {
});
return await new Promise<[Server, number]>((resolve, reject) => {
// TODO: remove 'as any' below. According to @types/node v12.20.42, the
// TODO: remove 'as any' below. According to @types/node v14.18.36, the
// callback type is `() => void`, but our code assumes `(err: Error) => void`
const listener = (server.listen as any)(0, '127.0.0.1', (err: Error) => {
// this callback is called for the 'listening' event

View File

@ -113,7 +113,7 @@ async function createProxyServer(): Promise<[number, number]> {
let proxyPort = 0; // TCP port number, 0 means automatic allocation
await new Promise<void>((resolve, reject) => {
// TODO: remove 'as any' below. According to @types/node v12.20.42, the
// TODO: remove 'as any' below. According to @types/node v14.18.36, the
// callback type is `() => void`, but our code assumes `(err: Error) => void`
const listener = (server.listen as any)(0, '127.0.0.1', (err: Error) => {
if (err) {
@ -197,7 +197,7 @@ async function createInterceptorServer(): Promise<number> {
let interceptorPort = 0;
await new Promise<void>((resolve, reject) => {
// TODO: remove 'as any' below. According to @types/node v12.20.42, the
// TODO: remove 'as any' below. According to @types/node v14.18.36, the
// callback type is `() => void`, but our code assumes `(err: Error) => void`
const listener = (server.listen as any)(0, '127.0.0.1', (err: Error) => {
if (err) {

View File

@ -6,7 +6,7 @@
"name": "Starter",
"slug": "microservices-starter",
"supports_multicontainer": true,
"is_legacy": false,
"is_legacy": true,
"__metadata": {}
}
],

View File

@ -6,7 +6,7 @@
"name": "Starter",
"slug": "microservices-starter",
"supports_multicontainer": true,
"is_legacy": false,
"is_legacy": true,
"__metadata": {}
}
],

File diff suppressed because it is too large Load Diff

View File

@ -3,20 +3,11 @@
{
"belongs_to__application": [
{
"app_name": "test app",
"slug": "org/test app",
"__metadata": {}
}
],
"id": 1747415,
"belongs_to__user": {
"__deferred": {
"uri": "/resin/user(46272)"
},
"__id": 46272
},
"is_managed_by__device": null,
"actor": 4180757,
"device_name": "sparkling-wood",
"is_of__device_type": [{ "slug": "raspberrypi4-64" }],
"uuid": "fda508c8583011b8466c26abdd5159f2",
@ -25,50 +16,10 @@
"commit": "18756d3386c25a044db66b89e0409804"
}
],
"note": null,
"local_id": null,
"status": "Idle",
"is_online": false,
"last_connectivity_event": "2019-11-23T00:26:35.074Z",
"is_connected_to_vpn": false,
"last_vpn_event": "2019-11-23T00:26:35.074Z",
"ip_address": "192.168.0.112",
"vpn_address": null,
"public_address": "89.186.29.129",
"os_version": "balenaOS 2.44.0+rev3",
"os_variant": "dev",
"supervisor_version": "10.3.7",
"should_be_managed_by__supervisor_release": null,
"is_managed_by__service_instance": {
"__deferred": {
"uri": "/resin/service_instance(124111)"
},
"__id": 124111
},
"provisioning_progress": null,
"provisioning_state": "",
"download_progress": null,
"is_web_accessible": false,
"longitude": "22.5853",
"latitude": "51.2712",
"location": "Lublin, Lublin, Poland",
"custom_longitude": "",
"custom_latitude": "",
"logs_channel": null,
"is_locked_until__date": null,
"is_accessible_by_support_until__date": null,
"created_at": "2019-11-18T12:27:37.423Z",
"is_active": true,
"api_heartbeat_state": "offline",
"cpu_usage" : 34,
"cpu_temp" : 56.2,
"cpu_id" : "some cpu id",
"memory_usage" : 1000,
"memory_total" : 4000,
"storage_block_device" : "/dev/mmcblk0",
"storage_usage" : 1000,
"storage_total" : 64000,
"is_undervolted" : true,
"__metadata": {
"uri": "/resin/device(@id)?@id=1747415"
}
@ -76,14 +27,6 @@
{
"belongs_to__application": [],
"id": 1747416,
"belongs_to__user": {
"__deferred": {
"uri": "/resin/user(46272)"
},
"__id": 46272
},
"is_managed_by__device": null,
"actor": 4180757,
"device_name": "dashing-spruce",
"is_of__device_type": [{ "slug": "raspberrypi4-64" }],
"uuid": "fda508c8583011b8466c26abdd5159f3",
@ -92,50 +35,10 @@
"commit": "18756d3386c25a044db66b89e0409804"
}
],
"note": null,
"local_id": null,
"status": "Idle",
"is_online": false,
"last_connectivity_event": "2019-11-23T00:26:35.074Z",
"is_connected_to_vpn": false,
"last_vpn_event": "2019-11-23T00:26:35.074Z",
"ip_address": "192.168.0.112",
"vpn_address": null,
"public_address": "89.186.29.129",
"os_version": "balenaOS 2.44.0+rev3",
"os_variant": "dev",
"supervisor_version": "10.3.7",
"should_be_managed_by__supervisor_release": null,
"is_managed_by__service_instance": {
"__deferred": {
"uri": "/resin/service_instance(124111)"
},
"__id": 124111
},
"provisioning_progress": null,
"provisioning_state": "",
"download_progress": null,
"is_web_accessible": false,
"longitude": "22.5853",
"latitude": "51.2712",
"location": "Lublin, Lublin, Poland",
"custom_longitude": "",
"custom_latitude": "",
"logs_channel": null,
"is_locked_until__date": null,
"is_accessible_by_support_until__date": null,
"created_at": "2019-11-18T12:27:37.423Z",
"is_active": true,
"api_heartbeat_state": "offline",
"cpu_usage" : 34,
"cpu_temp" : 56.2,
"cpu_id" : "some cpu id",
"memory_usage" : 1000,
"memory_total" : 4000,
"storage_block_device" : "/dev/mmcblk0",
"storage_usage" : 1000,
"storage_total" : 64000,
"is_undervolted" : true,
"__metadata": {
"uri": "/resin/device(@id)?@id=1747415"
}

View File

@ -1,21 +1,3 @@
> Warning Cannot resolve 'module'
node_modules/balena-sync/build/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 Cannot resolve ''./' + command'
node_modules/balena-sync/build/capitano/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 Cannot resolve ''./' + target'
node_modules/balena-sync/build/sync/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 Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules/open/xdg-open

View File

@ -1,21 +1,3 @@
> Warning Cannot resolve 'module'
node_modules/balena-sync/build/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 Cannot resolve ''./' + command'
node_modules/balena-sync/build/capitano/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 Cannot resolve ''./' + target'
node_modules/balena-sync/build/sync/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 Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules/open/xdg-open

View File

@ -1,21 +1,3 @@
> Warning Cannot resolve 'module'
node_modules\balena-sync\build\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 Cannot resolve ''./' + command'
node_modules\balena-sync\build\capitano\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 Cannot resolve ''./' + target'
node_modules\balena-sync\build\sync\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 Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules\open\xdg-open

View File

@ -45,7 +45,7 @@ class MockLivepushManager extends LivepushManager {
docker: {} as import('dockerode'),
api: {} as import('../../../lib/utils/device/api').DeviceAPI,
logger: {} as import('../../../lib/utils/logger'),
buildLogs: {},
imageIds: {},
deployOpts:
{} as import('../../../lib/utils/device/deploy').DeviceDeployOptions,
});

View File

@ -1,41 +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-sync' {
import { CommandDefinition } from 'capitano';
export function capitano(tool: 'balena-cli'): CommandDefinition;
export interface LocalBalenaOsDevice {
address: string;
host: string;
osVariant: string;
port: number;
}
declare namespace forms {
export function selectLocalBalenaOsDevice(
timeout?: number,
): Promise<string>;
}
declare namespace discover {
export function discoverLocalBalenaOsDevices(
timeout?: number,
): Promise<LocalBalenaOsDevice[]>;
}
}

23
typings/docker-toolbelt/index.d.ts vendored Normal file
View File

@ -0,0 +1,23 @@
declare module 'docker-toolbelt' {
import * as Docker from 'dockerode';
interface ImageSpec {
registry?: string;
imageName: string;
tagName: string;
digest?: string;
}
type ProgressCallback = (event: any) => void;
class DockerToolbelt extends Docker {
public getRegistryAndName(image: string): Promise<ImageSpec>;
public createDeltaAsync(
src: string,
dest: string,
onProgress?: ProgressCallback,
): Promise<string>;
}
export = DockerToolbelt;
}

View File

@ -15,4 +15,25 @@
* limitations under the License.
*/
declare module 'resin-cli-visuals';
declare module 'resin-cli-visuals' {
export const Progress: new (...options: any[]) => any;
export class Spinner {
constructor(message?: string);
spinner: any;
start(): void;
stop(): void;
}
export const SpinnerPromise: new <T>(options: {
promise: T;
startMessage: string;
stopMessage: string;
}) => T;
export const table: {
horizontal: (...options: any[]) => any;
vertical: (...options: any[]) => any;
};
export const drive: (...options: any[]) => any;
}