Merge pull request #2431 from balena-io/os-configure-dev-flag

os.getConfig MVP (os configure, config generate, local configure)
This commit is contained in:
bulldozer-balena[bot] 2021-12-29 14:45:46 +00:00 committed by GitHub
commit 5cf84d3f1d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 148 additions and 33 deletions

View File

@ -2087,8 +2087,8 @@ or 'menu-esr' (interactive menu, ESR versions)
## os build-config <image> <device-type>
Interactively generate an OS config once, so that the generated config
file can be used in `balena os configure`, skipping the interactive part.
Interactively generate a configuration file that can then be used as
non-interactive input by the 'balena os configure' command.
Examples:
@ -2126,10 +2126,21 @@ following sources, in precedence order:
2. A given `config.json` file specified with the `--config` option.
3. User input through interactive prompts (text menus).
The --device-type option may be used to override the fleet's default device
type, in case of a fleet with mixed device types.
The --device-type option is used to override the fleet's default device type,
in case of a fleet with mixed device types.
The --system-connection (-c) option can be used to inject NetworkManager connection
The '--dev' option is used to configure balenaOS to operate in development mode,
allowing anauthenticated root ssh access and exposing network ports such as
balenaEngine's 2375 (unencrypted). This option causes `"developmentMode": true`
to be inserted in the 'config.json' file in the image's boot partion. Development
mode (as a configurable option) is applicable to balenaOS releases from early
2022. Older releases have separate development and production balenaOS images
that cannot be reconfigured through 'config.json' or the '--dev' option. Do not
confuse the balenaOS "development mode" with a device's "local mode", the latter
being a supervisor feature that allows the "balena push" command to push a user's
application directly to a device in the local network.
The --system-connection (-c) option is used to inject NetworkManager connection
profiles for additional network interfaces, such as cellular/GSM or additional
WiFi or ethernet connections. This option may be passed multiple times in case there
are multiple files to inject. See connection profile examples and reference at:
@ -2197,6 +2208,10 @@ WiFi key (password) (non-interactive configuration)
WiFi SSID (network name) (non-interactive configuration)
#### --dev
Configure balenaOS to operate in development mode
#### -d, --device DEVICE
device UUID
@ -2264,6 +2279,17 @@ Generate a config.json file for a device or fleet.
The target balenaOS version must be specified with the --version option.
The '--dev' option is used to configure balenaOS to operate in development mode,
allowing anauthenticated root ssh access and exposing network ports such as
balenaEngine's 2375 (unencrypted). This option causes `"developmentMode": true`
to be inserted in the 'config.json' file in the image's boot partion. Development
mode (as a configurable option) is applicable to balenaOS releases from early
2022. Older releases have separate development and production balenaOS images
that cannot be reconfigured through 'config.json' or the '--dev' option. Do not
confuse the balenaOS "development mode" with a device's "local mode", the latter
being a supervisor feature that allows the "balena push" command to push a user's
application directly to a device in the local network.
To configure an image for a fleet of mixed device types, use the --fleet option
alongside the --deviceType option to specify the target device type.
@ -2288,11 +2314,10 @@ Examples:
$ balena config generate --device 7cf02a6 --version 2.12.7 --generate-device-api-key
$ balena config generate --device 7cf02a6 --version 2.12.7 --deviceApiKey <existingDeviceKey>
$ balena config generate --device 7cf02a6 --version 2.12.7 --output config.json
$ balena config generate --fleet MyFleet --version 2.12.7
$ balena config generate --fleet myorg/myfleet --version 2.12.7
$ balena config generate --fleet MyFleet --version 2.12.7 --deviceType fincm3
$ balena config generate --fleet MyFleet --version 2.12.7 --output config.json
$ balena config generate --fleet MyFleet --version 2.12.7 --network wifi --wifiSsid mySsid --wifiKey abcdefgh --appUpdatePollInterval 15
$ balena config generate --fleet myorg/fleet --version 2.12.7 --dev
$ balena config generate --fleet myorg/fleet --version 2.12.7 --deviceType fincm3
$ balena config generate --fleet myorg/fleet --version 2.12.7 --output config.json
$ balena config generate --fleet myorg/fleet --version 2.12.7 --network wifi --wifiSsid mySsid --wifiKey abcdefgh --appUpdatePollInterval 15
### Options
@ -2304,6 +2329,10 @@ a balenaOS version
fleet name, slug (preferred), or numeric ID (deprecated)
#### --dev
Configure balenaOS to operate in development mode
#### -d, --device DEVICE
device UUID

View File

@ -19,12 +19,13 @@ import { flags } from '@oclif/command';
import Command from '../../command';
import * as cf from '../../utils/common-flags';
import { getBalenaSdk, getCliForm, stripIndent } from '../../utils/lazy';
import { applicationIdInfo } from '../../utils/messages';
import { applicationIdInfo, devModeInfo } from '../../utils/messages';
import type { PineDeferred } from 'balena-sdk';
interface FlagsDef {
version: string; // OS version
fleet?: string;
dev?: boolean; // balenaOS development variant
device?: string;
deviceApiKey?: string;
deviceType?: string;
@ -47,6 +48,8 @@ export default class ConfigGenerateCmd extends Command {
The target balenaOS version must be specified with the --version option.
${devModeInfo.split('\n').join('\n\t\t')}
To configure an image for a fleet of mixed device types, use the --fleet option
alongside the --deviceType option to specify the target device type.
@ -61,11 +64,10 @@ export default class ConfigGenerateCmd extends Command {
'$ balena config generate --device 7cf02a6 --version 2.12.7 --generate-device-api-key',
'$ balena config generate --device 7cf02a6 --version 2.12.7 --deviceApiKey <existingDeviceKey>',
'$ balena config generate --device 7cf02a6 --version 2.12.7 --output config.json',
'$ balena config generate --fleet MyFleet --version 2.12.7',
'$ balena config generate --fleet myorg/myfleet --version 2.12.7',
'$ balena config generate --fleet MyFleet --version 2.12.7 --deviceType fincm3',
'$ balena config generate --fleet MyFleet --version 2.12.7 --output config.json',
'$ balena config generate --fleet MyFleet --version 2.12.7 --network wifi --wifiSsid mySsid --wifiKey abcdefgh --appUpdatePollInterval 15',
'$ balena config generate --fleet myorg/fleet --version 2.12.7 --dev',
'$ balena config generate --fleet myorg/fleet --version 2.12.7 --deviceType fincm3',
'$ balena config generate --fleet myorg/fleet --version 2.12.7 --output config.json',
'$ balena config generate --fleet myorg/fleet --version 2.12.7 --network wifi --wifiSsid mySsid --wifiKey abcdefgh --appUpdatePollInterval 15',
];
public static usage = 'config generate';
@ -76,6 +78,7 @@ export default class ConfigGenerateCmd extends Command {
required: true,
}),
fleet: { ...cf.fleet, exclusive: ['device'] },
dev: cf.dev,
device: {
...cf.device,
exclusive: ['fleet', 'provisioning-key-name'],
@ -191,6 +194,7 @@ export default class ConfigGenerateCmd extends Command {
override: { ...options, app: options.fleet, application: options.fleet },
});
answers.version = options.version;
answers.developmentMode = options.dev;
answers.provisioningKeyName = options['provisioning-key-name'];
// Generate config
@ -241,5 +245,7 @@ export default class ConfigGenerateCmd extends Command {
if (!options.fleet && options.deviceType) {
throw new ExpectedError(this.deviceTypeNotAllowedMessage);
}
const { validateDevOptionAndWarn } = await import('../../utils/config');
await validateDevOptionAndWarn(options.dev, options.version);
}
}

View File

@ -113,6 +113,12 @@ export default class LocalConfigureCmd extends Command {
},
domain: [['config_json', 'hostname']],
},
{
template: {
developmentMode: '{{developmentMode}}',
},
domain: [['config_json', 'developmentMode']],
},
{
template: {
wifi: {
@ -163,6 +169,13 @@ export default class LocalConfigureCmd extends Command {
name: 'networkKey',
default: data.networkKey,
},
{
message:
'Enable development mode? (Open ports and root access - Not for production!)',
type: 'confirm',
name: 'developmentMode',
default: false,
},
{
message: 'Do you want to set advanced settings?',
type: 'confirm',

View File

@ -35,10 +35,10 @@ interface ArgsDef {
export default class OsBuildConfigCmd extends Command {
public static description = stripIndent`
Build an OS config and save it to a JSON file.
Prepare a configuration file for use by the 'os configure' command.
Interactively generate an OS config once, so that the generated config
file can be used in \`balena os configure\`, skipping the interactive part.
Interactively generate a configuration file that can then be used as
non-interactive input by the 'balena os configure' command.
`;
public static examples = [

View File

@ -23,7 +23,7 @@ import Command from '../../command';
import { ExpectedError } from '../../errors';
import * as cf from '../../utils/common-flags';
import { getBalenaSdk, stripIndent, getCliForm } from '../../utils/lazy';
import { applicationIdInfo } from '../../utils/messages';
import { applicationIdInfo, devModeInfo } from '../../utils/messages';
const CONNECTIONS_FOLDER = '/system-connections';
@ -35,6 +35,7 @@ interface FlagsDef {
'config-network'?: string;
'config-wifi-key'?: string;
'config-wifi-ssid'?: string;
dev?: boolean; // balenaOS development variant
device?: string; // device UUID
'device-type'?: string;
help?: void;
@ -50,6 +51,7 @@ interface ArgsDef {
interface Answers {
appUpdatePollInterval: number; // in minutes
developmentMode?: boolean; // balenaOS development variant
deviceType: string; // e.g. "raspberrypi3"
network: 'ethernet' | 'wifi';
version: string; // e.g. "2.32.0+rev1"
@ -71,10 +73,12 @@ export default class OsConfigureCmd extends Command {
2. A given \`config.json\` file specified with the \`--config\` option.
3. User input through interactive prompts (text menus).
The --device-type option may be used to override the fleet's default device
type, in case of a fleet with mixed device types.
The --device-type option is used to override the fleet's default device type,
in case of a fleet with mixed device types.
The --system-connection (-c) option can be used to inject NetworkManager connection
${devModeInfo.split('\n').join('\n\t\t')}
The --system-connection (-c) option is used to inject NetworkManager connection
profiles for additional network interfaces, such as cellular/GSM or additional
WiFi or ethernet connections. This option may be passed multiple times in case there
are multiple files to inject. See connection profile examples and reference at:
@ -133,6 +137,7 @@ export default class OsConfigureCmd extends Command {
'config-wifi-ssid': flags.string({
description: 'WiFi SSID (network name) (non-interactive configuration)',
}),
dev: cf.dev,
device: { ...cf.device, exclusive: ['fleet', 'provisioning-key-name'] },
'device-type': flags.string({
description:
@ -212,6 +217,13 @@ export default class OsConfigureCmd extends Command {
configJson = JSON.parse(rawConfig);
}
const osVersion =
options.version ||
(await getOsVersionFromImage(params.image, deviceTypeManifest, devInit));
const { validateDevOptionAndWarn } = await import('../../utils/config');
await validateDevOptionAndWarn(options.dev, osVersion);
const answers: Answers = await askQuestionsForDeviceType(
deviceTypeManifest,
options,
@ -220,10 +232,8 @@ export default class OsConfigureCmd extends Command {
if (options.fleet) {
answers.deviceType = deviceTypeSlug;
}
answers.version =
options.version ||
(await getOsVersionFromImage(params.image, deviceTypeManifest, devInit));
answers.version = osVersion;
answers.developmentMode = options.dev;
answers.provisioningKeyName = options['provisioning-key-name'];
if (_.isEmpty(configJson)) {

View File

@ -70,6 +70,11 @@ export const force: IBooleanFlag<boolean> = flags.boolean({
default: false,
});
export const dev: IBooleanFlag<boolean> = flags.boolean({
description: 'Configure balenaOS to operate in development mode',
default: false,
});
export const drive = flags.string({
char: 'd',
description: stripIndent`

View File

@ -15,7 +15,7 @@ limitations under the License.
*/
import type * as BalenaSdk from 'balena-sdk';
import * as semver from 'balena-semver';
import { getBalenaSdk } from './lazy';
import { getBalenaSdk, stripIndent } from './lazy';
export interface ImgConfig {
applicationName: string;
@ -134,3 +134,34 @@ export function generateDeviceConfig(
return config;
});
}
/**
* Chech whether the `--dev` option of commands related to OS configuration
* such as `os configure` and `config generate` is compatible with a given
* balenaOS version, and print a warning regarding the consequences of using
* that option.
*/
export async function validateDevOptionAndWarn(
dev?: boolean,
version?: string,
logger?: import('./logger'),
) {
if (!dev) {
return;
}
if (version && /\bprod\b/.test(version)) {
const { ExpectedError } = await import('../errors');
throw new ExpectedError(
`Error: The '--dev' option conflicts with production balenaOS version '${version}'`,
);
}
if (!logger) {
const Logger = await import('./logger');
logger = Logger.getLogger();
}
logger.logInfo(stripIndent`
The '--dev' option is being used to configure a balenaOS image in development mode.
Please note that development mode allows unauthenticated, passwordless root ssh access
and exposes network ports such as 2375 that allows unencrypted access to balenaEngine.
Therefore, development mode should only be used in private, trusted local networks.`);
}

View File

@ -159,6 +159,18 @@ created public/open fleet, or with fleets from other balena accounts that you
may be invited to join under any role. For this reason, fleet names are
especially discouraged in scripts (e.g. CI environments).`;
export const devModeInfo = `\
The '--dev' option is used to configure balenaOS to operate in development mode,
allowing anauthenticated root ssh access and exposing network ports such as
balenaEngine's 2375 (unencrypted). This option causes \`"developmentMode": true\`
to be inserted in the 'config.json' file in the image's boot partion. Development
mode (as a configurable option) is applicable to balenaOS releases from early
2022. Older releases have separate development and production balenaOS images
that cannot be reconfigured through 'config.json' or the '--dev' option. Do not
confuse the balenaOS "development mode" with a device's "local mode", the latter
being a supervisor feature that allows the "balena push" command to push a user's
application directly to a device in the local network.`;
export const jsonInfo = `\
The --json option is recommended when scripting the output of this command,
because field names are less likely to change in JSON format and because it

17
npm-shrinkwrap.json generated
View File

@ -4140,9 +4140,9 @@
}
},
"balena-sdk": {
"version": "16.8.1",
"resolved": "https://registry.npmjs.org/balena-sdk/-/balena-sdk-16.8.1.tgz",
"integrity": "sha512-fSYo/aOGVRj0PhIRla8GRuLhyIecvri8kFFbDu0faUgDDUHfidyfIIUzuTggOc7XKr20WazvjfI4M2uVAqMKww==",
"version": "16.9.0",
"resolved": "https://registry.npmjs.org/balena-sdk/-/balena-sdk-16.9.0.tgz",
"integrity": "sha512-iuIiXAEkDXoEtUJzFG5RO+rvudqMsoBppdgQLOrnIdWc14T+mvwWUFKAHHAkvxnA0GLmbxqGp7qo3uVMgS2Ojw==",
"requires": {
"@balena/es-version": "^1.0.0",
"@types/json-schema": "^7.0.9",
@ -4152,7 +4152,7 @@
"abortcontroller-polyfill": "^1.7.1",
"balena-auth": "^4.1.0",
"balena-errors": "^4.7.1",
"balena-hup-action-utils": "~4.0.2",
"balena-hup-action-utils": "~4.1.0",
"balena-pine": "^12.4.0",
"balena-register-device": "^7.1.0",
"balena-request": "^11.5.0",
@ -4165,6 +4165,15 @@
"tslib": "^2.1.0"
},
"dependencies": {
"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==",
"requires": {
"balena-semver": "^2.0.0",
"tslib": "^2.0.0"
}
},
"moment": {
"version": "2.29.1",
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz",

View File

@ -208,7 +208,7 @@
"balena-image-manager": "^7.1.1",
"balena-preload": "^11.0.0",
"balena-release": "^3.2.0",
"balena-sdk": "^16.8.1",
"balena-sdk": "^16.9.0",
"balena-semver": "^2.3.0",
"balena-settings-client": "^4.0.7",
"balena-settings-storage": "^7.0.0",