return f"{self.source}:{self.target}" if self.target else f"{self.source}"
+class DriveFlag(StrEnum):
+ persist = enum.auto()
+
+
@dataclasses.dataclass(frozen=True)
class Drive:
id: str
directory: Optional[Path]
options: Optional[str]
file_id: str
- persist: bool
+ flags: list[DriveFlag]
# We use negative numbers for specifying special constants
if not is_valid_filename(id):
die(f"Unsupported path character in drive id '{id}'")
+ flag_parser = make_enum_parser(DriveFlag)
+ flag_list = p.split(",") if len(parts) > 5 and (p := parts[5]) else []
+
return Drive(
id=id,
size=parse_bytes(parts[1]),
directory=parse_path(p) if len(parts) > 2 and (p := parts[2]) else None,
options=p if len(parts) > 3 and (p := parts[3]) else None,
file_id=p if len(parts) > 4 and (p := parts[4]) else id,
- persist=parse_boolean(p) if len(parts) > 5 and (p := parts[5]) else False,
+ flags=[flag_parser(f) for f in flag_list],
)
directory=Path(d["Directory"]) if d.get("Directory") else None,
options=d.get("Options"),
file_id=d.get("FileId", d["Id"]),
- persist=d.get("Persist", False),
+ flags=[DriveFlag(f) for f in d.get("Flags", [])],
)
)
ConfigFeature,
ConsoleMode,
Drive,
+ DriveFlag,
Firmware,
Network,
OutputFormat,
def finalize_drive(drive: Drive) -> Iterator[Path]:
with contextlib.ExitStack() as stack:
file: IO[bytes]
- if drive.persist:
+ if DriveFlag.persist in drive.flags:
path = Path(drive.directory or "/var/tmp") / f"mkosi-drive-{drive.id}"
file = path.open("a+b")
else:
`Drives=`, `--drive=`
: Add a drive. Takes a colon-delimited string of format
- `<id>:<size>[:<directory>[:<options>[:<file-id>[:<persist>]]]]`. `id` specifies
+ `<id>:<size>[:<directory>[:<options>[:<file-id>[:<flags>]]]]`. `id` specifies
the ID assigned to the drive. This can be used as the `drive=`
property in various **qemu** devices. `size` specifies the size of the
drive. This takes a size in bytes. Additionally, the suffixes `K`, `M`
backing the drive. If unset, this defaults to the drive ID.
Drives with the same file ID will share the backing file.
The directory and size of the file will be determined from the first drive with a given file ID.
- `persist` takes a boolean value and determines whether the drive will be persisted across **qemu** invocations.
- Enabling persistence also prevents suffixing the filename with a random string.
- The file backing the drive will always be available under `/<directory>/mkosi-drive-<file-id>`
- You can skip values by setting them to the empty string, specifying e.g. `myfs:1G::::yes`
+ `flags` takes a comma-separated list of drive flags which currently only supports `persist`.
+ `persist` determines whether the drive will be persisted across **qemu** invocations.
+ The files backing the drives will be created with the schema
+ `/<directory>/mkosi-drive-<file-id>`.
+ You can skip values by setting them to the empty string, specifying e.g. `myfs:1G::::persist`
will create a persistent drive under `/var/tmp/mkosi-drive-myfs`.
**Example usage:**
ConsoleMode,
DocFormat,
Drive,
+ DriveFlag,
Firmware,
Incremental,
InitrdProfile,
{
"Directory": "/foo/bar",
"FileId": "red",
+ "Flags": [],
"Id": "abc",
"Options": "abc,qed",
- "Persist": false,
"Size": 200
},
{
"Directory": null,
"FileId": "wcd",
+ "Flags": [],
"Id": "abc",
"Options": "",
- "Persist": false,
"Size": 200
},
{
"Directory": null,
"FileId": "bla",
+ "Flags": [
+ "persist"
+ ],
"Id": "abc",
"Options": "",
- "Persist": true,
"Size": 200
}
],
dependencies=["dep1"],
distribution=Distribution.fedora,
drives=[
- Drive("abc", 200, Path("/foo/bar"), "abc,qed", "red", False),
- Drive("abc", 200, None, "", "wcd", False),
- Drive("abc", 200, None, "", "bla", True),
+ Drive("abc", 200, Path("/foo/bar"), "abc,qed", "red", []),
+ Drive("abc", 200, None, "", "wcd", []),
+ Drive("abc", 200, None, "", "bla", [DriveFlag.persist]),
],
environment_files=[],
environment={"foo": "foo", "BAR": "BAR", "Qux": "Qux"},