Skip to content

Commit

Permalink
os initialize: Deprecate the --type parameter
Browse files Browse the repository at this point in the history
Change-type: patch
  • Loading branch information
thgreasi committed Jan 12, 2025
1 parent d9f21b4 commit 06133c7
Show file tree
Hide file tree
Showing 7 changed files with 68 additions and 45 deletions.
1 change: 1 addition & 0 deletions docs/balena-cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -3048,6 +3048,7 @@ because we need to access the raw devices directly.

Examples:

$ balena os initialize ../path/rpi.img
$ balena os initialize ../path/rpi.img --type raspberry-pi

### Arguments
Expand Down
5 changes: 1 addition & 4 deletions src/commands/internal/osinit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,6 @@ export default class OsinitCmd extends Command {
image: Args.string({
required: true,
}),
type: Args.string({
required: true,
}),
config: Args.string({
required: true,
}),
Expand All @@ -58,7 +55,7 @@ export default class OsinitCmd extends Command {
const { getManifest, osProgressHandler } = await import(
'../../utils/helpers'
);
const manifest = await getManifest(params.image, params.type);
const manifest = await getManifest(params.image);

const { initialize } = await import('balena-device-init');
const initializeEmitter = await initialize(params.image, manifest, config);
Expand Down
1 change: 1 addition & 0 deletions src/commands/os/configure.ts
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@ export default class OsConfigureCmd extends Command {

const deviceTypeManifest = await helpers.getManifest(
params.image,
// TODO: Drop this in the next major in favor of calling checkManifestMatchesDeviceType() directly
deviceTypeSlug,
);

Expand Down
14 changes: 7 additions & 7 deletions src/commands/os/initialize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export default class OsInitializeCmd extends Command {
`;

public static examples = [
'$ balena os initialize ../path/rpi.img',
'$ balena os initialize ../path/rpi.img --type raspberry-pi',
];

Expand All @@ -63,6 +64,11 @@ export default class OsInitializeCmd extends Command {
console.info(`Initializing device ${INIT_WARNING_MESSAGE}`);

const manifest = await getManifest(params.image, options.type);
// the "type" arg will be removed on the next major - warn user
if (options.type != null) {
const { deviceTypeArgDeprecation } = await import('../../utils/messages');
console.log(deviceTypeArgDeprecation('type'));
}

const answers = await getCliForm().run(manifest.initialization?.options, {
override: {
Expand All @@ -81,13 +87,7 @@ export default class OsInitializeCmd extends Command {
await safeUmount(answers.drive);
}

await sudo([
'internal',
'osinit',
params.image,
options.type,
JSON.stringify(answers),
]);
await sudo(['internal', 'osinit', params.image, JSON.stringify(answers)]);

if (answers.drive != null) {
const { safeUmount } = await import('../../utils/umount');
Expand Down
1 change: 0 additions & 1 deletion src/utils/common-flags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,6 @@ export const deviceType = Flags.string({
description:
'device type (Check available types with `balena device-type list`)',
char: 't',
required: true,
});

export const json = Flags.boolean({
Expand Down
85 changes: 52 additions & 33 deletions src/utils/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ 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
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,
Expand Down Expand Up @@ -103,48 +103,67 @@ export async function runCommand<T>(commandArgs: string[]): Promise<T> {
return run(commandArgs) as Promise<T>;
}

export async function checkManifestMatchesDeviceType(
manifest: BalenaSdk.DeviceTypeJson.DeviceType,
deviceType: string,
) {
if (
manifest.slug !== deviceType &&
manifest.slug !==
(await getBalenaSdk().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}`,
);
}
}

export async function getManifest(
image: string,
deviceType: string,
// TODO: Drop this parameter in the next major
fallbackDeviceType?: string,
): Promise<BalenaSdk.DeviceTypeJson.DeviceType> {
const init = await import('balena-device-init');
const sdk = getBalenaSdk();
const manifest = await init.getImageManifest(image);
if (manifest != null) {
const config = manifest.configuration?.config;
if (config?.partition != null) {
const { getBootPartition } = await import('balena-config-json');
// Find the device-type.json property that holds the boot partition number for
// this device type (config.partition or config.partition.primary) and overwrite it
// with the boot partition number that was found by inspecting the image.
// since it's deprecated & no longer updated for newer releases.
if (typeof config.partition === 'number') {
config.partition = await getBootPartition(image);
} else if (config.partition.primary != null) {
config.partition.primary = await getBootPartition(image);
}
// TODO: Add handling for when we no longer include a `config.partition` at all.
if (manifest == null) {
// TODO: Change this in the next major to throw when not being able to find the manifest
// on the provided image, after confirming that this works for all supported OS versions.
if (fallbackDeviceType != null) {
console.error(
`[warn] Error while finding a device-type.json on the provided image path. Attempting to fetch from the API.`,
);
const sdk = getBalenaSdk();
return await sdk.models.config.getDeviceTypeManifestBySlug(
fallbackDeviceType,
);
}
} else {
// TODO: Change this in the next major to throw, after confirming that this works for all supported OS versions.
console.error(
`[warn] Error while finding a device-type.json on the provided image path. Attempting to fetch from the API.`,
);
}
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}`,
`Could not find the manifest on the provided image path '${image}'. Please double check that this is a valid balenaOS image.`,
);
}
return (
manifest ??
(await sdk.models.config.getDeviceTypeManifestBySlug(deviceType))
);

const config = manifest.configuration?.config;
if (config?.partition != null) {
const { getBootPartition } = await import('balena-config-json');
// Find the device-type.json property that holds the boot partition number for
// this device type (config.partition or config.partition.primary) and overwrite it
// with the boot partition number that was found by inspecting the image.
// since it's deprecated & no longer updated for newer releases.
if (typeof config.partition === 'number') {
config.partition = await getBootPartition(image);
} else if (config.partition.primary != null) {
config.partition.primary = await getBootPartition(image);
}
// TODO: Add handling for when we no longer include a `config.partition` at all.
}
// TODO: Drop this in the next major along with the fallbackDeviceType argument
// and move the checkManifestMatchesDeviceType() to the caller side when still necessary.
if (fallbackDeviceType != null) {
await checkManifestMatchesDeviceType(manifest, fallbackDeviceType);
}
return manifest;
}

export const areDeviceTypesCompatible = async (
Expand Down
6 changes: 6 additions & 0 deletions src/utils/messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,12 @@ If you have a particular use for buildArg, which is not satisfied by build-time
secrets, please contact us via support or the forums: https://forums.balena.io/
\n`;

export const deviceTypeArgDeprecation = (paramName: string) => `\
WARNING: You have specified a '--${paramName}' option, which is now deprecated, and
may be removed in the future. The balena-cli will now try to auto-detect
the device type of the provided balenaOS image.
\n`;

export function getNodeEngineVersionWarn(
version: string,
validVersions: string,
Expand Down

0 comments on commit 06133c7

Please sign in to comment.