Show upgrade disk checks by directory
This commit is contained in:
@@ -464,13 +464,12 @@ function validatePreExtractDiskSpace(packageBytes) {
|
||||
requiredBytes: packageBytes + MAX_EXTRACTED_BYTES + MIN_FREE_BYTES,
|
||||
});
|
||||
assertDiskSpace(stateCheck);
|
||||
logStep('磁盘空间检查', `${stateCheck.label} ${stateCheck.path} 可用 ${formatBytes(stateCheck.availableBytes)},需要 ${formatBytes(stateCheck.requiredBytes)}`);
|
||||
logDiskCheck(stateCheck);
|
||||
return [stateCheck];
|
||||
}
|
||||
|
||||
function validateUpgradeDiskSpace(stats, packageBytes) {
|
||||
const checksByPath = new Map();
|
||||
for (const check of [
|
||||
const checks = [
|
||||
buildDiskCheck({
|
||||
label: '升级状态目录',
|
||||
targetPath: stateRoot,
|
||||
@@ -481,16 +480,10 @@ function validateUpgradeDiskSpace(stats, packageBytes) {
|
||||
targetPath: projectRoot,
|
||||
requiredBytes: stats.totalBytes + (mode === 'cold' ? BUILD_FREE_BYTES : MIN_FREE_BYTES),
|
||||
}),
|
||||
]) {
|
||||
const existing = checksByPath.get(check.path);
|
||||
if (!existing || check.requiredBytes > existing.requiredBytes) {
|
||||
checksByPath.set(check.path, check);
|
||||
}
|
||||
}
|
||||
const checks = [...checksByPath.values()];
|
||||
];
|
||||
for (const check of checks) {
|
||||
assertDiskSpace(check);
|
||||
logStep('磁盘空间检查', `${check.label} ${check.path} 可用 ${formatBytes(check.availableBytes)},需要 ${formatBytes(check.requiredBytes)}`);
|
||||
logDiskCheck(check);
|
||||
}
|
||||
return checks;
|
||||
}
|
||||
@@ -499,7 +492,8 @@ function buildDiskCheck({ label, targetPath, requiredBytes }) {
|
||||
const usage = readDiskUsage(targetPath);
|
||||
return {
|
||||
label,
|
||||
path: usage.path,
|
||||
path: path.resolve(targetPath),
|
||||
mountPath: usage.mountPath,
|
||||
totalBytes: usage.totalBytes,
|
||||
availableBytes: usage.availableBytes,
|
||||
requiredBytes,
|
||||
@@ -526,7 +520,7 @@ function readDiskUsage(targetPath) {
|
||||
throw new Error(`读取磁盘空间失败:${targetPath}`);
|
||||
}
|
||||
return {
|
||||
path: row.slice(5).join(' ') || targetPath,
|
||||
mountPath: row.slice(5).join(' ') || targetPath,
|
||||
totalBytes,
|
||||
availableBytes,
|
||||
usedPercent: Number.isFinite(usedPercent) ? usedPercent : null,
|
||||
@@ -539,6 +533,11 @@ function assertDiskSpace(check) {
|
||||
throw new Error(`升级前磁盘空间不足:${check.label} ${check.path} 可用 ${formatBytes(check.availableBytes)},需要至少 ${formatBytes(check.requiredBytes)}`);
|
||||
}
|
||||
|
||||
function logDiskCheck(check) {
|
||||
const mountDetail = check.mountPath && check.mountPath !== check.path ? `(挂载点 ${check.mountPath})` : '';
|
||||
logStep('磁盘空间检查', `${check.label} ${check.path}${mountDetail} 可用 ${formatBytes(check.availableBytes)},需要 ${formatBytes(check.requiredBytes)}`);
|
||||
}
|
||||
|
||||
function validateFiles(files, updateMode) {
|
||||
for (const file of files) {
|
||||
assertSafeRelativePath(file);
|
||||
|
||||
@@ -52,6 +52,7 @@ type UpgradeJobState = {
|
||||
type DiskCheck = {
|
||||
label: string;
|
||||
path: string;
|
||||
mountPath?: string;
|
||||
totalBytes: number;
|
||||
availableBytes: number;
|
||||
requiredBytes?: number;
|
||||
@@ -114,15 +115,10 @@ function getRuntimeStatus(): RuntimeStatus {
|
||||
}
|
||||
|
||||
function getRuntimeDisks(projectRoot: string, stateDir: string): DiskCheck[] {
|
||||
const checks = [
|
||||
return [
|
||||
readDiskUsage('项目目录', projectRoot),
|
||||
readDiskUsage('升级状态目录', stateDir),
|
||||
].filter((check): check is DiskCheck => Boolean(check));
|
||||
const byPath = new Map<string, DiskCheck>();
|
||||
for (const check of checks) {
|
||||
if (!byPath.has(check.path)) byPath.set(check.path, check);
|
||||
}
|
||||
return [...byPath.values()];
|
||||
}
|
||||
|
||||
function readDiskUsage(label: string, targetPath: string): DiskCheck | null {
|
||||
@@ -139,7 +135,8 @@ function readDiskUsage(label: string, targetPath: string): DiskCheck | null {
|
||||
if (!Number.isFinite(totalBytes) || !Number.isFinite(availableBytes)) return null;
|
||||
return {
|
||||
label,
|
||||
path: row.slice(5).join(' ') || targetPath,
|
||||
path: path.resolve(targetPath),
|
||||
mountPath: row.slice(5).join(' ') || targetPath,
|
||||
totalBytes,
|
||||
availableBytes,
|
||||
usedPercent: Number.isFinite(usedPercent) ? usedPercent : null,
|
||||
|
||||
@@ -93,6 +93,7 @@ type RuntimeStatus = {
|
||||
type DiskCheck = {
|
||||
label: string;
|
||||
path: string;
|
||||
mountPath?: string;
|
||||
totalBytes: number;
|
||||
availableBytes: number;
|
||||
requiredBytes?: number;
|
||||
@@ -649,6 +650,9 @@ function DiskCheckList({ checks, showRequired = false }: { checks: DiskCheck[];
|
||||
</span>
|
||||
</div>
|
||||
<div className="mt-1 truncate font-mono text-xs text-muted-foreground" title={check.path}>{check.path}</div>
|
||||
{check.mountPath && check.mountPath !== check.path && (
|
||||
<div className="mt-1 truncate text-xs text-muted-foreground" title={check.mountPath}>挂载点 {check.mountPath}</div>
|
||||
)}
|
||||
<div className="mt-2 grid gap-2 text-xs text-muted-foreground sm:grid-cols-2">
|
||||
<span>可用 {formatBytes(check.availableBytes)} / 总计 {formatBytes(check.totalBytes)}</span>
|
||||
{showRequired && typeof check.requiredBytes === 'number' && <span>本次至少需要 {formatBytes(check.requiredBytes)}</span>}
|
||||
|
||||
Reference in New Issue
Block a user