mirror of
https://github.com/balena-io/etcher.git
synced 2025-07-28 13:46:33 +00:00
Merge unsafe mode with new target selector
Change-type: patch Changelog-entry: Merge unsafe mode with new target selector Signed-off-by: Lorenzo Alberto Maria Ambrosi <lorenzothunder.ambrosi@gmail.com>
This commit is contained in:
parent
71c7fbd3a2
commit
b0c71b21b3
@ -14,26 +14,36 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import {
|
||||||
|
faChevronDown,
|
||||||
|
faExclamationTriangle,
|
||||||
|
} from '@fortawesome/free-solid-svg-icons';
|
||||||
import { Drive as DrivelistDrive } from 'drivelist';
|
import { Drive as DrivelistDrive } from 'drivelist';
|
||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { Badge, Table as BaseTable, Txt, Flex } from 'rendition';
|
import { Badge, Table as BaseTable, Txt, Flex, Link } from 'rendition';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
COMPATIBILITY_STATUS_TYPES,
|
|
||||||
getDriveImageCompatibilityStatuses,
|
getDriveImageCompatibilityStatuses,
|
||||||
hasListDriveImageCompatibilityStatus,
|
hasListDriveImageCompatibilityStatus,
|
||||||
isDriveValid,
|
isDriveValid,
|
||||||
hasDriveImageCompatibilityStatus,
|
hasDriveImageCompatibilityStatus,
|
||||||
|
TargetStatus,
|
||||||
} from '../../../../shared/drive-constraints';
|
} from '../../../../shared/drive-constraints';
|
||||||
|
import { compatibility } from '../../../../shared/messages';
|
||||||
import { bytesToClosestUnit } from '../../../../shared/units';
|
import { bytesToClosestUnit } from '../../../../shared/units';
|
||||||
import { getDrives, hasAvailableDrives } from '../../models/available-drives';
|
import { getDrives, hasAvailableDrives } from '../../models/available-drives';
|
||||||
import { getImage, getSelectedDrives } from '../../models/selection-state';
|
import {
|
||||||
|
getImage,
|
||||||
|
getSelectedDrives,
|
||||||
|
isDriveSelected,
|
||||||
|
} from '../../models/selection-state';
|
||||||
import { store } from '../../models/store';
|
import { store } from '../../models/store';
|
||||||
import * as analytics from '../../modules/analytics';
|
import * as analytics from '../../modules/analytics';
|
||||||
import { open as openExternal } from '../../os/open-external/services/open-external';
|
import { open as openExternal } from '../../os/open-external/services/open-external';
|
||||||
import { Modal } from '../../styled-components';
|
import { Modal } from '../../styled-components';
|
||||||
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||||
|
|
||||||
export interface DrivelistTarget extends DrivelistDrive {
|
export interface DrivelistTarget extends DrivelistDrive {
|
||||||
displayName: string;
|
displayName: string;
|
||||||
@ -53,9 +63,7 @@ export interface DrivelistTarget extends DrivelistDrive {
|
|||||||
* containing the status type (ERROR, WARNING), and accompanying
|
* containing the status type (ERROR, WARNING), and accompanying
|
||||||
* status message.
|
* status message.
|
||||||
*/
|
*/
|
||||||
function getDriveStatuses(
|
function getDriveStatuses(drive: DrivelistTarget): TargetStatus[] {
|
||||||
drive: DrivelistTarget,
|
|
||||||
): Array<{ type: number; message: string }> {
|
|
||||||
return getDriveImageCompatibilityStatuses(drive, getImage());
|
return getDriveImageCompatibilityStatuses(drive, getImage());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,15 +103,20 @@ interface DriverlessDrive {
|
|||||||
linkMessage: string;
|
linkMessage: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface TargetStatus {
|
function badgeShadeFromStatus(status: string) {
|
||||||
message: string;
|
switch (status) {
|
||||||
type: number;
|
case compatibility.containsImage():
|
||||||
|
return 16;
|
||||||
|
case compatibility.system():
|
||||||
|
return 5;
|
||||||
|
default:
|
||||||
|
return 14;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderStatuses(statuses: TargetStatus[]) {
|
function renderStatuses(statuses: TargetStatus[]) {
|
||||||
return _.map(statuses, (status) => {
|
return _.map(statuses, (status) => {
|
||||||
const badgeShade =
|
const badgeShade = badgeShadeFromStatus(status.message);
|
||||||
status.type === COMPATIBILITY_STATUS_TYPES.WARNING ? 14 : 5;
|
|
||||||
return (
|
return (
|
||||||
<Badge key={status.message} shade={badgeShade}>
|
<Badge key={status.message} shade={badgeShade}>
|
||||||
{status.message}
|
{status.message}
|
||||||
@ -124,7 +137,6 @@ const InitProgress = styled(
|
|||||||
},
|
},
|
||||||
)`
|
)`
|
||||||
/* Reset the default appearance */
|
/* Reset the default appearance */
|
||||||
-webkit-appearance: none;
|
|
||||||
appearance: none;
|
appearance: none;
|
||||||
|
|
||||||
::-webkit-progress-bar {
|
::-webkit-progress-bar {
|
||||||
@ -141,7 +153,7 @@ const InitProgress = styled(
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
function renderProgress(progress: number) {
|
function renderProgress(progress: number) {
|
||||||
if (Boolean(progress)) {
|
if (progress) {
|
||||||
return (
|
return (
|
||||||
<Flex flexDirection="column">
|
<Flex flexDirection="column">
|
||||||
<Txt fontSize={12}>Initializing device</Txt>
|
<Txt fontSize={12}>Initializing device</Txt>
|
||||||
@ -149,15 +161,13 @@ function renderProgress(progress: number) {
|
|||||||
</Flex>
|
</Flex>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface TableData extends DrivelistTarget {
|
interface TableData extends DrivelistTarget {
|
||||||
disabled: boolean;
|
disabled: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const TargetSelectorModal = styled(
|
export const TargetSelectorModal = ({
|
||||||
({
|
|
||||||
close,
|
close,
|
||||||
cancel,
|
cancel,
|
||||||
}: {
|
}: {
|
||||||
@ -169,12 +179,12 @@ export const TargetSelectorModal = styled(
|
|||||||
defaultMissingDriversModalState,
|
defaultMissingDriversModalState,
|
||||||
);
|
);
|
||||||
const [drives, setDrives] = React.useState(getDrives());
|
const [drives, setDrives] = React.useState(getDrives());
|
||||||
const [selected, setSelected] = React.useState(getSelectedDrives());
|
const [selectedList, setSelected] = React.useState(getSelectedDrives());
|
||||||
|
const [showSystemDrives, setShowSystemDrives] = React.useState(false);
|
||||||
const image = getImage();
|
const image = getImage();
|
||||||
|
const hasStatus = hasListDriveImageCompatibilityStatus(selectedList, image);
|
||||||
|
|
||||||
const hasStatus = hasListDriveImageCompatibilityStatus(selected, image);
|
const enrichedDrivesData = _.map(drives, (drive) => {
|
||||||
|
|
||||||
const tableData = _.map(drives, (drive) => {
|
|
||||||
return {
|
return {
|
||||||
...drive,
|
...drive,
|
||||||
extra: drive.progress || getDriveStatuses(drive),
|
extra: drive.progress || getDriveStatuses(drive),
|
||||||
@ -182,6 +192,11 @@ export const TargetSelectorModal = styled(
|
|||||||
highlighted: hasDriveImageCompatibilityStatus(drive, image),
|
highlighted: hasDriveImageCompatibilityStatus(drive, image),
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
const normalDrives = _.reject(
|
||||||
|
enrichedDrivesData,
|
||||||
|
(drive) => drive.isSystem && !isDriveSelected(drive.device),
|
||||||
|
);
|
||||||
|
const systemDrives = _.filter(enrichedDrivesData, 'isSystem');
|
||||||
const disabledRows = _.map(
|
const disabledRows = _.map(
|
||||||
_.filter(drives, (drive) => {
|
_.filter(drives, (drive) => {
|
||||||
return !isDriveValid(drive, image) || drive.progress;
|
return !isDriveValid(drive, image) || drive.progress;
|
||||||
@ -193,6 +208,19 @@ export const TargetSelectorModal = styled(
|
|||||||
{
|
{
|
||||||
field: 'description',
|
field: 'description',
|
||||||
label: 'Name',
|
label: 'Name',
|
||||||
|
render: (description: string, drive: DrivelistTarget) => {
|
||||||
|
return drive.isSystem ? (
|
||||||
|
<Flex alignItems="center">
|
||||||
|
<FontAwesomeIcon
|
||||||
|
style={{ color: '#fca321' }}
|
||||||
|
icon={faExclamationTriangle}
|
||||||
|
/>
|
||||||
|
<Txt ml={8}>{description}</Txt>
|
||||||
|
</Flex>
|
||||||
|
) : (
|
||||||
|
<Txt>{description}</Txt>
|
||||||
|
);
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: 'size',
|
field: 'size',
|
||||||
@ -250,8 +278,7 @@ export const TargetSelectorModal = styled(
|
|||||||
if (drive.link) {
|
if (drive.link) {
|
||||||
analytics.logEvent('Open driver link modal', {
|
analytics.logEvent('Open driver link modal', {
|
||||||
url: drive.link,
|
url: drive.link,
|
||||||
applicationSessionUuid: store.getState().toJS()
|
applicationSessionUuid: store.getState().toJS().applicationSessionUuid,
|
||||||
.applicationSessionUuid,
|
|
||||||
flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid,
|
flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid,
|
||||||
});
|
});
|
||||||
setMissingDriversModal({ drive });
|
setMissingDriversModal({ drive });
|
||||||
@ -261,13 +288,23 @@ export const TargetSelectorModal = styled(
|
|||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
titleElement={
|
titleElement={
|
||||||
|
<Flex alignItems="baseline" mb={18}>
|
||||||
<Txt fontSize={24} align="left">
|
<Txt fontSize={24} align="left">
|
||||||
Select target
|
Select target
|
||||||
</Txt>
|
</Txt>
|
||||||
|
<Txt
|
||||||
|
fontSize={11}
|
||||||
|
ml={12}
|
||||||
|
color="#5b82a7"
|
||||||
|
style={{ fontWeight: 600 }}
|
||||||
|
>
|
||||||
|
{drives.length} found
|
||||||
|
</Txt>
|
||||||
|
</Flex>
|
||||||
}
|
}
|
||||||
titleDetails={<Txt fontSize={11}>{getDrives().length} found</Txt>}
|
titleDetails={<Txt fontSize={11}>{getDrives().length} found</Txt>}
|
||||||
cancel={cancel}
|
cancel={cancel}
|
||||||
done={() => close(selected)}
|
done={() => close(selectedList)}
|
||||||
action="Continue"
|
action="Continue"
|
||||||
style={{
|
style={{
|
||||||
width: '780px',
|
width: '780px',
|
||||||
@ -284,14 +321,22 @@ export const TargetSelectorModal = styled(
|
|||||||
<b>Plug a target drive</b>
|
<b>Plug a target drive</b>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
|
<Flex
|
||||||
|
flexDirection="column"
|
||||||
|
style={{ maxHeight: !showSystemDrives ? 250 : 265 }}
|
||||||
|
>
|
||||||
<TargetsTable
|
<TargetsTable
|
||||||
refFn={(t: BaseTable<TableData>) => {
|
refFn={(t: BaseTable<TableData>) => {
|
||||||
if (!_.isNull(t)) {
|
if (!_.isNull(t)) {
|
||||||
t.setRowSelection(selected);
|
t.setRowSelection(selectedList);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
columns={columns}
|
columns={columns}
|
||||||
data={tableData}
|
data={_.uniq(
|
||||||
|
showSystemDrives
|
||||||
|
? normalDrives.concat(systemDrives)
|
||||||
|
: normalDrives,
|
||||||
|
)}
|
||||||
disabledRows={disabledRows}
|
disabledRows={disabledRows}
|
||||||
rowKey="displayName"
|
rowKey="displayName"
|
||||||
onCheck={(rows: TableData[]) => {
|
onCheck={(rows: TableData[]) => {
|
||||||
@ -299,25 +344,36 @@ export const TargetSelectorModal = styled(
|
|||||||
}}
|
}}
|
||||||
onRowClick={(row: TableData) => {
|
onRowClick={(row: TableData) => {
|
||||||
if (!row.disabled) {
|
if (!row.disabled) {
|
||||||
const selectedIndex = selected.findIndex(
|
const selectedIndex = selectedList.findIndex(
|
||||||
(target) => target.device === row.device,
|
(target) => target.device === row.device,
|
||||||
);
|
);
|
||||||
if (selectedIndex === -1) {
|
if (selectedIndex === -1) {
|
||||||
selected.push(row);
|
selectedList.push(row);
|
||||||
setSelected(_.map(selected));
|
setSelected(_.map(selectedList));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Deselect if selected
|
// Deselect if selected
|
||||||
setSelected(
|
setSelected(
|
||||||
_.reject(
|
_.reject(
|
||||||
selected,
|
selectedList,
|
||||||
(drive) =>
|
(drive) =>
|
||||||
selected[selectedIndex].device === drive.device,
|
selectedList[selectedIndex].device === drive.device,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
></TargetsTable>
|
></TargetsTable>
|
||||||
|
{!showSystemDrives && (
|
||||||
|
<Link mt={16} onClick={() => setShowSystemDrives(true)}>
|
||||||
|
<Flex alignItems="center">
|
||||||
|
<FontAwesomeIcon icon={faChevronDown} />
|
||||||
|
<Txt ml={8}>
|
||||||
|
Show {drives.length - normalDrives.length} hidden
|
||||||
|
</Txt>
|
||||||
|
</Flex>
|
||||||
|
</Link>
|
||||||
|
)}
|
||||||
|
</Flex>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -349,27 +405,4 @@ export const TargetSelectorModal = styled(
|
|||||||
)}
|
)}
|
||||||
</Modal>
|
</Modal>
|
||||||
);
|
);
|
||||||
},
|
};
|
||||||
)`
|
|
||||||
> [data-display='table-head']
|
|
||||||
> [data-display='table-row']
|
|
||||||
> [data-display='table-cell']:first-child {
|
|
||||||
padding-left: 15px;
|
|
||||||
}
|
|
||||||
> [data-display='table-head']
|
|
||||||
> [data-display='table-row']
|
|
||||||
> [data-display='table-cell'] {
|
|
||||||
padding: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
> [data-display='table-body']
|
|
||||||
> [data-display='table-row']
|
|
||||||
> [data-display='table-cell']:first-child {
|
|
||||||
padding-left: 15px;
|
|
||||||
}
|
|
||||||
> [data-display='table-body']
|
|
||||||
> [data-display='table-row']
|
|
||||||
> [data-display='table-cell'] {
|
|
||||||
padding: 10px;
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
@ -73,7 +73,6 @@ export async function writeConfigFile(
|
|||||||
}
|
}
|
||||||
|
|
||||||
const DEFAULT_SETTINGS: _.Dictionary<any> = {
|
const DEFAULT_SETTINGS: _.Dictionary<any> = {
|
||||||
unsafeMode: false,
|
|
||||||
errorReporting: true,
|
errorReporting: true,
|
||||||
unmountOnSuccess: true,
|
unmountOnSuccess: true,
|
||||||
validateWriteOnSuccess: true,
|
validateWriteOnSuccess: true,
|
||||||
|
@ -17,19 +17,10 @@
|
|||||||
import * as sdk from 'etcher-sdk';
|
import * as sdk from 'etcher-sdk';
|
||||||
import { geteuid, platform } from 'process';
|
import { geteuid, platform } from 'process';
|
||||||
|
|
||||||
import * as settings from '../models/settings';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @summary returns true if system drives should be shown
|
|
||||||
*/
|
|
||||||
function includeSystemDrives() {
|
|
||||||
return (
|
|
||||||
settings.getSync('unsafeMode') && !settings.getSync('disableUnsafeMode')
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const adapters: sdk.scanner.adapters.Adapter[] = [
|
const adapters: sdk.scanner.adapters.Adapter[] = [
|
||||||
new sdk.scanner.adapters.BlockDeviceAdapter({ includeSystemDrives }),
|
new sdk.scanner.adapters.BlockDeviceAdapter({
|
||||||
|
includeSystemDrives: () => true,
|
||||||
|
}),
|
||||||
];
|
];
|
||||||
|
|
||||||
// Can't use permissions.isElevated() here as it returns a promise and we need to set
|
// Can't use permissions.isElevated() here as it returns a promise and we need to set
|
||||||
|
@ -131,8 +131,13 @@ export const Modal = styled((props) => {
|
|||||||
> div {
|
> div {
|
||||||
padding: 30px;
|
padding: 30px;
|
||||||
|
|
||||||
|
> h3 {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
> div:last-child {
|
> div:last-child {
|
||||||
height: 80px;
|
height: 80px;
|
||||||
|
background-color: #fff;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
|
@ -172,12 +172,7 @@ export function getDriveImageCompatibilityStatuses(
|
|||||||
const statusList = [];
|
const statusList = [];
|
||||||
|
|
||||||
// Mind the order of the if-statements if you modify.
|
// Mind the order of the if-statements if you modify.
|
||||||
if (isSourceDrive(drive, image)) {
|
if (isDriveLocked(drive)) {
|
||||||
statusList.push({
|
|
||||||
type: COMPATIBILITY_STATUS_TYPES.ERROR,
|
|
||||||
message: messages.compatibility.containsImage(),
|
|
||||||
});
|
|
||||||
} else if (isDriveLocked(drive)) {
|
|
||||||
statusList.push({
|
statusList.push({
|
||||||
type: COMPATIBILITY_STATUS_TYPES.ERROR,
|
type: COMPATIBILITY_STATUS_TYPES.ERROR,
|
||||||
message: messages.compatibility.locked(),
|
message: messages.compatibility.locked(),
|
||||||
@ -196,6 +191,13 @@ export function getDriveImageCompatibilityStatuses(
|
|||||||
message: messages.compatibility.tooSmall(prettyBytes(relativeBytes)),
|
message: messages.compatibility.tooSmall(prettyBytes(relativeBytes)),
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
if (isSourceDrive(drive, image)) {
|
||||||
|
statusList.push({
|
||||||
|
type: COMPATIBILITY_STATUS_TYPES.ERROR,
|
||||||
|
message: messages.compatibility.containsImage(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (isSystemDrive(drive)) {
|
if (isSystemDrive(drive)) {
|
||||||
statusList.push({
|
statusList.push({
|
||||||
type: COMPATIBILITY_STATUS_TYPES.WARNING,
|
type: COMPATIBILITY_STATUS_TYPES.WARNING,
|
||||||
@ -273,3 +275,8 @@ export function hasListDriveImageCompatibilityStatus(
|
|||||||
) {
|
) {
|
||||||
return Boolean(getListDriveImageCompatibilityStatuses(drives, image).length);
|
return Boolean(getListDriveImageCompatibilityStatuses(drives, image).length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface TargetStatus {
|
||||||
|
message: string;
|
||||||
|
type: number;
|
||||||
|
}
|
||||||
|
@ -65,16 +65,16 @@ export const compatibility = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
system: () => {
|
system: () => {
|
||||||
return 'System Drive';
|
return 'System drive';
|
||||||
},
|
},
|
||||||
|
|
||||||
containsImage: () => {
|
containsImage: () => {
|
||||||
return 'Drive Mountpoint Contains Image';
|
return 'Source drive';
|
||||||
},
|
},
|
||||||
|
|
||||||
// The drive is large and therefore likely not a medium you want to write to.
|
// The drive is large and therefore likely not a medium you want to write to.
|
||||||
largeDrive: () => {
|
largeDrive: () => {
|
||||||
return 'Large Drive';
|
return 'Large drive';
|
||||||
},
|
},
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
|
@ -1126,7 +1126,7 @@ describe('Shared: DriveConstraints', function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('given the drive contains the image and the drive is locked', () => {
|
describe('given the drive contains the image and the drive is locked', () => {
|
||||||
it('should return the contains-image drive error by precedence', function () {
|
it('should return the locked error by precedence', function () {
|
||||||
this.drive.isReadOnly = true;
|
this.drive.isReadOnly = true;
|
||||||
this.image.path = path.join(this.mountpoint, 'rpi.img');
|
this.image.path = path.join(this.mountpoint, 'rpi.img');
|
||||||
|
|
||||||
@ -1135,7 +1135,7 @@ describe('Shared: DriveConstraints', function () {
|
|||||||
this.image,
|
this.image,
|
||||||
);
|
);
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const expectedTuples = [['ERROR', 'containsImage']];
|
const expectedTuples = [['ERROR', 'locked']];
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
expectStatusTypesAndMessagesToBe(result, expectedTuples);
|
expectStatusTypesAndMessagesToBe(result, expectedTuples);
|
||||||
@ -1303,7 +1303,7 @@ describe('Shared: DriveConstraints', function () {
|
|||||||
),
|
),
|
||||||
).to.deep.equal([
|
).to.deep.equal([
|
||||||
{
|
{
|
||||||
message: 'Drive Mountpoint Contains Image',
|
message: 'Source drive',
|
||||||
type: 2,
|
type: 2,
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
@ -1345,7 +1345,7 @@ describe('Shared: DriveConstraints', function () {
|
|||||||
),
|
),
|
||||||
).to.deep.equal([
|
).to.deep.equal([
|
||||||
{
|
{
|
||||||
message: 'System Drive',
|
message: 'System drive',
|
||||||
type: 1,
|
type: 1,
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
@ -1359,7 +1359,7 @@ describe('Shared: DriveConstraints', function () {
|
|||||||
),
|
),
|
||||||
).to.deep.equal([
|
).to.deep.equal([
|
||||||
{
|
{
|
||||||
message: 'Large Drive',
|
message: 'Large drive',
|
||||||
type: 1,
|
type: 1,
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
@ -1386,7 +1386,7 @@ describe('Shared: DriveConstraints', function () {
|
|||||||
constraints.getListDriveImageCompatibilityStatuses(drives, image),
|
constraints.getListDriveImageCompatibilityStatuses(drives, image),
|
||||||
).to.deep.equal([
|
).to.deep.equal([
|
||||||
{
|
{
|
||||||
message: 'Drive Mountpoint Contains Image',
|
message: 'Source drive',
|
||||||
type: 2,
|
type: 2,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1398,11 +1398,11 @@ describe('Shared: DriveConstraints', function () {
|
|||||||
type: 2,
|
type: 2,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
message: 'System Drive',
|
message: 'System drive',
|
||||||
type: 1,
|
type: 1,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
message: 'Large Drive',
|
message: 'Large drive',
|
||||||
type: 1,
|
type: 1,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user