Skip to content

Commit

Permalink
feat(web): storage config model (#1718)
Browse files Browse the repository at this point in the history
The UI components should be agnostic to the structure and complexity of
the storage config.

Add a Config model to deal with the storage config. The model generates
objects (e.g., `Drive`, `Partition`, etc) from the config data. This
makes easier for the UI components to read and modify the config data.
  • Loading branch information
joseivanlopez authored Nov 11, 2024
2 parents fe69e94 + 26f5fe7 commit 7c83b1f
Show file tree
Hide file tree
Showing 18 changed files with 1,540 additions and 157 deletions.
247 changes: 124 additions & 123 deletions rust/agama-lib/share/storage.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"drives": {
"description": "Drives (disks, BIOS RAIDs and multipath devices).",
"type": "array",
"items": { "$ref": "#/$defs/drive" }
"items": { "$ref": "#/$defs/driveElement" }
},
"volumeGroups": {
"description": "LVM volume groups.",
Expand All @@ -37,7 +37,7 @@
}
}
},
"drive": {
"driveElement": {
"anyOf": [
{ "$ref": "#/$defs/formattedDrive" },
{ "$ref": "#/$defs/partitionedDrive" }
Expand All @@ -49,7 +49,7 @@
"additionalProperties": false,
"required": ["filesystem"],
"properties": {
"search": { "$ref": "#/$defs/search" },
"search": { "$ref": "#/$defs/searchElement" },
"alias": { "$ref": "#/$defs/alias" },
"encryption": { "$ref": "#/$defs/encryption" },
"filesystem": { "$ref": "#/$defs/filesystem" }
Expand All @@ -59,10 +59,105 @@
"type": "object",
"additionalProperties": false,
"properties": {
"search": { "$ref": "#/$defs/search" },
"search": { "$ref": "#/$defs/searchElement" },
"alias": { "$ref": "#/$defs/alias" },
"ptableType": { "$ref": "#/$defs/ptableType" },
"partitions": { "$ref": "#/$defs/partitions" }
"partitions": {
"type": "array",
"items": { "$ref": "#/$defs/partitionElement" }
}
}
},
"ptableType": {
"description": "Partition table type.",
"$comment": "The partition table is created only if all the current partitions are deleted.",
"enum": ["gpt", "msdos", "dasd"]
},
"partitionElement": {
"anyOf": [
{ "$ref": "#/$defs/simpleVolumesGenerator" },
{ "$ref": "#/$defs/advancedPartitionsGenerator" },
{ "$ref": "#/$defs/regularPartition" },
{ "$ref": "#/$defs/partitionToDelete" },
{ "$ref": "#/$defs/PartitionToDeleteIfNeeded" }
]
},
"simpleVolumesGenerator": {
"description": "Automatically creates the default or mandatory volumes configured by the selected product.",
"type": "object",
"additionalProperties": false,
"required": ["generate"],
"properties": {
"generate": {
"enum": ["default", "mandatory"]
}
}
},
"advancedPartitionsGenerator": {
"description": "Creates the default or mandatory partitions configured by the selected product.",
"type": "object",
"additionalProperties": false,
"required": ["generate"],
"properties": {
"generate": {
"type": "object",
"additionalProperties": false,
"required": ["partitions"],
"properties": {
"partitions": {
"enum": ["default", "mandatory"]
},
"encryption": { "$ref": "#/$defs/encryption" }
}
}
}
},
"regularPartition": {
"type": "object",
"additionalProperties": false,
"properties": {
"search": { "$ref": "#/$defs/searchElement" },
"alias": { "$ref": "#/$defs/alias" },
"id": {
"title": "Partition id",
"enum": [
"linux",
"swap",
"lvm",
"raid",
"esp",
"prep",
"bios_boot"
]
},
"size": { "$ref": "#/$defs/size" },
"encryption": { "$ref": "#/$defs/encryption" },
"filesystem": { "$ref": "#/$defs/filesystem" }
}
},
"partitionToDelete": {
"type": "object",
"additionalProperties": false,
"required": ["delete", "search"],
"properties": {
"search": { "$ref": "#/$defs/searchElement" },
"delete": {
"description": "Delete the partition.",
"const": true
}
}
},
"PartitionToDeleteIfNeeded": {
"type": "object",
"additionalProperties": false,
"required": ["deleteIfNeeded", "search"],
"properties": {
"search": { "$ref": "#/$defs/searchElement" },
"deleteIfNeeded": {
"description": "Delete the partition if needed to make space.",
"const": true
},
"size": { "$ref": "#/$defs/size" }
}
},
"volumeGroup": {
Expand All @@ -77,42 +172,22 @@
},
"extentSize": { "$ref": "#/$defs/sizeValue" },
"physicalVolumes": {
"title": "Physical volumes",
"description": "Devices to use as physical volumes.",
"type": "array",
"items": {
"anyOf": [
{ "$ref": "#/$defs/alias" },
{ "$ref": "#/$defs/simplePhysicalVolumesGenerator" },
{ "$ref": "#/$defs/advancedPhysicalVolumesGenerator" }
]
}
"items": { "$ref": "#/$defs/physicalVolumeElement" }
},
"logicalVolumes": {
"title": "Logical volumes",
"type": "array",
"items": {
"anyOf": [
{ "$ref": "#/$defs/simpleVolumesGenerator" },
{ "$ref": "#/$defs/advancedLogicalVolumesGenerator" },
{ "$ref": "#/$defs/logicalVolume" },
{ "$ref": "#/$defs/thinPoolLogicalVolume" },
{ "$ref": "#/$defs/thinLogicalVolume" }
]
}
"items": { "$ref": "#/$defs/logicalVolumeElement" }
}
}
},
"simpleVolumesGenerator": {
"description": "Automatically creates the default or mandatory volumes configured by the selected product.",
"type": "object",
"additionalProperties": false,
"required": ["generate"],
"properties": {
"generate": {
"enum": ["default", "mandatory"]
}
}
"physicalVolumeElement": {
"anyOf": [
{ "$ref": "#/$defs/alias" },
{ "$ref": "#/$defs/simplePhysicalVolumesGenerator" },
{ "$ref": "#/$defs/advancedPhysicalVolumesGenerator" }
]
},
"simplePhysicalVolumesGenerator": {
"description": "Automatically creates the needed physical volumes in the indicated devices.",
Expand Down Expand Up @@ -146,6 +221,15 @@
}
}
},
"logicalVolumeElement": {
"anyOf": [
{ "$ref": "#/$defs/simpleVolumesGenerator" },
{ "$ref": "#/$defs/advancedLogicalVolumesGenerator" },
{ "$ref": "#/$defs/logicalVolume" },
{ "$ref": "#/$defs/thinPoolLogicalVolume" },
{ "$ref": "#/$defs/thinLogicalVolume" }
]
},
"advancedLogicalVolumesGenerator": {
"description": "Automatically creates the default or mandatory logical volumes configured by the selected product.",
"type": "object",
Expand Down Expand Up @@ -226,102 +310,18 @@
"minimum": 1,
"maximum": 128
},
"ptableType": {
"description": "Partition table type.",
"$comment": "The partition table is created only if all the current partitions are deleted.",
"enum": ["gpt", "msdos", "dasd"]
},
"partitions": {
"type": "array",
"items": {
"anyOf": [
{ "$ref": "#/$defs/simpleVolumesGenerator" },
{ "$ref": "#/$defs/advancedPartitionsGenerator" },
{ "$ref": "#/$defs/partition" },
{ "$ref": "#/$defs/partitionToDelete" },
{ "$ref": "#/$defs/PartitionToDeleteIfNeeded" }
]
}
},
"advancedPartitionsGenerator": {
"description": "Creates the default or mandatory partitions configured by the selected product.",
"type": "object",
"additionalProperties": false,
"required": ["generate"],
"properties": {
"generate": {
"type": "object",
"additionalProperties": false,
"required": ["partitions"],
"properties": {
"partitions": {
"enum": ["default", "mandatory"]
},
"encryption": { "$ref": "#/$defs/encryption" }
}
}
}
},
"partition": {
"type": "object",
"additionalProperties": false,
"properties": {
"search": { "$ref": "#/$defs/search" },
"alias": { "$ref": "#/$defs/alias" },
"id": {
"title": "Partition id",
"enum": [
"linux",
"swap",
"lvm",
"raid",
"esp",
"prep",
"bios_boot"
]
},
"size": { "$ref": "#/$defs/size" },
"encryption": { "$ref": "#/$defs/encryption" },
"filesystem": { "$ref": "#/$defs/filesystem" }
}
},
"partitionToDelete": {
"type": "object",
"additionalProperties": false,
"required": ["delete", "search"],
"properties": {
"search": { "$ref": "#/$defs/search" },
"delete": {
"description": "Delete the partition.",
"const": true
}
}
},
"PartitionToDeleteIfNeeded": {
"type": "object",
"additionalProperties": false,
"required": ["deleteIfNeeded", "search"],
"properties": {
"search": { "$ref": "#/$defs/search" },
"deleteIfNeeded": {
"description": "Delete the partition if needed to make space.",
"const": true
},
"size": { "$ref": "#/$defs/size" }
}
},
"search": {
"searchElement": {
"anyOf": [
{ "$ref": "#/$defs/searchAll" },
{ "$ref": "#/$defs/searchByName" },
{ "$ref": "#/$defs/simpleSearchAll" },
{ "$ref": "#/$defs/simpleSearchByName" },
{ "$ref": "#/$defs/advancedSearch" }
]
},
"searchAll": {
"simpleSearchAll": {
"description": "Shortcut to match all devices if there is any (equivalent to specify no conditions and to skip the entry if no device is found).",
"const": "*"
},
"searchByName": {
"simpleSearchByName": {
"descrition": "Search by device name",
"type": "string",
"examples": ["/dev/vda", "/dev/disk/by-id/ata-WDC_WD3200AAKS-75L9"]
Expand All @@ -337,7 +337,7 @@
"additionalProperties": false,
"required": ["name"],
"properties": {
"name": { "$ref": "#/$defs/searchByName" }
"name": { "$ref": "#/$defs/simpleSearchByName" }
}
},
"max": {
Expand Down Expand Up @@ -398,6 +398,7 @@
"anyOf": [
{ "$ref": "#/$defs/sizeValue" },
{
"title": "Size current",
"description": "The current size of the device.",
"const": "current"
}
Expand Down
6 changes: 4 additions & 2 deletions web/src/api/storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,11 @@ import { config } from "~/api/storage/types";
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const probe = (): Promise<any> => post("/api/storage/probe");

const fetchConfig = (): Promise<config.Config> => get("/api/storage/config");
const fetchConfig = (): Promise<config.Config | undefined> =>
get("/api/storage/config").then((config) => config.storage);

const fetchSolvedConfig = (): Promise<config.Config> => get("/api/storage/solved_config");
const fetchSolvedConfig = (): Promise<config.Config | undefined> =>
get("/api/storage/solved_config").then((config) => config.storage);

const setConfig = (config: config.Config) => put("/api/storage/config", config);

Expand Down
Loading

0 comments on commit 7c83b1f

Please sign in to comment.