Compare commits

...

5 Commits

Author SHA1 Message Date
ed1946ec36 balena device tunnel
Change-type: patch
2024-11-05 08:04:38 -05:00
ef6d37f073 balena device note
Change-type: patch
2024-11-05 07:57:30 -05:00
01a81b3551 balena device deactivate nit
Change-type: patch
2024-11-05 07:27:13 -05:00
0acf3eb53f balena config generate
Change-type: patch
2024-11-05 07:18:55 -05:00
1565d51a4c balena build
Change-type: patch
2024-11-05 07:18:55 -05:00
21 changed files with 55 additions and 90 deletions

View File

@ -1678,10 +1678,6 @@ note content
device UUID
#### --dev DEV
## device os-update
### Description

View File

@ -37,7 +37,7 @@ export default class APIKeyListCmd extends Command {
char: 'u',
description: 'show API keys for your user',
}),
fleet: cf.fleet,
fleet: cf.fleet(),
};
public static authenticated = true;

View File

@ -86,12 +86,15 @@ ${dockerignoreHelp}
arch: Flags.string({
description: 'the architecture to build for',
char: 'A',
exclusive: ['fleet'],
dependsOn: ['deviceType'],
}),
deviceType: Flags.string({
description: 'the type of device this build is for',
char: 'd',
exclusive: ['fleet'],
}),
fleet: cf.fleet,
fleet: cf.fleet({ exclusive: ['deviceType', 'arch'] }),
...composeCliFlags,
...dockerCliFlags,
};
@ -148,17 +151,6 @@ ${dockerignoreHelp}
}
protected async validateOptions(opts: FlagsDef, sdk: BalenaSDK) {
// Validate option combinations
if (
(opts.fleet == null && (opts.arch == null || opts.deviceType == null)) ||
(opts.fleet != null && (opts.arch != null || opts.deviceType != null))
) {
const { ExpectedError } = await import('../../errors');
throw new ExpectedError(
'You must specify either a fleet (-f), or the device type (-d) and optionally the architecture (-A)',
);
}
// Validate project directory
const { validateProjectDirectory } = await import('../../utils/compose_ts');
const { dockerfilePath, registrySecrets } = await validateProjectDirectory(

View File

@ -64,11 +64,11 @@ export default class ConfigGenerateCmd extends Command {
description: 'a balenaOS version',
required: true,
}),
fleet: { ...cf.fleet, exclusive: ['device'] },
fleet: cf.fleet({ exclusive: ['device'] }),
dev: cf.dev,
secureBoot: cf.secureBoot,
device: {
...cf.device,
...cf.device(),
exclusive: [
'fleet',
'provisioning-key-name',
@ -83,6 +83,7 @@ export default class ConfigGenerateCmd extends Command {
deviceType: Flags.string({
description:
"device type slug (run 'balena device-type list' for possible values)",
dependsOn: ['fleet'],
}),
'generate-device-api-key': Flags.boolean({
description: 'generate a fresh device key for the device',
@ -240,9 +241,6 @@ export default class ConfigGenerateCmd extends Command {
$ balena help config generate
`;
protected readonly deviceTypeNotAllowedMessage =
'The --deviceType option can only be used alongside the --fleet option';
protected async validateOptions(
options: Interfaces.InferredFlags<typeof ConfigGenerateCmd.flags>,
) {
@ -252,9 +250,6 @@ export default class ConfigGenerateCmd extends Command {
throw new ExpectedError(this.missingDeviceOrAppMessage);
}
if (!options.fleet && options.deviceType) {
throw new ExpectedError(this.deviceTypeNotAllowedMessage);
}
const { normalizeOsVersion } = await import('../../utils/normalization');
options.version = normalizeOsVersion(options.version);
const { validateDevOptionAndWarn } = await import('../../utils/config');

View File

@ -47,13 +47,14 @@ export default class DeviceDeactivateCmd extends Command {
public static authenticated = true;
public async run() {
const { args: params, flags: options } =
await this.parse(DeviceDeactivateCmd);
const {
args: { uuid },
flags: options,
} = await this.parse(DeviceDeactivateCmd);
const balena = getBalenaSdk();
const patterns = await import('../../utils/patterns');
const uuid = params.uuid;
const deactivationWarning = `
Warning! Deactivating a device will charge a fee equivalent to the
normal monthly cost for the device (e.g. $1 for an essentials device);

View File

@ -73,7 +73,7 @@ export default class DeviceInitCmd extends Command {
];
public static flags = {
fleet: cf.fleet,
fleet: cf.fleet(),
yes: cf.yes,
advanced: Flags.boolean({
char: 'v',

View File

@ -57,7 +57,7 @@ export default class DeviceListCmd extends Command {
];
public static flags = {
fleet: cf.fleet,
fleet: cf.fleet(),
json: cf.json,
};

View File

@ -54,7 +54,7 @@ export default class DeviceMoveCmd extends Command {
};
public static flags = {
fleet: cf.fleet,
fleet: cf.fleet(),
};
public static authenticated = true;

View File

@ -15,8 +15,7 @@
* limitations under the License.
*/
import { Flags, Args, Command } from '@oclif/core';
import { ExpectedError } from '../../errors';
import { Args, Command } from '@oclif/core';
import * as cf from '../../utils/common-flags';
import { getBalenaSdk, stripIndent } from '../../utils/lazy';
@ -41,35 +40,24 @@ export default class DeviceNoteCmd extends Command {
public static args = {
note: Args.string({
description: 'note content',
required: true,
}),
};
public static flags = {
device: { exclusive: ['dev'], ...cf.device },
dev: Flags.string({
exclusive: ['device'],
hidden: true,
}),
device: cf.device({ required: true }),
};
public static authenticated = true;
public async run() {
const { args: params, flags: options } = await this.parse(DeviceNoteCmd);
if (params.note?.length === 0) {
throw new ExpectedError('Missing note content');
}
options.device = options.device || options.dev;
delete options.dev;
if (options.device == null || options.device.length === 0) {
throw new ExpectedError('Missing device UUID (--device)');
}
const {
args: params,
flags: { device },
} = await this.parse(DeviceNoteCmd);
const balena = getBalenaSdk();
return balena.models.device.setNote(options.device, params.note ?? '');
return balena.models.device.setNote(device!, params.note!);
}
}

View File

@ -16,11 +16,7 @@
*/
import { Flags, Args, Command } from '@oclif/core';
import {
NoPortsDefinedError,
InvalidPortMappingError,
ExpectedError,
} from '../../errors';
import { InvalidPortMappingError, ExpectedError } from '../../errors';
import { getBalenaSdk, stripIndent } from '../../utils/lazy';
import { lowercaseIfSlug } from '../../utils/normalization';
@ -85,6 +81,7 @@ export default class DeviceTunnelCmd extends Command {
'port mapping in the format <remotePort>[:[localIP:]localPort]',
char: 'p',
multiple: true,
required: true,
}),
};
@ -117,10 +114,6 @@ export default class DeviceTunnelCmd extends Command {
}
};
if (options.port === undefined) {
throw new NoPortsDefinedError();
}
// Ascertain device uuid
const { getOnlineTargetDeviceUuid } = await import('../../utils/patterns');
const uuid = await getOnlineTargetDeviceUuid(sdk, params.deviceOrFleet);

View File

@ -97,14 +97,14 @@ export default class EnvListCmd extends Command {
];
public static flags = {
fleet: { ...cf.fleet, exclusive: ['device'] },
fleet: { ...cf.fleet(), exclusive: ['device'] },
config: Flags.boolean({
default: false,
char: 'c',
description: 'show configuration variables only',
exclusive: ['service'],
}),
device: { ...cf.device, exclusive: ['fleet'] },
device: { ...cf.device(), exclusive: ['fleet'] },
json: cf.json,
service: { ...cf.service, exclusive: ['config'] },
};

View File

@ -95,8 +95,8 @@ export default class EnvSetCmd extends Command {
public static strict = false;
public static flags = {
fleet: { ...cf.fleet, exclusive: ['device'] },
device: { ...cf.device, exclusive: ['fleet'] },
fleet: { ...cf.fleet(), exclusive: ['device'] },
device: { ...cf.device(), exclusive: ['fleet'] },
quiet: cf.quiet,
service: cf.service,
};

View File

@ -60,7 +60,7 @@ export default class JoinCmd extends Command {
};
public static flags = {
fleet: cf.fleet,
fleet: cf.fleet(),
pollInterval: Flags.integer({
description: 'the interval in minutes to check for updates',
char: 'i',

View File

@ -97,7 +97,7 @@ export default class OsConfigureCmd extends Command {
description:
'ask advanced configuration questions (when in interactive mode)',
}),
fleet: { ...cf.fleet, exclusive: ['device'] },
fleet: { ...cf.fleet(), exclusive: ['device'] },
config: Flags.string({
description:
'path to a pre-generated config.json file to be injected in the OS image',
@ -120,7 +120,7 @@ export default class OsConfigureCmd extends Command {
dev: cf.dev,
secureBoot: cf.secureBoot,
device: {
...cf.device,
...cf.device(),
exclusive: [
'fleet',
'provisioning-key-name',

View File

@ -79,7 +79,7 @@ export default class PreloadCmd extends Command {
};
public static flags = {
fleet: cf.fleet,
fleet: cf.fleet(),
commit: Flags.string({
description: `\
The commit hash of the release to preload. Use "current" to specify the current

View File

@ -57,7 +57,7 @@ export default class SupportCmd extends Command {
char: 'd',
}),
fleet: {
...cf.fleet,
...cf.fleet(),
description:
'comma-separated list (no spaces) of fleet names or slugs (preferred)',
},

View File

@ -43,11 +43,11 @@ export default class TagListCmd extends Command {
public static flags = {
fleet: {
...cf.fleet,
...cf.fleet(),
exclusive: ['device', 'release'],
},
device: {
...cf.device,
...cf.device(),
exclusive: ['fleet', 'release'],
},
release: {

View File

@ -46,11 +46,11 @@ export default class TagRmCmd extends Command {
public static flags = {
fleet: {
...cf.fleet,
...cf.fleet(),
exclusive: ['device', 'release'],
},
device: {
...cf.device,
...cf.device(),
exclusive: ['fleet', 'release'],
},
release: {

View File

@ -60,11 +60,11 @@ export default class TagSetCmd extends Command {
public static flags = {
fleet: {
...cf.fleet,
...cf.fleet(),
exclusive: ['device', 'release'],
},
device: {
...cf.device,
...cf.device(),
exclusive: ['fleet', 'release'],
},
release: {

View File

@ -39,12 +39,6 @@ export class InvalidPortMappingError extends ExpectedError {
}
}
export class NoPortsDefinedError extends ExpectedError {
constructor() {
super('No ports have been provided.');
}
}
export class SIGINTError extends ExpectedError {}
/**

View File

@ -19,16 +19,22 @@ import { Flags } from '@oclif/core';
import { stripIndent } from './lazy';
import { lowercaseIfSlug } from './normalization';
export const fleet = Flags.string({
char: 'f',
description: 'fleet name or slug (preferred)',
parse: lowercaseIfSlug,
});
// eslint-disable-next-line id-denylist
export const fleet = (extraOpts?: Partial<typeof Flags.string>) =>
Flags.string({
char: 'f',
description: 'fleet name or slug (preferred)',
parse: lowercaseIfSlug,
...extraOpts,
});
export const device = Flags.string({
char: 'd',
description: 'device UUID',
});
// eslint-disable-next-line id-denylist
export const device = (extraOpts?: Partial<typeof Flags.string>) =>
Flags.string({
char: 'd',
description: 'device UUID',
...extraOpts,
});
export const quiet = Flags.boolean({
char: 'q',