mirror of
https://github.com/balena-io/balena-cli.git
synced 2025-06-24 18:45:07 +00:00
Compare commits
28 Commits
custom-doc
...
v13.7.0
Author | SHA1 | Date | |
---|---|---|---|
f6d668684a | |||
be7c0dc897 | |||
566b7f97e0 | |||
f55dd81a19 | |||
dba5349390 | |||
6a8dfcc664 | |||
59e35d866f | |||
9235c928f1 | |||
3d88f0144a | |||
a6b461ba91 | |||
b96da951db | |||
8235cead07 | |||
30b9d9141d | |||
03b41d9989 | |||
aab3af2153 | |||
600457de61 | |||
17db857e10 | |||
eb45ae2a30 | |||
2eaf70bff3 | |||
226f45f732 | |||
c4990f3a26 | |||
0195a3b18c | |||
3d90aeb122 | |||
0571039bfe | |||
ee668a4c5c | |||
ead4dbfab1 | |||
0b498d09df | |||
2b2c40c22d |
File diff suppressed because it is too large
Load Diff
289
CHANGELOG.md
289
CHANGELOG.md
@ -4,6 +4,295 @@ 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/).
|
||||
|
||||
## 13.7.0 - 2022-07-07
|
||||
|
||||
* Add `--view` flag to `fleet` command for opening a fleet's dashboard page [Matthew Yarmolinsky]
|
||||
|
||||
## 13.6.1 - 2022-06-09
|
||||
|
||||
|
||||
<details>
|
||||
<summary> Update balena-sdk to use the native OS release phase & variant fields [Thodoris Greasidis] </summary>
|
||||
|
||||
> ### balena-sdk-16.22.0 - 2022-06-06
|
||||
>
|
||||
> * os: Start using the release.phase field in the available versions [Thodoris Greasidis]
|
||||
>
|
||||
> ### balena-sdk-16.21.1 - 2022-06-02
|
||||
>
|
||||
> * Add provisioning key expiry date to generateDeviceProvisioningKey [Nitish Agarwal]
|
||||
>
|
||||
> ### balena-sdk-16.21.0 - 2022-06-01
|
||||
>
|
||||
> * os: Refactor the computation of OS releases [Thodoris Greasidis]
|
||||
> * os: Use the model's release variant when the native fields are used [Thodoris Greasidis]
|
||||
>
|
||||
> ### balena-sdk-16.20.6 - 2022-06-01
|
||||
>
|
||||
> * Deprecate the needsPasswordReset field of the JWTUser [Thodoris Greasidis]
|
||||
>
|
||||
> ### balena-sdk-16.20.5 - 2022-05-25
|
||||
>
|
||||
> * Update TypeScript to v4.7 [Thodoris Greasidis]
|
||||
>
|
||||
</details>
|
||||
|
||||
## 13.6.0 - 2022-06-06
|
||||
|
||||
* Update QEMU to v7.0.0 [Kyle Harding]
|
||||
|
||||
## 13.5.3 - 2022-05-31
|
||||
|
||||
* Drop the needsPasswordReset property from the tests [Thodoris Greasidis]
|
||||
|
||||
## 13.5.2 - 2022-05-31
|
||||
|
||||
* Deduplicate npm-shrinkwrap.json [Thodoris Greasidis]
|
||||
|
||||
## 13.5.1 - 2022-05-26
|
||||
|
||||
* preload: Fix issue where balenaOS v2.98.3+ required an Internet connection to start apps [pipex]
|
||||
|
||||
## 13.5.0 - 2022-05-24
|
||||
|
||||
|
||||
<details>
|
||||
<summary> Update balena-sdk to 16.20.4 [Nitish Agarwal] </summary>
|
||||
|
||||
> ### balena-sdk-16.20.4 - 2022-05-09
|
||||
>
|
||||
> * bump @types/node from 10.17.60 to 12.20.500 [Thodoris Greasidis]
|
||||
>
|
||||
> ### balena-sdk-16.20.3 - 2022-05-06
|
||||
>
|
||||
> * patch: bump browserify from 14.5.0 to 17.0.0 [dependabot[bot]]
|
||||
>
|
||||
> ### balena-sdk-16.20.2 - 2022-05-05
|
||||
>
|
||||
> * patch: bump tmp from 0.0.31 to 0.2.1 [dependabot[bot]]
|
||||
>
|
||||
> ### balena-sdk-16.20.1 - 2022-05-05
|
||||
>
|
||||
> * Drop the non-populated apiUrl & actionsUrl properties from Config type [Thodoris Greasidis]
|
||||
>
|
||||
> ### balena-sdk-16.20.0 - 2022-05-04
|
||||
>
|
||||
> * models.apiKey: Update apiKeyInfo with expiryDate option [Nitish Agarwal]
|
||||
> * os.getConfig: Add typings for the provisioningKeyExpiryDate option [Balena CI]
|
||||
>
|
||||
> ### balena-sdk-16.19.14 - 2022-05-04
|
||||
>
|
||||
> * config.getAll: Mark the deviceTypes property as optional [Thodoris Greasidis]
|
||||
>
|
||||
> ### balena-sdk-16.19.13 - 2022-05-03
|
||||
>
|
||||
> * patch: bump mocha from 3.5.3 to 10.0.0 [dependabot[bot]]
|
||||
>
|
||||
> ### balena-sdk-16.19.12 - 2022-05-03
|
||||
>
|
||||
> * config.getAll: Deprecate the pubnub property and mark as optional [Thodoris Greasidis]
|
||||
>
|
||||
> ### balena-sdk-16.19.11 - 2022-05-03
|
||||
>
|
||||
> * patch: bump mockttp from 0.9.1 to 2.7.0 [Thodoris Greasidis]
|
||||
>
|
||||
> ### balena-sdk-16.19.10 - 2022-04-27
|
||||
>
|
||||
> * Reduce the prod typing dependencies [Thodoris Greasidis]
|
||||
>
|
||||
> ### balena-sdk-16.19.9 - 2022-04-26
|
||||
>
|
||||
> * patch: Remove documentation.md from the NPM package [Vipul Gupta]
|
||||
>
|
||||
> ### balena-sdk-16.19.8 - 2022-04-20
|
||||
>
|
||||
> * patch: Remove additional quotes [Vipul Gupta (@vipulgupta2048)]
|
||||
>
|
||||
> ### balena-sdk-16.19.7 - 2022-04-12
|
||||
>
|
||||
> * tests: Update to work with latest major of superagent [Thodoris Greasidis]
|
||||
> * patch: bump superagent from 3.8.3 to 7.1.2 [dependabot[bot]]
|
||||
>
|
||||
> ### balena-sdk-16.19.6 - 2022-04-11
|
||||
>
|
||||
> * patch: bump dotenv from 4.0.0 to 16.0.0 [dependabot[bot]]
|
||||
>
|
||||
> ### balena-sdk-16.19.5 - 2022-04-09
|
||||
>
|
||||
> * Bump karma to v6 [Thodoris Greasidis]
|
||||
>
|
||||
> ### balena-sdk-16.19.4 - 2022-04-09
|
||||
>
|
||||
> * Add dependabot configuration [Thodoris Greasidis]
|
||||
>
|
||||
> ### balena-sdk-16.19.3 - 2022-04-06
|
||||
>
|
||||
> * tests: Update v5 model endpoint prefix references [Thodoris Greasidis]
|
||||
>
|
||||
> ### balena-sdk-16.19.2 - 2022-04-06
|
||||
>
|
||||
>
|
||||
> <details>
|
||||
> <summary> Fix extracting a meaningful error message instead of "[object Object]" [Thodoris Greasidis] </summary>
|
||||
>
|
||||
>> #### balena-request-11.5.5 - 2022-04-06
|
||||
>>
|
||||
>> * Fix extracting the response error from object response bodies [Thodoris Greasidis]
|
||||
>>
|
||||
>> #### balena-request-11.5.4 - 2022-04-06
|
||||
>>
|
||||
>> * Drop explicit karma-chrome-launcher devDependency [Thodoris Greasidis]
|
||||
>>
|
||||
> </details>
|
||||
>
|
||||
>
|
||||
> ### balena-sdk-16.19.1 - 2022-04-05
|
||||
>
|
||||
> * Update balena-request dependency to v11.5.3 [Matthew Yarmolinsky]
|
||||
>
|
||||
> ### balena-sdk-16.19.0 - 2022-03-16
|
||||
>
|
||||
> * Add release.setKnownIssueList function for setting a release's known issue list [Matthew Yarmolinsky]
|
||||
>
|
||||
> ### balena-sdk-16.18.0 - 2022-03-14
|
||||
>
|
||||
> * minor: Add trying SDK in the browser [Vipul Gupta (@vipulgupta2048)]
|
||||
>
|
||||
> ### balena-sdk-16.17.0 - 2022-03-11
|
||||
>
|
||||
> * device.getWithServiceDetails: Add the release id in the service info [Matthew Yarmolinsky]
|
||||
>
|
||||
> ### balena-sdk-16.16.1 - 2022-03-08
|
||||
>
|
||||
> * Replace internal use of deprecated OsVersion.rawVersion with raw_version [Thodoris Greasidis]
|
||||
>
|
||||
> ### balena-sdk-16.16.0 - 2022-03-03
|
||||
>
|
||||
> * Add support for named imports from .mjs files [Thodoris Greasidis]
|
||||
> * Update npx command to fix ts-compatibility tests [Thodoris Greasidis]
|
||||
> * Regenerate Documentation [Thodoris Greasidis]
|
||||
> * Update typescript to 4.6.2 [Thodoris Greasidis]
|
||||
>
|
||||
> ### balena-sdk-16.15.1 - 2022-02-24
|
||||
>
|
||||
> * Remove unnecessary vpn address filtering when fetching local addresses [Pagan Gazzard]
|
||||
>
|
||||
> ### balena-sdk-16.15.0 - 2022-02-16
|
||||
>
|
||||
> * Add applicationClass parameter to application create function for setting is_of__class property [Matthew Yarmolinsky]
|
||||
>
|
||||
> ### balena-sdk-16.14.0 - 2022-02-15
|
||||
>
|
||||
> * Add name and description field to generateDeviceKey for device. [Nitish Agarwal]
|
||||
>
|
||||
> ### balena-sdk-16.13.4 - 2022-01-27
|
||||
>
|
||||
> * typings: Fix conditional $or/$and/$not $filters [Thodoris Greasidis]
|
||||
>
|
||||
> ### balena-sdk-16.13.3 - 2022-01-27
|
||||
>
|
||||
> * Deprecate the supportsBlink field of the DeviceTypeJson.DeviceType type [Thodoris Greasidis]
|
||||
>
|
||||
> ### balena-sdk-16.13.2 - 2022-01-25
|
||||
>
|
||||
> * Deprecate the logoUrl field of the DeviceTypeJson.DeviceType type [Thodoris Greasidis]
|
||||
>
|
||||
> ### balena-sdk-16.13.1 - 2022-01-21
|
||||
>
|
||||
> * Replace internal use of release.contains__image with release_image [Thodoris Greasidis]
|
||||
>
|
||||
> ### balena-sdk-16.13.0 - 2022-01-21
|
||||
>
|
||||
> * models: Deprecate the release.contains__image in favor of the term form [Thodoris Greasidis]
|
||||
> * models: Add the release_image term form property in the Release typings [Thodoris Greasidis]
|
||||
>
|
||||
> ### balena-sdk-16.12.1 - 2022-01-17
|
||||
>
|
||||
> * config.getConfigVarSchema: Send the token only when using a device type [Thodoris Greasidis]
|
||||
>
|
||||
> ### balena-sdk-16.12.0 - 2022-01-10
|
||||
>
|
||||
> * Replace DeviceTypeJson usage for alias resolution with model queries [Thodoris Greasidis]
|
||||
> * models/device-type: Support aliases as argument of the get() method [Thodoris Greasidis]
|
||||
>
|
||||
> ### balena-sdk-16.11.3 - 2022-01-09
|
||||
>
|
||||
> * Fix jsdoc example for balena.errors [Ken Bannister]
|
||||
>
|
||||
> ### balena-sdk-16.11.2 - Invalid date
|
||||
>
|
||||
> * tests: Convert auth spec to async await [Thodoris Greasidis]
|
||||
>
|
||||
> ### balena-sdk-16.11.1 - Invalid date
|
||||
>
|
||||
> * Fix buggy tests causing flakiness on node 16 [Thodoris Greasidis]
|
||||
>
|
||||
> ### balena-sdk-16.11.0 - Invalid date
|
||||
>
|
||||
> * Alias device.getManifestBySlug as config.getDeviceTypeManifestBySlug [Thodoris Greasidis]
|
||||
> * Deprecate device.getManifestByApplication [Thodoris Greasidis]
|
||||
>
|
||||
> ### balena-sdk-16.10.0 - Invalid date
|
||||
>
|
||||
> * application.get: Add support for retrieving applications by uuid [Thodoris Greasidis]
|
||||
> * package.json: Rename the lint-fix npm script to lint:fix [Thodoris Greasidis]
|
||||
>
|
||||
> ### balena-sdk-16.9.4 - 2021-12-29
|
||||
>
|
||||
> * os: Avoid mutating the args in getAvailableOsVersions & getAllOsVersion [Thodoris Greasidis]
|
||||
>
|
||||
> ### balena-sdk-16.9.3 - 2021-12-28
|
||||
>
|
||||
> * os: Replace semver normalization with balena-semver [Thodoris Greasidis]
|
||||
>
|
||||
> ### balena-sdk-16.9.2 - 2021-12-28
|
||||
>
|
||||
> * Stop relying on the balena-pine module [Thodoris Greasidis]
|
||||
>
|
||||
> ### balena-sdk-16.9.1 - 2021-12-28
|
||||
>
|
||||
> * Enable nested changelogs for balena-hup-action-utils [Thodoris Greasidis]
|
||||
>
|
||||
</details>
|
||||
|
||||
* Add provisioning key expiry date option to config generate options [Balena CI]
|
||||
|
||||
## 13.4.3 - 2022-05-19
|
||||
|
||||
|
||||
<details>
|
||||
<summary> Update docker-progress to 5.1.3 [Pagan Gazzard] </summary>
|
||||
|
||||
> ### docker-progress-5.1.3 - 2022-05-11
|
||||
>
|
||||
> * Reject on the stream closing if it has not already ended successfully [Pagan Gazzard]
|
||||
>
|
||||
> ### docker-progress-5.1.2 - 2022-05-10
|
||||
>
|
||||
> * Update dependencies [Pagan Gazzard]
|
||||
>
|
||||
> ### docker-progress-5.1.1 - 2022-05-10
|
||||
>
|
||||
> * Avoid breaking changes to PushPullOptions required properties [Kyle Harding]
|
||||
>
|
||||
> ### docker-progress-5.1.0 - 2022-03-10
|
||||
>
|
||||
> * Add support for building images with progress [Felipe Lalanne]
|
||||
>
|
||||
</details>
|
||||
|
||||
## 13.4.2 - 2022-05-10
|
||||
|
||||
|
||||
<details>
|
||||
<summary> preload: Fix detection of supervisor version for balenaOS v2.93.0 [Kyle Harding] </summary>
|
||||
|
||||
> ### balena-preload-12.0.1 - 2022-05-10
|
||||
>
|
||||
> * Update supervisor image regex to include tagged images [Kyle Harding]
|
||||
>
|
||||
</details>
|
||||
|
||||
## 13.4.1 - 2022-04-11
|
||||
|
||||
* leave: Update log message to advise that device still needs deleting [Taro Murao]
|
||||
|
@ -353,6 +353,7 @@ Examples:
|
||||
|
||||
$ balena fleet MyFleet
|
||||
$ balena fleet myorg/myfleet
|
||||
$ balena fleet myorg/myfleet --view
|
||||
|
||||
### Arguments
|
||||
|
||||
@ -362,6 +363,10 @@ fleet name, slug (preferred), or numeric ID (deprecated)
|
||||
|
||||
### Options
|
||||
|
||||
#### --view
|
||||
|
||||
open fleet dashboard page
|
||||
|
||||
## fleet create <name>
|
||||
|
||||
Create a new balena fleet.
|
||||
@ -811,6 +816,10 @@ path to the config JSON file, see `balena os build-config`
|
||||
|
||||
custom key name assigned to generated provisioning api key
|
||||
|
||||
#### --provisioning-key-expiry-date PROVISIONING-KEY-EXPIRY-DATE
|
||||
|
||||
expiry date assigned to generated provisioning api key (format: YYYY-MM-DD)
|
||||
|
||||
## device local-mode <uuid>
|
||||
|
||||
Output current local mode status, or enable/disable local mode
|
||||
@ -2236,6 +2245,10 @@ paths to local files to place into the 'system-connections' directory
|
||||
|
||||
custom key name assigned to generated provisioning api key
|
||||
|
||||
#### --provisioning-key-expiry-date PROVISIONING-KEY-EXPIRY-DATE
|
||||
|
||||
expiry date assigned to generated provisioning api key (format: YYYY-MM-DD)
|
||||
|
||||
## os initialize <image>
|
||||
|
||||
Initialize an os image for a device with a previously
|
||||
@ -2373,6 +2386,10 @@ supervisor cloud polling interval in minutes (e.g. for device variables)
|
||||
|
||||
custom key name assigned to generated provisioning api key
|
||||
|
||||
#### --provisioning-key-expiry-date PROVISIONING-KEY-EXPIRY-DATE
|
||||
|
||||
expiry date assigned to generated provisioning api key (format: YYYY-MM-DD)
|
||||
|
||||
## config inject <file>
|
||||
|
||||
Inject a 'config.json' file to a balenaOS image file or attached SD card or
|
||||
@ -3020,10 +3037,6 @@ Use QEMU for ARM architecture emulation during the image build
|
||||
|
||||
Alternative Dockerfile name/path, relative to the source folder
|
||||
|
||||
#### --dockercompose DOCKERCOMPOSE
|
||||
|
||||
Alternative docker-compose.yml name in the source root folder
|
||||
|
||||
#### --logs
|
||||
|
||||
No-op and deprecated since balena CLI v12.0.0. Build logs are now shown by default.
|
||||
@ -3248,10 +3261,6 @@ Use QEMU for ARM architecture emulation during the image build
|
||||
|
||||
Alternative Dockerfile name/path, relative to the source folder
|
||||
|
||||
#### --dockercompose DOCKERCOMPOSE
|
||||
|
||||
Alternative docker-compose.yml name in the source root folder
|
||||
|
||||
#### --logs
|
||||
|
||||
No-op and deprecated since balena CLI v12.0.0. Build logs are now shown by default.
|
||||
|
@ -37,6 +37,7 @@ interface FlagsDef {
|
||||
wifiKey?: string;
|
||||
appUpdatePollInterval?: string;
|
||||
'provisioning-key-name'?: string;
|
||||
'provisioning-key-expiry-date'?: string;
|
||||
help: void;
|
||||
}
|
||||
|
||||
@ -81,7 +82,11 @@ export default class ConfigGenerateCmd extends Command {
|
||||
dev: cf.dev,
|
||||
device: {
|
||||
...cf.device,
|
||||
exclusive: ['fleet', 'provisioning-key-name'],
|
||||
exclusive: [
|
||||
'fleet',
|
||||
'provisioning-key-name',
|
||||
'provisioning-key-expiry-date',
|
||||
],
|
||||
},
|
||||
deviceApiKey: flags.string({
|
||||
description:
|
||||
@ -120,6 +125,11 @@ export default class ConfigGenerateCmd extends Command {
|
||||
description: 'custom key name assigned to generated provisioning api key',
|
||||
exclusive: ['device'],
|
||||
}),
|
||||
'provisioning-key-expiry-date': flags.string({
|
||||
description:
|
||||
'expiry date assigned to generated provisioning api key (format: YYYY-MM-DD)',
|
||||
exclusive: ['device'],
|
||||
}),
|
||||
help: cf.help,
|
||||
};
|
||||
|
||||
@ -196,6 +206,7 @@ export default class ConfigGenerateCmd extends Command {
|
||||
answers.version = options.version;
|
||||
answers.developmentMode = options.dev;
|
||||
answers.provisioningKeyName = options['provisioning-key-name'];
|
||||
answers.provisioningKeyExpiryDate = options['provisioning-key-expiry-date'];
|
||||
|
||||
// Generate config
|
||||
const { generateDeviceConfig, generateApplicationConfig } = await import(
|
||||
|
@ -114,7 +114,7 @@ ${dockerignoreHelp}
|
||||
];
|
||||
|
||||
public static usage = 'deploy <fleet> [image]';
|
||||
// TODO: docker-compose naming
|
||||
|
||||
public static flags: flags.Input<FlagsDef> = {
|
||||
source: flags.string({
|
||||
description:
|
||||
|
@ -31,6 +31,7 @@ interface FlagsDef {
|
||||
config?: string;
|
||||
help: void;
|
||||
'provisioning-key-name'?: string;
|
||||
'provisioning-key-expiry-date'?: string;
|
||||
}
|
||||
|
||||
export default class DeviceInitCmd extends Command {
|
||||
@ -97,6 +98,10 @@ export default class DeviceInitCmd extends Command {
|
||||
'provisioning-key-name': flags.string({
|
||||
description: 'custom key name assigned to generated provisioning api key',
|
||||
}),
|
||||
'provisioning-key-expiry-date': flags.string({
|
||||
description:
|
||||
'expiry date assigned to generated provisioning api key (format: YYYY-MM-DD)',
|
||||
}),
|
||||
help: cf.help,
|
||||
};
|
||||
|
||||
@ -185,6 +190,14 @@ export default class DeviceInitCmd extends Command {
|
||||
options['provisioning-key-name'],
|
||||
);
|
||||
}
|
||||
|
||||
if (options['provisioning-key-expiry-date']) {
|
||||
configureCommand.push(
|
||||
'--provisioning-key-expiry-date',
|
||||
options['provisioning-key-expiry-date'],
|
||||
);
|
||||
}
|
||||
|
||||
await runCommand(configureCommand);
|
||||
}
|
||||
|
||||
|
@ -15,7 +15,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import type { flags } from '@oclif/command';
|
||||
import type { flags as flagsType } from '@oclif/command';
|
||||
import { flags } from '@oclif/command';
|
||||
import type { Release } from 'balena-sdk';
|
||||
|
||||
import Command from '../../command';
|
||||
@ -28,6 +29,7 @@ import type { DataOutputOptions } from '../../framework';
|
||||
|
||||
interface FlagsDef extends DataOutputOptions {
|
||||
help: void;
|
||||
view: boolean;
|
||||
}
|
||||
|
||||
interface ArgsDef {
|
||||
@ -45,14 +47,19 @@ export default class FleetCmd extends Command {
|
||||
public static examples = [
|
||||
'$ balena fleet MyFleet',
|
||||
'$ balena fleet myorg/myfleet',
|
||||
'$ balena fleet myorg/myfleet --view',
|
||||
];
|
||||
|
||||
public static args = [ca.fleetRequired];
|
||||
|
||||
public static usage = 'fleet <fleet>';
|
||||
|
||||
public static flags: flags.Input<FlagsDef> = {
|
||||
public static flags: flagsType.Input<FlagsDef> = {
|
||||
help: cf.help,
|
||||
view: flags.boolean({
|
||||
default: false,
|
||||
description: 'open fleet dashboard page',
|
||||
}),
|
||||
...(isV14() ? cf.dataOutputFlags : {}),
|
||||
};
|
||||
|
||||
@ -66,7 +73,9 @@ export default class FleetCmd extends Command {
|
||||
|
||||
const { getApplication } = await import('../../utils/sdk');
|
||||
|
||||
const application = (await getApplication(getBalenaSdk(), params.fleet, {
|
||||
const balena = getBalenaSdk();
|
||||
|
||||
const application = (await getApplication(balena, params.fleet, {
|
||||
$expand: {
|
||||
is_for__device_type: { $select: 'slug' },
|
||||
should_be_running__release: { $select: 'commit' },
|
||||
@ -78,6 +87,15 @@ export default class FleetCmd extends Command {
|
||||
commit?: string;
|
||||
};
|
||||
|
||||
if (options.view) {
|
||||
const open = await import('open');
|
||||
const dashboardUrl = balena.models.application.getDashboardUrl(
|
||||
application.id,
|
||||
);
|
||||
await open(dashboardUrl, { wait: false });
|
||||
return;
|
||||
}
|
||||
|
||||
application.device_type = application.is_for__device_type[0].slug;
|
||||
application.commit = application.should_be_running__release[0]?.commit;
|
||||
|
||||
|
@ -43,6 +43,7 @@ interface FlagsDef {
|
||||
'system-connection': string[];
|
||||
'initial-device-name'?: string;
|
||||
'provisioning-key-name'?: string;
|
||||
'provisioning-key-expiry-date'?: string;
|
||||
}
|
||||
|
||||
interface ArgsDef {
|
||||
@ -58,6 +59,7 @@ interface Answers {
|
||||
wifiSsid?: string;
|
||||
wifiKey?: string;
|
||||
provisioningKeyName?: string;
|
||||
provisioningKeyExpiryDate?: string;
|
||||
}
|
||||
|
||||
export default class OsConfigureCmd extends Command {
|
||||
@ -121,7 +123,7 @@ export default class OsConfigureCmd extends Command {
|
||||
config: flags.string({
|
||||
description:
|
||||
'path to a pre-generated config.json file to be injected in the OS image',
|
||||
exclusive: ['provisioning-key-name'],
|
||||
exclusive: ['provisioning-key-name', 'provisioning-key-expiry-date'],
|
||||
}),
|
||||
'config-app-update-poll-interval': flags.integer({
|
||||
description:
|
||||
@ -138,7 +140,14 @@ export default class OsConfigureCmd extends Command {
|
||||
description: 'WiFi SSID (network name) (non-interactive configuration)',
|
||||
}),
|
||||
dev: cf.dev,
|
||||
device: { ...cf.device, exclusive: ['fleet', 'provisioning-key-name'] },
|
||||
device: {
|
||||
...cf.device,
|
||||
exclusive: [
|
||||
'fleet',
|
||||
'provisioning-key-name',
|
||||
'provisioning-key-expiry-date',
|
||||
],
|
||||
},
|
||||
'device-type': flags.string({
|
||||
description:
|
||||
'device type slug (e.g. "raspberrypi3") to override the fleet device type',
|
||||
@ -161,6 +170,11 @@ export default class OsConfigureCmd extends Command {
|
||||
description: 'custom key name assigned to generated provisioning api key',
|
||||
exclusive: ['config', 'device'],
|
||||
}),
|
||||
'provisioning-key-expiry-date': flags.string({
|
||||
description:
|
||||
'expiry date assigned to generated provisioning api key (format: YYYY-MM-DD)',
|
||||
exclusive: ['config', 'device'],
|
||||
}),
|
||||
help: cf.help,
|
||||
};
|
||||
|
||||
@ -235,6 +249,7 @@ export default class OsConfigureCmd extends Command {
|
||||
answers.version = osVersion;
|
||||
answers.developmentMode = options.dev;
|
||||
answers.provisioningKeyName = options['provisioning-key-name'];
|
||||
answers.provisioningKeyExpiryDate = options['provisioning-key-expiry-date'];
|
||||
|
||||
if (_.isEmpty(configJson)) {
|
||||
if (device) {
|
||||
|
@ -138,7 +138,6 @@ export default class PushCmd extends Command {
|
||||
char: 'e',
|
||||
default: false,
|
||||
}),
|
||||
// TODO: docker-compose naming
|
||||
dockerfile: flags.string({
|
||||
description:
|
||||
'Alternative Dockerfile name/path, relative to the source folder',
|
||||
|
1
lib/utils/compose-types.d.ts
vendored
1
lib/utils/compose-types.d.ts
vendored
@ -61,7 +61,6 @@ export interface ComposeOpts {
|
||||
export interface ComposeCliFlags {
|
||||
emulated: boolean;
|
||||
dockerfile?: string;
|
||||
dockercompose?: string;
|
||||
logs: boolean;
|
||||
nologs: boolean;
|
||||
'multi-dockerignore': boolean;
|
||||
|
@ -1639,7 +1639,6 @@ function truncateString(str: string, len: number): string {
|
||||
return str.slice(0, str.lastIndexOf('\n'));
|
||||
}
|
||||
|
||||
// TODO: docker-compose naming
|
||||
export const composeCliFlags: flags.Input<ComposeCliFlags> = {
|
||||
emulated: flags.boolean({
|
||||
description:
|
||||
@ -1650,10 +1649,6 @@ export const composeCliFlags: flags.Input<ComposeCliFlags> = {
|
||||
description:
|
||||
'Alternative Dockerfile name/path, relative to the source folder',
|
||||
}),
|
||||
dockercompose: flags.string({
|
||||
description:
|
||||
'Alternative docker-compose.yml name in the source root folder',
|
||||
}),
|
||||
logs: flags.boolean({
|
||||
description:
|
||||
'No-op and deprecated since balena CLI v12.0.0. Build logs are now shown by default.',
|
||||
|
@ -92,7 +92,6 @@ async function readDockerIgnoreFile(projectDir: string): Promise<string> {
|
||||
return dockerIgnoreStr;
|
||||
}
|
||||
|
||||
// TODO: docker-compose naming
|
||||
/**
|
||||
* Create an instance of '@balena/dockerignore', initialized with the contents
|
||||
* of a .dockerignore file (if any) found at the given directory argument, plus
|
||||
|
@ -86,7 +86,6 @@ If the --registry-secrets option is not specified, and a secrets.yml or
|
||||
secrets.json file exists in the balena directory (usually $HOME/.balena),
|
||||
this file will be used instead.`;
|
||||
|
||||
// TODO: docker-compose naming
|
||||
export const dockerignoreHelp =
|
||||
'DOCKERIGNORE AND GITIGNORE FILES \n' +
|
||||
`By default, the balena CLI will use a single ".dockerignore" file (if any) at
|
||||
|
@ -21,7 +21,7 @@ import { ExpectedError } from '../errors';
|
||||
import { getBalenaSdk, stripIndent } from './lazy';
|
||||
import Logger = require('./logger');
|
||||
|
||||
export const QEMU_VERSION = 'v6.0.0+balena1';
|
||||
export const QEMU_VERSION = 'v7.0.0+balena1';
|
||||
export const QEMU_BIN_NAME = 'qemu-execve';
|
||||
|
||||
export function qemuPathInContext(context: string) {
|
||||
|
91
npm-shrinkwrap.json
generated
91
npm-shrinkwrap.json
generated
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "balena-cli",
|
||||
"version": "13.4.1",
|
||||
"version": "13.7.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
@ -2550,17 +2550,15 @@
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/docker-modem/-/docker-modem-3.0.2.tgz",
|
||||
"integrity": "sha512-qC7prjoEYR2QEe6SmCVfB1x3rfcQtUr1n4x89+3e0wSTMQ/KYCyf+/RAA9n2tllkkNc6//JMUZePdFRiGIWfaQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/node": "*",
|
||||
"@types/ssh2": "*"
|
||||
}
|
||||
},
|
||||
"@types/dockerode": {
|
||||
"version": "3.3.8",
|
||||
"resolved": "https://registry.npmjs.org/@types/dockerode/-/dockerode-3.3.8.tgz",
|
||||
"integrity": "sha512-/Hip29GzPBWfbSS87lyQDVoB7Ja+kr8oOFWXsySxNFa7jlyj3Yws8LaZRmn1xZl7uJH3Xxsg0oI09GHpT1pIBw==",
|
||||
"dev": true,
|
||||
"version": "3.3.9",
|
||||
"resolved": "https://registry.npmjs.org/@types/dockerode/-/dockerode-3.3.9.tgz",
|
||||
"integrity": "sha512-SYRN5FF/qmwpxUT6snJP5D8k0wgoUKOGVs625XvpRJOOUi6s//UYI4F0tbyE3OmzpI70Fo1+aqpzX27zCrInww==",
|
||||
"requires": {
|
||||
"@types/docker-modem": "*",
|
||||
"@types/node": "*"
|
||||
@ -2696,9 +2694,9 @@
|
||||
"integrity": "sha512-9VN+6yxLOPLOav+7PwjZbxiID2bVaeq0ED4qSQmdQTdjnXJSaCVKTR58t15oqH1H5t8Ng2ZX1SabJVoN9Q34bw=="
|
||||
},
|
||||
"@types/json-schema": {
|
||||
"version": "7.0.9",
|
||||
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz",
|
||||
"integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ=="
|
||||
"version": "7.0.11",
|
||||
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz",
|
||||
"integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ=="
|
||||
},
|
||||
"@types/jsonstream": {
|
||||
"version": "0.8.30",
|
||||
@ -2989,7 +2987,6 @@
|
||||
"version": "0.5.52",
|
||||
"resolved": "https://registry.npmjs.org/@types/ssh2/-/ssh2-0.5.52.tgz",
|
||||
"integrity": "sha512-lbLLlXxdCZOSJMCInKH2+9V/77ET2J6NPQHpFI0kda61Dd1KglJs+fPQBchizmzYSOJBgdTajhPqBO1xxLywvg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/node": "*",
|
||||
"@types/ssh2-streams": "*"
|
||||
@ -2999,7 +2996,6 @@
|
||||
"version": "0.1.9",
|
||||
"resolved": "https://registry.npmjs.org/@types/ssh2-streams/-/ssh2-streams-0.1.9.tgz",
|
||||
"integrity": "sha512-I2J9jKqfmvXLR5GomDiCoHrEJ58hAOmFrekfFqmCFd+A6gaEStvWnPykoWUwld1PNg4G5ag1LwdA+Lz1doRJqg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
@ -3812,9 +3808,9 @@
|
||||
}
|
||||
},
|
||||
"balena-preload": {
|
||||
"version": "12.0.0",
|
||||
"resolved": "https://registry.npmjs.org/balena-preload/-/balena-preload-12.0.0.tgz",
|
||||
"integrity": "sha512-BD4ayIqqopJB0KFFjjlz0rIpcbbHojG8El8qOBLJHvidatgtgVs5xFWBoF5B7fgdJdjRsclA/AbUMZwovN7t3w==",
|
||||
"version": "12.1.0",
|
||||
"resolved": "https://registry.npmjs.org/balena-preload/-/balena-preload-12.1.0.tgz",
|
||||
"integrity": "sha512-nsvsbYYbfkJ4kQ7Hmvq4RDw6yZp36rScNJEoZwY2xIB7Jn+OxIC5EP+XRj6tMkzvKMJYZsdCS/nbSlABxKK6ZQ==",
|
||||
"requires": {
|
||||
"archiver": "^3.1.1",
|
||||
"balena-sdk": "^16.0.0",
|
||||
@ -3985,49 +3981,61 @@
|
||||
}
|
||||
},
|
||||
"balena-sdk": {
|
||||
"version": "16.9.0",
|
||||
"resolved": "https://registry.npmjs.org/balena-sdk/-/balena-sdk-16.9.0.tgz",
|
||||
"integrity": "sha512-iuIiXAEkDXoEtUJzFG5RO+rvudqMsoBppdgQLOrnIdWc14T+mvwWUFKAHHAkvxnA0GLmbxqGp7qo3uVMgS2Ojw==",
|
||||
"version": "16.22.0",
|
||||
"resolved": "https://registry.npmjs.org/balena-sdk/-/balena-sdk-16.22.0.tgz",
|
||||
"integrity": "sha512-HTEC8fYD0SZDlqgn0gcQ7EWliL9XIiGQ/P3f6xxvs4Nj0mG5wYtFrqK8dC6NAR0VQQxzWJtvM6iDFhshLIes7A==",
|
||||
"requires": {
|
||||
"@balena/es-version": "^1.0.0",
|
||||
"@types/json-schema": "^7.0.9",
|
||||
"@types/lodash": "^4.14.168",
|
||||
"@types/memoizee": "^0.4.5",
|
||||
"@types/node": "^10.17.55",
|
||||
"@types/node": "^12.20.50",
|
||||
"abortcontroller-polyfill": "^1.7.1",
|
||||
"balena-auth": "^4.1.0",
|
||||
"balena-errors": "^4.7.1",
|
||||
"balena-hup-action-utils": "~4.1.0",
|
||||
"balena-pine": "^12.4.0",
|
||||
"balena-register-device": "^7.1.0",
|
||||
"balena-request": "^11.5.0",
|
||||
"balena-request": "^11.5.5",
|
||||
"balena-semver": "^2.3.0",
|
||||
"balena-settings-client": "^4.0.6",
|
||||
"lodash": "^4.17.21",
|
||||
"memoizee": "^0.4.15",
|
||||
"moment": "^2.29.1",
|
||||
"ndjson": "^2.0.0",
|
||||
"pinejs-client-core": "^6.9.6",
|
||||
"tslib": "^2.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/node": {
|
||||
"version": "10.17.60",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz",
|
||||
"integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw=="
|
||||
"version": "12.20.55",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz",
|
||||
"integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ=="
|
||||
},
|
||||
"balena-hup-action-utils": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/balena-hup-action-utils/-/balena-hup-action-utils-4.1.0.tgz",
|
||||
"integrity": "sha512-aLVlbdXhJi1rHpTmF9/YbheWtgAmwDUBPk3eKXhJuOZWg4XDnhbP4DUOdPBIM+U+rvXcPeBKOYqsswO0ymd96w==",
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/balena-hup-action-utils/-/balena-hup-action-utils-4.1.1.tgz",
|
||||
"integrity": "sha512-VpyH3py5NPMBJe1fwj5NFUeq58i2V5VaXU1EMa0ja/kUCUwTM1HL5nfNNOU3bd66V+VGqCw49iO7Wppccg3pPg==",
|
||||
"requires": {
|
||||
"balena-semver": "^2.0.0",
|
||||
"tslib": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"balena-request": {
|
||||
"version": "11.5.5",
|
||||
"resolved": "https://registry.npmjs.org/balena-request/-/balena-request-11.5.5.tgz",
|
||||
"integrity": "sha512-sQG+OBAUKOW4KENPRGqit/34l3kWZqoT+aUdpitIG8QdKUrRjKQkjkCmDzprDEDJuXfWoCToKdleN9tYwRCXEw==",
|
||||
"requires": {
|
||||
"@balena/node-web-streams": "^0.2.3",
|
||||
"balena-errors": "^4.7.1",
|
||||
"fetch-ponyfill": "^7.1.0",
|
||||
"fetch-readablestream": "^0.2.0",
|
||||
"progress-stream": "^2.0.0",
|
||||
"qs": "^6.9.4",
|
||||
"tslib": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"tslib": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
|
||||
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
|
||||
"version": "2.4.0",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
|
||||
"integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -4568,7 +4576,7 @@
|
||||
"buffer-shims": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz",
|
||||
"integrity": "sha1-mXjOMXOIxkmth5MCjDR37wRKi1E="
|
||||
"integrity": "sha512-Zy8ZXMyxIT6RMTeY7OP/bDndfj6bwCan7SS98CEndS6deHwWPpseeHlwarNcBim+etXnF9HBc1non5JgDaJU1g=="
|
||||
},
|
||||
"buffers": {
|
||||
"version": "0.1.1",
|
||||
@ -6170,12 +6178,13 @@
|
||||
}
|
||||
},
|
||||
"docker-progress": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/docker-progress/-/docker-progress-5.0.1.tgz",
|
||||
"integrity": "sha512-xVkMZNe48A6jxINzz8X/0jAy5YzAZy8u9QRK8nNSlVp1XHEhYfN0QlFZKOFzq1TO99if+c+yBpn4YZuGcZHG3Q==",
|
||||
"version": "5.1.3",
|
||||
"resolved": "https://registry.npmjs.org/docker-progress/-/docker-progress-5.1.3.tgz",
|
||||
"integrity": "sha512-Ou+o4ISCxMvuoeG09S/irjgleLdG4ZhNiqo31p8vOzDfZm5+JaS2ouHo4lc4kXKqTN6c5eCm+62oRGoaPLDY1A==",
|
||||
"requires": {
|
||||
"@types/dockerode": "^3.3.9",
|
||||
"JSONStream": "^1.3.5",
|
||||
"lodash": "^4.17.15"
|
||||
"lodash": "^4.17.21"
|
||||
}
|
||||
},
|
||||
"docker-qemu-transpose": {
|
||||
@ -10557,7 +10566,7 @@
|
||||
"macmount": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/macmount/-/macmount-1.0.0.tgz",
|
||||
"integrity": "sha1-qsz7nv62fdbpRkm5HMErNtAtLPE=",
|
||||
"integrity": "sha512-kaz5wkgk4lQSAZ+Ch+TJHJHQqjmqM9TOjoLMrOp1mdLlrQBPa2qC/5Hj6OEjklVpMZn6GC2EeBibmSVeyRpXuA==",
|
||||
"optional": true
|
||||
},
|
||||
"magic-string": {
|
||||
@ -17224,9 +17233,9 @@
|
||||
}
|
||||
},
|
||||
"typescript": {
|
||||
"version": "4.5.4",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.4.tgz",
|
||||
"integrity": "sha512-VgYs2A2QIRuGphtzFV7aQJduJ2gyfTljngLzjpfW9FoYZF6xuw1W0vW9ghCKLfcWrCFxK81CSGRAvS1pn4fIUg==",
|
||||
"version": "4.6.4",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.4.tgz",
|
||||
"integrity": "sha512-9ia/jWHIEbo49HfjrLGfKbZSuWo9iTMwXO+Ca3pRsSpbsMbc7/IU8NKdCZVRRBafVPGnoJeFL76ZOAA84I9fEg==",
|
||||
"dev": true
|
||||
},
|
||||
"unbox-primitive": {
|
||||
@ -17387,7 +17396,7 @@
|
||||
"bluebird": {
|
||||
"version": "3.4.7",
|
||||
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.4.7.tgz",
|
||||
"integrity": "sha1-9y12C+Cbf3bQjtj66Ysomo0F+rM="
|
||||
"integrity": "sha512-iD3898SR7sWVRHbiQv+sHUtHnMvC1o3nW5rAcqnq3uOn07DSAppZYUkIGslDz6gXC7HfunPe7YVBgoEJASPcHA=="
|
||||
},
|
||||
"process-nextick-args": {
|
||||
"version": "1.0.7",
|
||||
|
14
package.json
14
package.json
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "balena-cli",
|
||||
"version": "13.4.1",
|
||||
"version": "13.7.0",
|
||||
"description": "The official balena Command Line Interface",
|
||||
"main": "./build/app.js",
|
||||
"homepage": "https://github.com/balena-io/balena-cli",
|
||||
@ -127,7 +127,7 @@
|
||||
"@types/chai-as-promised": "^7.1.4",
|
||||
"@types/cli-truncate": "^2.0.0",
|
||||
"@types/common-tags": "^1.8.1",
|
||||
"@types/dockerode": "^3.3.8",
|
||||
"@types/dockerode": "^3.3.9",
|
||||
"@types/ejs": "^3.1.0",
|
||||
"@types/express": "^4.17.13",
|
||||
"@types/fs-extra": "^9.0.13",
|
||||
@ -191,7 +191,7 @@
|
||||
"simple-git": "^2.48.0",
|
||||
"sinon": "^11.1.2",
|
||||
"ts-node": "^10.4.0",
|
||||
"typescript": "^4.5.4"
|
||||
"typescript": "^4.6.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"@balena/dockerignore": "^1.0.2",
|
||||
@ -207,9 +207,9 @@
|
||||
"balena-errors": "^4.7.1",
|
||||
"balena-image-fs": "^7.0.6",
|
||||
"balena-image-manager": "^7.1.1",
|
||||
"balena-preload": "^12.0.0",
|
||||
"balena-preload": "^12.1.0",
|
||||
"balena-release": "^3.2.0",
|
||||
"balena-sdk": "^16.9.0",
|
||||
"balena-sdk": "^16.22.0",
|
||||
"balena-semver": "^2.3.0",
|
||||
"balena-settings-client": "^4.0.7",
|
||||
"balena-settings-storage": "^7.0.0",
|
||||
@ -225,7 +225,7 @@
|
||||
"common-tags": "^1.7.2",
|
||||
"denymount": "^2.3.0",
|
||||
"docker-modem": "3.0.0",
|
||||
"docker-progress": "^5.0.1",
|
||||
"docker-progress": "^5.1.3",
|
||||
"docker-qemu-transpose": "^1.1.1",
|
||||
"dockerode": "^3.3.1",
|
||||
"ejs": "^3.1.6",
|
||||
@ -288,6 +288,6 @@
|
||||
"windosu": "^0.3.0"
|
||||
},
|
||||
"versionist": {
|
||||
"publishedAt": "2022-04-11T16:10:47.566Z"
|
||||
"publishedAt": "2022-07-07T07:29:37.147Z"
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,6 @@ const johnDoe = {
|
||||
gitlab_id: 1325,
|
||||
social_service_account: null,
|
||||
hasPasswordSet: true,
|
||||
needsPasswordReset: false,
|
||||
public_key: false,
|
||||
features: [],
|
||||
id: 1344,
|
||||
@ -21,7 +20,6 @@ const janeDoe = {
|
||||
social_service_account: null,
|
||||
has_disabled_newsletter: true,
|
||||
hasPasswordSet: true,
|
||||
needsPasswordReset: false,
|
||||
public_key: false,
|
||||
features: [],
|
||||
intercomUserHash:
|
||||
|
@ -59,6 +59,7 @@ if (process.platform !== 'win32') {
|
||||
'--config-network ethernet',
|
||||
'--initial-device-name testDeviceName',
|
||||
'--provisioning-key-name testKey',
|
||||
'--provisioning-key-expiry-date 2050-12-12',
|
||||
];
|
||||
|
||||
const { err } = await runCommand(command.join(' '));
|
||||
|
Reference in New Issue
Block a user