diff --git a/ogWebconsole/src/app/components/commands/commands-task/task-logs/task-logs.component.ts b/ogWebconsole/src/app/components/commands/commands-task/task-logs/task-logs.component.ts index 37b65e1..d605f41 100644 --- a/ogWebconsole/src/app/components/commands/commands-task/task-logs/task-logs.component.ts +++ b/ogWebconsole/src/app/components/commands/commands-task/task-logs/task-logs.component.ts @@ -50,6 +50,11 @@ export class TaskLogsComponent implements OnInit { header: 'Hilo de trabajo', cell: (trace: any) => `${trace.jobId}` }, + { + columnDef: 'output', + header: 'Logs', + cell: (trace: any) => `${trace.output}` + }, { columnDef: 'executedAt', header: 'Programación de ejecución', diff --git a/ogWebconsole/src/app/components/groups/components/client-main-view/client-main-view.component.css b/ogWebconsole/src/app/components/groups/components/client-main-view/client-main-view.component.css index c86bb98..c1c12f0 100644 --- a/ogWebconsole/src/app/components/groups/components/client-main-view/client-main-view.component.css +++ b/ogWebconsole/src/app/components/groups/components/client-main-view/client-main-view.component.css @@ -233,3 +233,30 @@ text-anchor: middle; } +.disk-container { + display: flex; + flex-direction: row; + justify-content: space-between; + align-items: flex-start; + gap: 20px; +} + +.table-container { + flex: 3; + overflow-x: auto; +} + +.charts-container { + flex: 2; + display: flex; + flex-direction: column; + align-items: center; + gap: 10px; +} + +.disk-usage { + text-align: center; +} + + + diff --git a/ogWebconsole/src/app/components/groups/components/client-main-view/client-main-view.component.html b/ogWebconsole/src/app/components/groups/components/client-main-view/client-main-view.component.html index a78d6f8..c3add36 100644 --- a/ogWebconsole/src/app/components/groups/components/client-main-view/client-main-view.component.html +++ b/ogWebconsole/src/app/components/groups/components/client-main-view/client-main-view.component.html @@ -36,40 +36,44 @@

Discos/Particiones

-
- - - - - - - -
{{ column.header }} - - {{ column.cell(image) }} - - - - {{ (image.size / 1024).toFixed(2) }} GB - - -
-
+
+ +
+ + + + + + + +
{{ column.header }} + + {{ column.cell(image) }} + + + + {{ (image.size / 1024).toFixed(2) }} GB + + +
+
-
- -
+ +
+
+ [doughnut]="true" + >

Disco {{ disk.diskNumber }}

Usado: {{ (disk.used).toFixed(2) }} GB ({{ disk.percentage }}%)

Total: {{ disk.total }} GB

-
- + +
+ diff --git a/ogWebconsole/src/app/components/groups/components/client-main-view/client-main-view.component.ts b/ogWebconsole/src/app/components/groups/components/client-main-view/client-main-view.component.ts index 78b9a40..6e9728b 100644 --- a/ogWebconsole/src/app/components/groups/components/client-main-view/client-main-view.component.ts +++ b/ogWebconsole/src/app/components/groups/components/client-main-view/client-main-view.component.ts @@ -6,6 +6,7 @@ import {PartitionAssistantComponent} from "./partition-assistant/partition-assis import {MatDialog} from "@angular/material/dialog"; import {Router} from "@angular/router"; import {EditClientComponent} from "../../shared/clients/edit-client/edit-client.component"; +import {ToastrService} from "ngx-toastr"; interface ClientInfo { property: string; @@ -90,7 +91,8 @@ export class ClientMainViewComponent implements OnInit { constructor( private http: HttpClient, private dialog: MatDialog, - private router: Router + private router: Router, + private toastService: ToastrService ) { const url = window.location.href; const segments = url.split('/'); @@ -192,7 +194,7 @@ export class ClientMainViewComponent implements OnInit { } loadPartitions(): void { - this.http.get(`${this.baseUrl}/partitions?client.id=${this.clientData?.id}`).subscribe({ + this.http.get(`${this.baseUrl}/partitions?client.id=${this.clientData?.id}&order[partitionNumber]=ASC`).subscribe({ next: data => { this.dataSource = data['hydra:member']; this.partitions = data['hydra:member']; @@ -216,6 +218,7 @@ export class ClientMainViewComponent implements OnInit { } onCommandSelect(action: any): void { + console.log(action); if (action === 'partition') { this.openPartitionAssistant(); } @@ -227,6 +230,55 @@ export class ClientMainViewComponent implements OnInit { if (action === 'deploy-image') { this.openDeployImageAssistant(); } + + if (action === 'reboot') { + this.rebootClient(); + } + + if (action === 'power-off') { + this.powerOffClient(); + } + + if (action === 'power-on') { + this.powerOnClient(); + } + } + + rebootClient(): void { + this.http.post(`${this.baseUrl}/clients/server/${this.clientData.uuid}/reboot`, {}).subscribe( + response => { + this.toastService.success('Cliente actualizado correctamente'); + }, + error => { + this.toastService.error('Error de conexión con el cliente'); + } + ); + } + + powerOnClient(): void { + const payload = { + client: this.clientData['@id'] + } + + this.http.post(`${this.baseUrl}${this.clientData.repository['@id']}/wol`, payload).subscribe( + response => { + this.toastService.success('Cliente actualizado correctamente'); + }, + error => { + this.toastService.error('Error de conexión con el cliente'); + } + ); + } + + powerOffClient(): void { + this.http.post(`${this.baseUrl}/clients/server/${this.clientData.uuid}/power-off`, {}).subscribe( + response => { + this.toastService.success('Cliente actualizado correctamente'); + }, + error => { + this.toastService.error('Error de conexión con el cliente'); + } + ); } openPartitionAssistant(): void { diff --git a/ogWebconsole/src/app/components/groups/components/client-main-view/partition-assistant/partition-assistant.component.css b/ogWebconsole/src/app/components/groups/components/client-main-view/partition-assistant/partition-assistant.component.css index 284808b..3746bb0 100644 --- a/ogWebconsole/src/app/components/groups/components/client-main-view/partition-assistant/partition-assistant.component.css +++ b/ogWebconsole/src/app/components/groups/components/client-main-view/partition-assistant/partition-assistant.component.css @@ -122,3 +122,43 @@ button.remove-btn:hover { border-radius: 4px; margin-top: 10px; } + +.partition-assistant .row { + display: flex; + flex-wrap: wrap; + margin-bottom: 20px; +} + +.form-container { + flex: 0 0 65%; + max-width: 65%; + padding-right: 20px; + box-sizing: border-box; +} + +.chart-container { + flex: 0 0 35%; + max-width: 35%; +} + +.partition-bar { + display: flex; + height: 40px; + margin: 20px 0; +} + +.partition-segment { + display: flex; + justify-content: center; + align-items: center; + text-align: center; + font-size: 10px; + color: white; + height: 100%; +} + +.chart-container ngx-charts-pie-chart { + display: block; + align-content: center; + justify-self: center; +} diff --git a/ogWebconsole/src/app/components/groups/components/client-main-view/partition-assistant/partition-assistant.component.html b/ogWebconsole/src/app/components/groups/components/client-main-view/partition-assistant/partition-assistant.component.html index af3e4ca..311b8f6 100644 --- a/ogWebconsole/src/app/components/groups/components/client-main-view/partition-assistant/partition-assistant.component.html +++ b/ogWebconsole/src/app/components/groups/components/client-main-view/partition-assistant/partition-assistant.component.html @@ -1,67 +1,100 @@ -

Asistente de particionado

+
+

Asistente de particionado

+
+ +
+
+
- + Tamaño: {{ (disk.totalDiskSize / 1024).toFixed(2) }} GB
-
-
- {{ partition.type }} ({{ (partition.size / 1024).toFixed(2) }} GB) +
+
+ {{ partition.partitionCode }} ({{ (partition.size / 1024).toFixed(2) }} GB) +
+
+
+ +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
ParticiónTipo particiónS. ficherosTamaño (MB)Tamaño (%)FormatearEliminar
{{ partition.partitionNumber }} + + + + + + + + + + + +
+
+ +
+ + +
+ - - - - - - - - - - - - - - - - - - - - - - - -
ParticiónTipo particiónTamaño (MB)Uso (%)FormatearEliminar
{{ partition.partitionNumber }} - - - - - - - - - -
-
{{ errorMessage }}
diff --git a/ogWebconsole/src/app/components/groups/components/client-main-view/partition-assistant/partition-assistant.component.ts b/ogWebconsole/src/app/components/groups/components/client-main-view/partition-assistant/partition-assistant.component.ts index ab0803c..cab33a8 100644 --- a/ogWebconsole/src/app/components/groups/components/client-main-view/partition-assistant/partition-assistant.component.ts +++ b/ogWebconsole/src/app/components/groups/components/client-main-view/partition-assistant/partition-assistant.component.ts @@ -2,18 +2,23 @@ import {Component, EventEmitter, Inject, Input, OnInit, Output} from '@angular/c import { HttpClient } from '@angular/common/http'; import { ToastrService } from 'ngx-toastr'; import {MAT_DIALOG_DATA} from "@angular/material/dialog"; -import {ActivatedRoute} from "@angular/router"; +import {ActivatedRoute, Router} from "@angular/router"; +import { PARTITION_TYPES } from '../../../../../shared/constants/partition-types'; +import { FILESYSTEM_TYPES } from '../../../../../shared/constants/filesystem-types'; +import {toUnredirectedSourceFile} from "@angular/compiler-cli/src/ngtsc/util/src/typescript"; interface Partition { uuid?: string; partitionNumber: number; size: number; - type: string; + partitionCode: string; + filesystem: string; sizeBytes: number; memoryUsage: number; format: boolean; color: string; percentage: number; + removed: boolean; } @Component({ @@ -24,19 +29,27 @@ interface Partition { export class PartitionAssistantComponent implements OnInit { baseUrl: string = import.meta.env.NG_APP_BASE_API_URL; @Output() dataChange = new EventEmitter(); - + partitionTypes = PARTITION_TYPES; + filesystemTypes = FILESYSTEM_TYPES; errorMessage = ''; originalPartitions: any[] = []; clientId: string | null = null; + newPartitions: any[] = []; + updateRequests: any[] = []; data: any = {}; - disks: { diskNumber: number; totalDiskSize: number; partitions: Partition[] }[] = []; + disks: { diskNumber: number; totalDiskSize: number; partitions: Partition[]; chartData: any[]; used: number; percentage: number }[] = []; private apiUrl: string = this.baseUrl + '/partitions'; + view: [number, number] = [400, 300]; + showLegend = true; + showLabels = true; + constructor( private http: HttpClient, private toastService: ToastrService, - private route: ActivatedRoute + private route: ActivatedRoute, + private router: Router, ) {} ngOnInit() { @@ -77,33 +90,81 @@ export class PartitionAssistantComponent implements OnInit { partitionNumber: partition.partitionNumber, size: this.convertBytesToGB(partition.size), memoryUsage: partition.memoryUsage, - type: partition.type || partition.filesystem || 'NTFS', + partitionCode: partition.partitionCode, + filesystem: partition.filesystem, sizeBytes: partition.size, format: false, color: '#1f1b91', - percentage: 0 + percentage: 0, + removed: false }); } }); disksMap.forEach((disk, diskNumber) => { this.updatePartitionPercentages(disk.partitions, disk.totalDiskSize); + + const used = this.calculateUsedSpace(disk.partitions); + const percentage = (used / disk.totalDiskSize) * 100; + const chartData = this.generateChartData(disk.partitions); + this.disks.push({ diskNumber: diskNumber, totalDiskSize: disk.totalDiskSize, - partitions: disk.partitions + partitions: disk.partitions, + chartData: chartData, + used: used, + percentage: percentage }); }); + this.disks.forEach((disk) => { + this.updatePartitionPercentages(disk.partitions, disk.totalDiskSize); + }); } convertBytesToGB(bytes: number): number { return bytes } + activePartitions(diskNumber: number) { + const disk = this.disks.find((d) => d.diskNumber === diskNumber); + if (disk) { + return disk.partitions.filter((partition) => !partition.removed); + } + + return null; + } + updatePartitionPercentages(partitions: Partition[], totalDiskSize: number) { + let totalUsedPercentage = 0; + partitions.forEach((partition) => { - partition.percentage = (partition.size / totalDiskSize) * 100 + partition.percentage = Number(((partition.size / totalDiskSize) * 100).toFixed(2)) + totalUsedPercentage += partition.percentage; }); + + const unusedPercentage = 100 - totalUsedPercentage; + + const chartData = partitions + .filter((partition) => !partition.removed) + .map((partition) => ({ + name: `Partición ${partition.partitionNumber}`, + value: partition.percentage, + color: partition.color, + })); + + if (unusedPercentage > 0) { + chartData.push({ + name: 'Espacio sin usar', + value: unusedPercentage, + color: '#ffffff' + }); + } + + const disk = this.disks.find(d => d.partitions === partitions); + if (disk) { + disk.chartData = chartData; + } } addPartition(diskNumber: number) { @@ -112,21 +173,26 @@ export class PartitionAssistantComponent implements OnInit { if (disk) { const remainingGB = this.getRemainingGB(disk.partitions, disk.totalDiskSize); if (remainingGB > 0) { + const removedPartitions = disk.partitions.filter((p) => !p.removed); const maxPartitionNumber = - disk.partitions.length > 0 ? Math.max(...disk.partitions.map((p) => p.partitionNumber)) : 0; + removedPartitions.length > 0 ? Math.max(...removedPartitions.map((p) => p.partitionNumber)) : 0; const newPartitionNumber = maxPartitionNumber + 1; + disk.partitions.push({ partitionNumber: newPartitionNumber, size: 0, - type: 'NTFS', + partitionCode: 'LINUX', + filesystem: 'EXT4', memoryUsage: 0, sizeBytes: 0, format: false, color: '#' + Math.floor(Math.random() * 16777215).toString(16), - percentage: 0 + percentage: 0, + removed: false }); this.updatePartitionPercentages(disk.partitions, disk.totalDiskSize); + this.updateDiskChart(disk); } else { this.errorMessage = 'No hay suficiente espacio libre en el disco para crear una nueva partición.'; } @@ -138,7 +204,9 @@ export class PartitionAssistantComponent implements OnInit { if (disk) { const partition = disk.partitions[index]; const remainingGB = this.getRemainingGB(disk.partitions, disk.totalDiskSize) + partition.size; - + if (partition) { + partition.percentage = Number(((size / disk.totalDiskSize) * 100).toFixed(2)); + } if (size > remainingGB) { this.errorMessage = `El tamaño de la partición no puede superar el espacio libre (${remainingGB.toFixed(2)} GB).`; } else { @@ -148,41 +216,16 @@ export class PartitionAssistantComponent implements OnInit { partition.percentage = (size / disk.totalDiskSize) * 100; this.updatePartitionPercentages(disk.partitions, disk.totalDiskSize); + this.updateDiskChart(disk); } } } - updatePartitionPercentage(diskNumber: number, index: number, percentage: number) { - const disk = this.disks.find((d) => d.diskNumber === diskNumber); - if (disk) { - const partition = disk.partitions[index]; - - const newSizeMB = (percentage / 100) * disk.totalDiskSize; - - const totalPercentage = disk.partitions.reduce((sum, part) => sum + (part === partition ? percentage : part.percentage), 0); - - if (totalPercentage > 100) { - this.errorMessage = 'El tamaño total en porcentaje de las particiones no puede exceder el 100%'; - partition.percentage = 100 - (totalPercentage - percentage); - } else { - this.errorMessage = ''; - partition.percentage = percentage; - partition.size = newSizeMB; - } - } - } - - - getRemainingGB(partitions: Partition[], totalDiskSize: number): number { const totalUsedGB = partitions.reduce((acc, partition) => acc + partition.size, 0); return Math.max(0, totalDiskSize - totalUsedGB); } - isPartitionModified(original: any, current: Partition): boolean { - return this.convertBytesToGB(original.size) !== current.size || original.type !== current.type; - } - getModifiedOrNewPartitions() { const modifiedPartitions: any[] = []; @@ -191,22 +234,11 @@ export class PartitionAssistantComponent implements OnInit { const originalPartition = this.originalPartitions.find( (p) => p.diskNumber === disk.diskNumber && p.partitionNumber === partition.partitionNumber ); - - if (!originalPartition) { - modifiedPartitions.push({ - partition, - diskNumber: disk.diskNumber, - partitionNumber: partition.partitionNumber, - isNew: true - }); - } else if (this.isPartitionModified(originalPartition, partition)) { - modifiedPartitions.push({ - partition, - diskNumber: disk.diskNumber, - partitionNumber: partition.partitionNumber, - isNew: false - }); - } + modifiedPartitions.push({ + partition, + diskNumber: disk.diskNumber, + partitionNumber: partition.partitionNumber, + }); }); }); @@ -219,6 +251,7 @@ export class PartitionAssistantComponent implements OnInit { return totalPartitionSize > disk.totalDiskSize; }); + console.log(invalidDisks); if (invalidDisks.length > 0) { this.errorMessage = 'El tamaño total de las particiones en uno o más discos excede el tamaño total del disco.'; return; @@ -233,63 +266,78 @@ export class PartitionAssistantComponent implements OnInit { return; } - modifiedPartitions.forEach(({ partition, diskNumber, partitionNumber, isNew }) => { + modifiedPartitions.forEach(({ partition, diskNumber, partitionNumber }) => { const payload = { diskNumber: diskNumber, partitionNumber: partitionNumber, memoryUsage: partition.memoryUsage, size: partition.size, - filesystem: partition.type, - client: `/clients/${this.clientId}` + partitionCode: partition.partitionCode, + filesystem: partition.filesystem, + client: `/clients/${this.clientId}`, + uuid: partition.uuid, + removed: partition.removed || false, + format: partition.format || false, }; - if (isNew) { - this.http.post(this.apiUrl, payload).subscribe( - (response) => { - this.toastService.success('Partición creada exitosamente'); - window.location.reload(); - }, - (error) => { - console.error('Error al crear la partición:', error); - this.toastService.error('Error al crear la partición'); - } - ); - } else if (partition.uuid) { - const patchUrl = `${this.apiUrl}/${partition.uuid}`; - this.http.patch(patchUrl, payload).subscribe( - (response) => { - this.toastService.success('Partición actualizada exitosamente'); - window.location.reload(); - }, - (error) => { - console.error('Error al actualizar la partición:', error); - this.toastService.error('Error al actualizar la partición'); - } - ); - } + this.newPartitions.push(payload); }); + + if (this.newPartitions.length > 0) { + const bulkPayload = { partitions: this.newPartitions }; + + this.http.post(this.apiUrl, bulkPayload).subscribe( + (response) => { + this.toastService.success('Particiones creadas exitosamente'); + this.router.navigate(['/traces']); + }, + (error) => { + console.error('Error al crear las particiones:', error); + this.toastService.error('Error al crear las particiones'); + } + ); + } } removePartition(diskNumber: number, partition: Partition) { const disk = this.disks.find((d) => d.diskNumber === diskNumber); - if (disk) { - const index = disk.partitions.indexOf(partition); - if (index !== -1) { - disk.partitions.splice(index, 1); - this.updatePartitionPercentages(disk.partitions, disk.totalDiskSize); - - if (partition.uuid) { - const deleteUrl = `${this.apiUrl}/${partition.uuid}`; - this.http.delete(deleteUrl).subscribe( - (response) => { - this.toastService.success('Partición eliminada exitosamente'); - window.location.reload(); - }, - (error) => {} - ); - } + const partitionToRemove = disk.partitions.find((p) => p === partition); + if (partitionToRemove) { + partitionToRemove.removed = true; } + this.updateDiskChart(disk); + this.updatePartitionPercentages(disk.partitions, disk.totalDiskSize); } } + + updatePartitionSizeFromPercentage(diskNumber: number, partitionIndex: number, percentage: number): void { + const disk = this.disks.find(d => d.diskNumber === diskNumber); + if (disk) { + const partition = disk.partitions[partitionIndex]; + if (partition) { + partition.size = (disk.totalDiskSize * percentage) / 100; + } + this.updateDiskChart(disk); + this.updatePartitionPercentages(disk.partitions, disk.totalDiskSize); + } + } + + calculateUsedSpace(partitions: Partition[]): number { + return partitions.reduce((acc, partition) => acc + partition.size, 0); + } + + generateChartData(partitions: Partition[]): any[] { + return partitions.map((partition) => ({ + name: `Partición ${partition.partitionNumber}`, + value: partition.percentage, + color: partition.color + })); + } + + updateDiskChart(disk: any) { + disk.chartData = this.generateChartData(disk.partitions); + disk.used = this.calculateUsedSpace(disk.partitions); + disk.percentage = (disk.used / disk.totalDiskSize) * 100; + } } diff --git a/ogWebconsole/src/app/shared/constants/filesystem-types.ts b/ogWebconsole/src/app/shared/constants/filesystem-types.ts new file mode 100644 index 0000000..dfbcc56 --- /dev/null +++ b/ogWebconsole/src/app/shared/constants/filesystem-types.ts @@ -0,0 +1,26 @@ +export const FILESYSTEM_TYPES = [ + { id: 1, name: 'EMPTY', description: 'EMPTY', active: 0 }, + { id: 2, name: 'CACHE', description: 'CACHE', active: 0 }, + { id: 3, name: 'BTRFS', description: 'BTRFS', active: 0 }, + { id: 4, name: 'EXT2', description: 'EXT2', active: 0 }, + { id: 5, name: 'EXT3', description: 'EXT3', active: 0 }, + { id: 6, name: 'EXT4', description: 'EXT4', active: 0 }, + { id: 7, name: 'FAT12', description: 'FAT12', active: 0 }, + { id: 8, name: 'FAT16', description: 'FAT16', active: 0 }, + { id: 9, name: 'FAT32', description: 'FAT32', active: 0 }, + { id: 10, name: 'HFS', description: 'HFS', active: 0 }, + { id: 11, name: 'HFSPLUS', description: 'HFSPLUS', active: 0 }, + { id: 12, name: 'JFS', description: 'JFS', active: 0 }, + { id: 13, name: 'NTFS', description: 'NTFS', active: 0 }, + { id: 14, name: 'REISERFS', description: 'REISERFS', active: 0 }, + { id: 15, name: 'REISER4', description: 'REISER4', active: 0 }, + { id: 16, name: 'UFS', description: 'UFS', active: 0 }, + { id: 17, name: 'XFS', description: 'XFS', active: 0 }, + { id: 18, name: 'EXFAT', description: 'EXFAT', active: 0 }, + { id: 19, name: 'LINUX-SWAP', description: 'LINUX-SWAP', active: 0 }, + { id: 20, name: 'F2FS', description: 'F2FS', active: 0 }, + { id: 21, name: 'NILFS2', description: 'NILFS2', active: 0 }, + { id: 22, name: '0', description: '', active: 0 }, + { id: 23, name: 'LINUX-LVM', description: '', active: 0 }, + { id: 24, name: 'ISO9660', description: '', active: 0 }, +]; diff --git a/ogWebconsole/src/app/shared/constants/partition-types.ts b/ogWebconsole/src/app/shared/constants/partition-types.ts new file mode 100644 index 0000000..1b900ac --- /dev/null +++ b/ogWebconsole/src/app/shared/constants/partition-types.ts @@ -0,0 +1,72 @@ +export const PARTITION_TYPES = [ + { code: 0, name: 'EMPTY', active: false }, + { code: 1, name: 'FAT12', active: true }, + { code: 5, name: 'EXTENDED', active: false }, + { code: 6, name: 'FAT16', active: true }, + { code: 7, name: 'NTFS', active: true }, + { code: 11, name: 'FAT32', active: true }, + { code: 17, name: 'HFAT12', active: true }, + { code: 22, name: 'HFAT16', active: true }, + { code: 23, name: 'HNTFS', active: true }, + { code: 27, name: 'HFAT32', active: true }, + { code: 130, name: 'LINUX-SWAP', active: false }, + { code: 131, name: 'LINUX', active: true }, + { code: 142, name: 'LINUX-LVM', active: true }, + { code: 165, name: 'FREEBSD', active: true }, + { code: 166, name: 'OPENBSD', active: true }, + { code: 169, name: 'NETBSD', active: true }, + { code: 175, name: 'HFS', active: true }, + { code: 190, name: 'SOLARIS-BOOT', active: true }, + { code: 191, name: 'SOLARIS', active: true }, + { code: 202, name: 'CACHE', active: false }, + { code: 218, name: 'DATA', active: true }, + { code: 238, name: 'GPT', active: false }, + { code: 239, name: 'EFI', active: true }, + { code: 251, name: 'VMFS', active: true }, + { code: 253, name: 'LINUX-RAID', active: true }, + { code: 1792, name: 'WINDOWS', active: true }, + { code: 3073, name: 'WIN-RESERV', active: true }, + { code: 9984, name: 'WIN-RECOV', active: true }, + { code: 32512, name: 'CHROMEOS-KRN', active: true }, + { code: 32513, name: 'CHROMEOS', active: true }, + { code: 32514, name: 'CHROMEOS-RESERV', active: true }, + { code: 33280, name: 'LINUX-SWAP', active: false }, + { code: 33536, name: 'LINUX', active: true }, + { code: 33537, name: 'LINUX-RESERV', active: true }, + { code: 33538, name: 'LINUX', active: true }, + { code: 36352, name: 'LINUX-LVM', active: true }, + { code: 42240, name: 'FREEBSD-DISK', active: false }, + { code: 42241, name: 'FREEBSD-BOOT', active: true }, + { code: 42242, name: 'FREEBSD-SWAP', active: false }, + { code: 42243, name: 'FREEBSD', active: true }, + { code: 42244, name: 'FREEBSD', active: true }, + { code: 43265, name: 'NETBSD-SWAP', active: false }, + { code: 43266, name: 'NETBSD', active: true }, + { code: 43267, name: 'NETBSD', active: true }, + { code: 43268, name: 'NETBSD', active: true }, + { code: 43269, name: 'NETBSD', active: true }, + { code: 43270, name: 'NETBSD-RAID', active: true }, + { code: 43776, name: 'HFS-BOOT', active: true }, + { code: 44800, name: 'HFS', active: true }, + { code: 44801, name: 'HFS-RAID', active: true }, + { code: 44802, name: 'HFS-RAID', active: true }, + { code: 48640, name: 'SOLARIS-BOOT', active: true }, + { code: 48896, name: 'SOLARIS', active: true }, + { code: 48897, name: 'SOLARIS', active: true }, + { code: 48898, name: 'SOLARIS-SWAP', active: false }, + { code: 48899, name: 'SOLARIS-DISK', active: true }, + { code: 48900, name: 'SOLARIS', active: true }, + { code: 48901, name: 'SOLARIS', active: true }, + { code: 51712, name: 'CACHE', active: false }, + { code: 61184, name: 'EFI', active: true }, + { code: 61185, name: 'MBR', active: false }, + { code: 61186, name: 'BIOS-BOOT', active: false }, + { code: 64256, name: 'VMFS', active: true }, + { code: 64257, name: 'VMFS-RESERV', active: true }, + { code: 64258, name: 'VMFS-KRN', active: true }, + { code: 64768, name: 'LINUX-RAID', active: true }, + { code: 65535, name: 'UNKNOWN', active: true }, + { code: 65536, name: 'LVM-LV', active: true }, + { code: 65552, name: 'ZFS-VOL', active: true }, + { code: 39, name: 'HNTFS-WINRE', active: true }, +];