Convert device os-update command to oclif

Change-type: patch
Signed-off-by: Scott Lowe <scott@balena.io>
This commit is contained in:
Scott Lowe 2020-06-18 15:36:46 +02:00
parent 4995e9b642
commit ebb0ec5287
8 changed files with 182 additions and 151 deletions

View File

@ -61,6 +61,7 @@ const capitanoDoc = {
'build/actions-oclif/device/shutdown.js',
'build/actions-oclif/devices/index.js',
'build/actions-oclif/devices/supported.js',
'build/actions-oclif/device/os-update.js',
'build/actions-oclif/device/public-url.js',
],
},

View File

@ -168,7 +168,6 @@ Users are encouraged to regularly update the balena CLI to the latest version.
- Device
- [device init](#device-init)
- [device os-update &#60;uuid&#62;](#device-os-update-uuid)
- [device identify &#60;uuid&#62;](#device-identify-uuid)
- [device &#60;uuid&#62;](#device-uuid)
- [device move &#60;uuid&#62;](#device-move-uuid)
@ -179,6 +178,7 @@ Users are encouraged to regularly update the balena CLI to the latest version.
- [device shutdown &#60;uuid&#62;](#device-shutdown-uuid)
- [devices](#devices)
- [devices supported](#devices-supported)
- [device os-update &#60;uuid&#62;](#device-os-update-uuid)
- [device public-url &#60;uuid&#62;](#device-public-url-uuid)
- Environment Variables
@ -496,30 +496,6 @@ the drive to write the image to, like `/dev/sdb` or `/dev/mmcblk0`. Careful with
path to the config JSON file, see `balena os build-config`
## device os-update &#60;uuid&#62;
Use this command to trigger a Host OS update for a device.
Notice this command will ask for confirmation interactively.
You can avoid this by passing the `--yes` boolean option.
Requires balenaCloud; will not work with openBalena or standalone balenaOS.
Examples:
$ balena device os-update 23c73a1
$ balena device os-update 23c73a1 --version 2.31.0+rev1.prod
### Options
#### --version &#60;version&#62;
a balenaOS version
#### --yes, -y
confirm non interactively
## device identify &#60;uuid&#62;
Identify a device by making the ACT LED blink (Raspberry Pi).
@ -746,6 +722,36 @@ produce JSON output instead of tabular output
add extra columns in the tabular output (ALIASES, ARCH, STATE)
## device os-update &#60;uuid&#62;
Start a Host OS update for a device.
Note this command will ask for confirmation interactively.
This can be avoided by passing the `--yes` option.
Requires balenaCloud; will not work with openBalena or standalone balenaOS.
Examples:
$ balena device os-update 23c73a1
$ balena device os-update 23c73a1 --version 2.31.0+rev1.prod
### Arguments
#### UUID
the uuid of the device to update
### Options
#### --version VERSION
a balenaOS version
#### -y, --yes
answer "yes" to all questions (non interactive use)
## device public-url &#60;uuid&#62;
This command will output the current public URL for the

View File

@ -0,0 +1,148 @@
/**
* @license
* Copyright 2016-2020 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.
*/
import { flags } from '@oclif/command';
import { IArg } from '@oclif/parser/lib/args';
import { stripIndent } from 'common-tags';
import Command from '../../command';
import * as cf from '../../utils/common-flags';
import { getBalenaSdk } from '../../utils/lazy';
import { tryAsInteger } from '../../utils/validation';
import { Device } from 'balena-sdk';
import { ExpectedError } from '../../errors';
interface FlagsDef {
version?: string;
yes: boolean;
help: void;
}
interface ArgsDef {
uuid: string;
}
export default class DeviceOsUpdateCmd extends Command {
public static description = stripIndent`
Start a Host OS update for a device.
Start a Host OS update for a device.
Note this command will ask for confirmation interactively.
This can be avoided by passing the \`--yes\` option.
Requires balenaCloud; will not work with openBalena or standalone balenaOS.
`;
public static examples = [
'$ balena device os-update 23c73a1',
'$ balena device os-update 23c73a1 --version 2.31.0+rev1.prod',
];
public static args: Array<IArg<any>> = [
{
name: 'uuid',
description: 'the uuid of the device to update',
parse: (dev) => tryAsInteger(dev),
required: true,
},
];
public static usage = 'device os-update <uuid>';
public static flags: flags.Input<FlagsDef> = {
version: flags.string({
description: 'a balenaOS version',
}),
yes: cf.yes,
help: cf.help,
};
public static authenticated = true;
public async run() {
const { args: params, flags: options } = this.parse<FlagsDef, ArgsDef>(
DeviceOsUpdateCmd,
);
const _ = await import('lodash');
const sdk = getBalenaSdk();
const patterns = await import('../../utils/patterns');
const form = await import('resin-cli-form');
// Get device info
const {
uuid,
device_type,
os_version,
os_variant,
} = await sdk.models.device.get(params.uuid, {
$select: ['uuid', 'device_type', 'os_version', 'os_variant'],
});
// Get current device OS version
const currentOsVersion = sdk.models.device.getOsVersion({
os_version,
os_variant,
} as Device);
if (!currentOsVersion) {
throw new ExpectedError(
'The current os version of the device is not available',
);
}
// Get supported OS update versions
const hupVersionInfo = await sdk.models.os.getSupportedOsUpdateVersions(
device_type,
currentOsVersion,
);
if (hupVersionInfo.versions.length === 0) {
throw new ExpectedError(
'There are no available Host OS update targets for this device',
);
}
// Get target OS version
let targetOsVersion = options.version;
if (targetOsVersion != null) {
if (!_.includes(hupVersionInfo.versions, targetOsVersion)) {
throw new ExpectedError(
`The provided version ${targetOsVersion} is not in the Host OS update targets for this device`,
);
}
} else {
targetOsVersion = await form.ask({
message: 'Target OS version',
type: 'list',
choices: hupVersionInfo.versions.map((version) => ({
name:
hupVersionInfo.recommended === version
? `${version} (recommended)`
: version,
value: version,
})),
});
}
// Confirm and start update
await patterns.confirm(
options.yes || false,
'Host OS updates require a device restart when they complete. Are you sure you want to proceed?',
);
await sdk.models.device.startOsUpdate(uuid, targetOsVersion);
await patterns.awaitDeviceOsUpdate(uuid, targetOsVersion);
}
}

View File

@ -112,5 +112,3 @@ Examples:
});
},
};
export { osUpdate } from './device_ts';

View File

@ -1,122 +0,0 @@
/*
Copyright 2016-2020 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.
*/
import { Device } from 'balena-sdk';
import { CommandDefinition } from 'capitano';
import { stripIndent } from 'common-tags';
import { ExpectedError } from '../errors';
import { getBalenaSdk } from '../utils/lazy';
import { normalizeUuidProp } from '../utils/normalization';
import * as commandOptions from './command-options';
// tslint:disable-next-line:no-namespace
namespace OsUpdate {
export interface Args {
uuid: string;
}
export type Options = commandOptions.OptionalOsVersionOption &
commandOptions.YesOption;
}
export const osUpdate: CommandDefinition<OsUpdate.Args, OsUpdate.Options> = {
signature: 'device os-update <uuid>',
description: 'Start a Host OS update for a device',
help: stripIndent`
Use this command to trigger a Host OS update for a device.
Notice this command will ask for confirmation interactively.
You can avoid this by passing the \`--yes\` boolean option.
Requires balenaCloud; will not work with openBalena or standalone balenaOS.
Examples:
$ balena device os-update 23c73a1
$ balena device os-update 23c73a1 --version 2.31.0+rev1.prod
`,
options: [commandOptions.optionalOsVersion, commandOptions.yes],
permission: 'user',
async action(params, options) {
normalizeUuidProp(params);
const _ = await import('lodash');
const sdk = getBalenaSdk();
const patterns = await import('../utils/patterns');
const form = await import('resin-cli-form');
// Get device info
const {
uuid,
device_type,
os_version,
os_variant,
} = await sdk.models.device.get(params.uuid, {
$select: ['uuid', 'device_type', 'os_version', 'os_variant'],
});
// Get current device OS version
const currentOsVersion = sdk.models.device.getOsVersion({
os_version,
os_variant,
} as Device);
if (!currentOsVersion) {
throw new ExpectedError(
'The current os version of the device is not available',
);
}
// Get supported OS update versions
const hupVersionInfo = await sdk.models.os.getSupportedOsUpdateVersions(
device_type,
currentOsVersion,
);
if (hupVersionInfo.versions.length === 0) {
throw new ExpectedError(
'There are no available Host OS update targets for this device',
);
}
// Get target OS version
let targetOsVersion = options.version;
if (targetOsVersion != null) {
if (!_.includes(hupVersionInfo.versions, targetOsVersion)) {
throw new ExpectedError(
`The provided version ${targetOsVersion} is not in the Host OS update targets for this device`,
);
}
} else {
targetOsVersion = await form.ask({
message: 'Target OS version',
type: 'list',
choices: hupVersionInfo.versions.map((version) => ({
name:
hupVersionInfo.recommended === version
? `${version} (recommended)`
: version,
value: version,
})),
});
}
// Confirm and start update
await patterns.confirm(
options.yes || false,
'Host OS updates require a device restart when they complete. Are you sure you want to proceed?',
);
await sdk.models.device.startOsUpdate(uuid, targetOsVersion);
await patterns.awaitDeviceOsUpdate(uuid, targetOsVersion);
},
};

View File

@ -54,7 +54,6 @@ capitano.command(actions.auth.whoami);
// ---------- Device Module ----------
capitano.command(actions.device.init);
capitano.command(actions.device.osUpdate);
// ---------- OS Module ----------
capitano.command(actions.os.versions);

View File

@ -144,6 +144,7 @@ export const convertedCommands = [
'device',
'device:identify',
'device:move',
'device:os-update',
'device:public-url',
'device:reboot',
'device:register',

View File

@ -40,7 +40,7 @@ Additional commands:
device identify <uuid> identify a device
device init initialise a device with balenaOS
device move <uuid> move a device to another application
device os-update <uuid> Start a Host OS update for a device
device os-update <uuid> start a Host OS update for a device
device public-url <uuid> get or manage the public URL for a device
device reboot <uuid> restart a device
device register <application> register a device