Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

patch: upgrade balena-lint to 6.2.2 #298

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions lib/block-write-stream.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export class BlockWriteStream extends Writable {
highWaterMark?: number;
delayFirstBuffer?: boolean;
maxRetries?: number;
startOffset?: number
startOffset?: number;
}) {
super({ objectMode: true, highWaterMark });
this.destination = destination;
Expand All @@ -59,7 +59,12 @@ export class BlockWriteStream extends Writable {
private async writeBuffer(buffer: Buffer, position: number): Promise<void> {
await retryOnTransientError(
async () => {
await this.destination.write(buffer, 0, buffer.length, position + this.startOffset);
await this.destination.write(
buffer,
0,
buffer.length,
position + this.startOffset,
);
},
this.maxRetries,
RETRY_BASE_TIMEOUT,
Expand Down
127 changes: 71 additions & 56 deletions lib/diskpart.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@ const DISKPART_RETRIES = 5;
const PATTERN = /PHYSICALDRIVE(\d+)/i;

// This module provides utility functions for disk partitioning and related disk
// level tasks. Presently it relies on the Windows 'diskpart' utility to implement
// level tasks. Presently it relies on the Windows 'diskpart' utility to implement
// this functionality.
// Given this reliance, any new exported functions must throw an Error when used on
// Given this reliance, any new exported functions must throw an Error when used on
// non-Windows platforms. Only the clean() function silently accepts non-Windows
// platforms, for historical reasons. Of course it also is fine to implement a function
// with support for other platforms, and we may do so generally in the future.
Expand All @@ -57,7 +57,7 @@ class ExecError extends Error {
const execFileAsync = async (
command: string,
args: string[] = [],
options: ExecFileOptions = {}
options: ExecFileOptions = {},
): Promise<ExecResult> => {
return await new Promise(
(resolve: (res: ExecResult) => void, reject: (err: ExecError) => void) => {
Expand All @@ -71,9 +71,9 @@ const execFileAsync = async (
} else {
resolve({ stdout, stderr });
}
}
},
);
}
},
);
};

Expand All @@ -97,19 +97,16 @@ const runDiskpart = async (commands: string[]): Promise<string> => {
if (platform() !== 'win32') {
return '';
}
let output = { 'stdout':'', 'stderr':'' }
let output = { stdout: '', stderr: '' };
await withTmpFile({ keepOpen: false }, async (file: TmpFileResult) => {
await fs.writeFile(file.path, commands.join('\r\n'));
await withDiskpartMutex(async () => {
output = await execFileAsync('diskpart', [
'/s',
file.path,
]);
output = await execFileAsync('diskpart', ['/s', file.path]);
debug('stdout:', output.stdout);
debug('stderr:', output.stderr);
});
});
return output.stdout
return output.stdout;
};

/**
Expand Down Expand Up @@ -137,9 +134,9 @@ const prepareDeviceId = (device: string) => {
export const clean = async (device: string): Promise<void> => {
debug('clean', device);
if (platform() !== 'win32') {
return
return;
}

let deviceId;

try {
Expand All @@ -165,7 +162,7 @@ export const clean = async (device: string): Promise<void> => {
await delay(DISKPART_DELAY);
} else {
throw new Error(
`Couldn't clean the drive, ${error.message} (code ${error.code})`
`Couldn't clean the drive, ${error.message} (code ${error.code})`,
);
}
}
Expand All @@ -183,11 +180,11 @@ export const clean = async (device: string): Promise<void> => {
*/
export const shrinkPartition = async (
partition: string,
desiredMB?: number
desiredMB?: number,
) => {
debug('shrink', partition, desiredMB);
if (platform() !== 'win32') {
throw new Error("shrinkPartition() not available on this platform")
throw new Error('shrinkPartition() not available on this platform');
}

try {
Expand All @@ -196,15 +193,17 @@ export const shrinkPartition = async (
`shrink ${desiredMB ? 'DESIRED='.concat(desiredMB + '') : ''}`,
]);
} catch (error) {
throw(`shrinkPartition: ${error}${error.stdout ? `\n${error.stdout}` : ''}`);
throw new Error(
`shrinkPartition: ${error}${error.stdout ? `\n${error.stdout}` : ''}`,
);
}
};

/**
*
* @param {string} device - device path
* @param {number} sizeMB - size of the new partition (free space has to be present)
* @param {string} fs - default "fat32", possible "ntfs" the filesystem to format with
* @param {string} fsType - default "fat32", possible "ntfs" the filesystem to format with
* @param {string} desiredLetter - letter to assign to the new volume, gets the next free letter by default
* @example
* createPartition('\\\\.\\PhysicalDrive2', 2048)
Expand All @@ -214,12 +213,12 @@ export const shrinkPartition = async (
export const createPartition = async (
device: string,
sizeMB: number,
fs?: 'exFAT' | 'fat32' | 'ntfs',
fsType?: 'exFAT' | 'fat32' | 'ntfs',
label?: string,
desiredLetter?: string
desiredLetter?: string,
) => {
if (platform() !== 'win32') {
throw new Error("createPartition() not available on this platform")
throw new Error('createPartition() not available on this platform');
}

const deviceId = prepareDeviceId(device);
Expand All @@ -228,11 +227,19 @@ export const createPartition = async (
`select disk ${deviceId}`,
`create partition primary size=${sizeMB}`,
`${desiredLetter ? 'assign letter='.concat(desiredLetter) : ''}`,
`${fs ? 'format fs='.concat(fs).concat(`label=${label ?? 'Balena Volume'}`.concat(' quick')) : ''}`,
`detail partition`
])
`${
fsType
? 'format fs='
.concat(fsType)
.concat(`label=${label ?? 'Balena Volume'}`.concat(' quick'))
: ''
}`,
`detail partition`,
]);
} catch (error) {
throw(`createPartition: ${error}${error.stdout ? `\n${error.stdout}` : ''}`);
throw new Error(
`createPartition: ${error}${error.stdout ? `\n${error.stdout}` : ''}`,
);
}
};

Expand All @@ -246,10 +253,12 @@ export const createPartition = async (
*/
export const setPartitionOnlineStatus = async (
volume: string,
status: boolean
status: boolean,
) => {
if (platform() !== 'win32') {
throw new Error("setPartitionOnlineStatus() not available on this platform")
throw new Error(
'setPartitionOnlineStatus() not available on this platform',
);
}

try {
Expand All @@ -258,7 +267,11 @@ export const setPartitionOnlineStatus = async (
`${status ? 'online' : 'offline'} volume`,
]);
} catch (error) {
throw(`setPartitionOnlineStatus: ${error}${error.stdout ? `\n${error.stdout}` : ''}`);
throw new Error(
`setPartitionOnlineStatus: ${error}${
error.stdout ? `\n${error.stdout}` : ''
}`,
);
}
};

Expand All @@ -275,7 +288,7 @@ export const setPartitionOnlineStatus = async (
*/
export const findVolume = async (
device: string,
label: string
label: string,
): Promise<string> => {
const deviceId = prepareDeviceId(device);

Expand All @@ -290,49 +303,49 @@ export const findVolume = async (
* Volume 4 NTFS Partition 530 MB Healthy Hidden
*/
if (platform() !== 'win32') {
throw new Error("findVolume() not available on this platform")
throw new Error('findVolume() not available on this platform');
}

let listText = ''
let listText = '';
try {
listText = await runDiskpart([
`select disk ${deviceId}`,
`list volume`
]);
listText = await runDiskpart([`select disk ${deviceId}`, `list volume`]);
} catch (error) {
throw(`findVolume: ${error}${error.stdout ? `\n${error.stdout}` : ''}`);
throw new Error(
`findVolume: ${error}${error.stdout ? `\n${error.stdout}` : ''}`,
);
}

let labelPos = -1;
// Look for 'Label' in column headings; then compare text on subsequent rows
// at that position for the expected label.
for (let line of listText.split('\n')) {
for (const line of listText.split('\n')) {
if (labelPos < 0) {
labelPos = line.indexOf('Label');
} else {
const volMatch = line.match(/Volume\s+(\d+)/);
if (volMatch && (line.substring(labelPos, labelPos + label.length) == label)) {
return volMatch[1]
if (
volMatch &&
line.substring(labelPos, labelPos + label.length) === label
) {
return volMatch[1];
}
}
}
return ''
return '';
};

/**
* Provide unallocated space on disk, in KB
*
*
* @param {string} device - device path
* @example
* getUnallocatedSize('\\\\.\\PhysicalDrive0')
* .then(...)
* .catch(...)
*/
export const getUnallocatedSize = async (
device: string
): Promise<number> => {
export const getUnallocatedSize = async (device: string): Promise<number> => {
if (platform() !== 'win32') {
throw new Error("getUnallocatedSize() not available on this platform")
throw new Error('getUnallocatedSize() not available on this platform');
}

const deviceId = prepareDeviceId(device);
Expand All @@ -348,35 +361,37 @@ export const getUnallocatedSize = async (
* -------- ------------- ------- ------- --- ---
* Disk 0 Online 50 GB 6158 MB *
*/
let listText = ''
let listText = '';
try {
listText = await runDiskpart([
`list disk`
]);
listText = await runDiskpart([`list disk`]);
} catch (error) {
throw(`getUnallocatedSize: ${error}${error.stdout ? `\n${error.stdout}` : ''}`);
throw new Error(
`getUnallocatedSize: ${error}${error.stdout ? `\n${error.stdout}` : ''}`,
);
}

let freePos = -1;
// Look for 'Free' in column headings; then read size at that position
// Look for 'Free' in column headings; then read size at that position
// on the row for the requested disk.
for (let line of listText.split('\n')) {
for (const line of listText.split('\n')) {
if (freePos < 0) {
freePos = line.indexOf('Free');
} else if (line.indexOf(`Disk ${deviceId}`) >= 0) {
const freeMatch = line.substring(freePos).match(/(\d+)\s+(\w+)B/);
if (freeMatch) {
let res = Number(freeMatch[1]);
for (let units of ['K', 'M', 'G', 'T']) {
if (freeMatch[2] == units) {
for (const units of ['K', 'M', 'G', 'T']) {
if (freeMatch[2] === units) {
return res;
} else {
res *= 1024;
}
}
}
break; // should have matched; break to throw below
break; // should have matched; break to throw below
}
}
throw(`getUnallocatedSize: Can't read Free space on disk ${deviceId} from: ${listText}`);
throw new Error(
`getUnallocatedSize: Can't read Free space on disk ${deviceId} from: ${listText}`,
);
};
Loading