Skip to content

Commit af6355d

Browse files
authored
Merge pull request #252 from balena-io-modules/secure-boot-backup
Secure boot backup
2 parents 44fe728 + e4e56b3 commit af6355d

5 files changed

Lines changed: 649 additions & 344 deletions

File tree

package-lock.json

Lines changed: 31 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
"ajv-formats": "^3.0.1",
3434
"ajv-keywords": "^5.1.0",
3535
"analytics-client": "^3.1.2",
36+
"balena-semver": "^3.0.10",
3637
"color": "^5.0.0",
3738
"color-hash": "^2.0.2",
3839
"date-fns": "^4.1.0",

src/components/DownloadImageDialog/ApplicationInstructions.tsx

Lines changed: 72 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
import has from 'lodash/has';
21
import { interpolateMustache } from './utils';
32
import { Box, List, Tab, Tabs, Typography } from '@mui/material';
43
import { memo, useEffect, useState } from 'react';
54
import { MUILinkWithTracking } from '../MUILinkWithTracking';
65
import type { DeviceType, OsSpecificContractInstructions } from './models';
76
import { OrderedListItem } from '../OrderedListItem';
87
import { Markdown } from '../Markdown';
8+
import { Chip } from '../Chip';
9+
import { token } from '../../utils/token';
910

1011
export type OsOptions = ReturnType<typeof getUserOs>;
1112

@@ -26,12 +27,16 @@ export const getUserOs = () => {
2627
return 'Unknown';
2728
};
2829

30+
const SECURE_BOOT_INSTRUCTION_TO_REPLACE_START = 'Press the F10 key while BIOS';
31+
2932
export const ApplicationInstructions = memo(function ApplicationInstructions({
3033
deviceType,
3134
templateData,
35+
secureboot,
3236
}: {
3337
deviceType: DeviceType;
3438
templateData: { dockerImage: string };
39+
secureboot: boolean;
3540
}) {
3641
const [currentOs, setCurrentOs] = useState<OsOptions>(getUserOs());
3742

@@ -106,7 +111,10 @@ export const ApplicationInstructions = memo(function ApplicationInstructions({
106111
</Box>
107112
)}
108113

109-
<InstructionsList instructions={finalInstructions} />
114+
<InstructionsList
115+
instructions={finalInstructions}
116+
secureboot={secureboot}
117+
/>
110118

111119
<Box mt={2}>
112120
<Typography>
@@ -124,26 +132,21 @@ export const ApplicationInstructions = memo(function ApplicationInstructions({
124132
});
125133

126134
interface InstructionsItemProps {
127-
node: any;
135+
instruction: string;
128136
index: number;
137+
secureboot: boolean;
129138
}
130139

131140
interface InstructionsListProps {
132-
instructions: any[];
141+
instructions: string[];
142+
secureboot: boolean;
133143
}
134144

135-
const InstructionsItem = ({ node, index }: InstructionsItemProps) => {
136-
const hasChildren = has(node, 'children');
137-
let text = null;
138-
139-
if (typeof node === 'string') {
140-
text = node;
141-
}
142-
143-
if (node?.text) {
144-
text = node.text;
145-
}
146-
145+
const InstructionsItem = ({
146+
instruction,
147+
index,
148+
secureboot,
149+
}: InstructionsItemProps) => {
147150
return (
148151
<OrderedListItem index={index + 1} sx={{ maxWidth: '100%' }}>
149152
<Markdown
@@ -166,29 +169,69 @@ const InstructionsItem = ({ node, index }: InstructionsItemProps) => {
166169
return <p />;
167170
},
168171
p: ({ children }) => (
169-
<p style={{ marginTop: 0, marginBottom: 0 }}>{children}</p>
172+
<p style={{ marginTop: 0, marginBottom: 0 }}>
173+
{/* TODO: Find a way to do this via contracts */}
174+
{secureboot &&
175+
instruction.includes(SECURE_BOOT_INSTRUCTION_TO_REPLACE_START) ? (
176+
<>
177+
{
178+
instruction.split(
179+
SECURE_BOOT_INSTRUCTION_TO_REPLACE_START,
180+
)[0]
181+
}
182+
<Box
183+
mt={2}
184+
borderLeft={1}
185+
borderColor={token('color.border.subtle')}
186+
pl={2}
187+
>
188+
<Chip
189+
sx={{ marginRight: 1 }}
190+
label="Secure Boot"
191+
color="purple"
192+
/>
193+
The device needs to be configured in secure boot setup mode.
194+
This depends on the UEFI/BIOS implementation, but in
195+
general, this involves resetting the UEFI settings to
196+
default configuration, configuring the device to boot in
197+
UEFI mode, setting the first boot option to the USB key and
198+
disabling the restoration of factory keys. Save and Exit the
199+
UEFI/BIOS menu and the device should automatically reboot
200+
and begin the provisioning process.{' '}
201+
<MUILinkWithTracking href="https://docs.balena.io/reference/OS/secure-boot-and-full-disk-encryption/generic-x86-64-gpt/#provision-the-device">
202+
Read more on UEFI settings for secure boot and full disk
203+
encryption.
204+
</MUILinkWithTracking>
205+
</Box>
206+
</>
207+
) : (
208+
children
209+
)}
210+
</p>
170211
),
171212
}}
172213
>
173-
{text}
214+
{instruction}
174215
</Markdown>
175-
176-
{hasChildren && (
177-
<List>
178-
{(node.children as any[]).map((item, i) => {
179-
return <InstructionsItem key={i} node={item} index={i} />;
180-
})}
181-
</List>
182-
)}
183216
</OrderedListItem>
184217
);
185218
};
186219

187-
const InstructionsList = ({ instructions }: InstructionsListProps) => {
220+
const InstructionsList = ({
221+
instructions,
222+
secureboot,
223+
}: InstructionsListProps) => {
188224
return (
189225
<List>
190-
{instructions.map((item, i) => {
191-
return <InstructionsItem key={`${item}_${i}`} node={item} index={i} />;
226+
{instructions.map((instruction, i) => {
227+
return (
228+
<InstructionsItem
229+
key={`${instruction}_${i}`}
230+
instruction={instruction}
231+
index={i}
232+
secureboot={secureboot}
233+
/>
234+
);
192235
})}
193236
</List>
194237
);

0 commit comments

Comments
 (0)