diff --git a/doc/config_options.txt b/doc/config_options.txt index 3dc0813b93c..d33b8cf97da 100644 --- a/doc/config_options.txt +++ b/doc/config_options.txt @@ -16,6 +16,156 @@ User keys can be used in search. ``` + +```{config:option} boot.priority devices-disk +:required: "no" +:shortdesc: "Boot priority for VMs (higher value boots first)" +:type: "integer" + +``` + +```{config:option} ceph.cluster_name devices-disk +:default: "`ceph`" +:required: "no" +:shortdesc: "The cluster name of the Ceph cluster (required for Ceph or CephFS sources)" +:type: "string" + +``` + +```{config:option} ceph.user_name devices-disk +:default: "`admin`" +:required: "no" +:shortdesc: "The user name of the Ceph cluster (required for Ceph or CephFS sources)" +:type: "string" + +``` + +```{config:option} initial.* devices-disk +:required: "no" +:shortdesc: "Initial volume configuration for instance root disk devices" +:type: "string" + +``` + +```{config:option} io.bus devices-disk +:default: "`virtio-scsi`" +:required: "no" +:shortdesc: "Only for VMs: Override the bus for the device (`nvme`, `virtio-blk`, or `virtio-scsi`)" +:type: "string" + +``` + +```{config:option} io.cache devices-disk +:default: "`none`" +:required: "no" +:shortdesc: "Only for VMs: Override the caching mode for the device (`none`, `writeback` or `unsafe`)" +:type: "string" + +``` + +```{config:option} limits.max devices-disk +:required: "no" +:shortdesc: "I/O limit in byte/s or IOPS for both read and write (same as setting both `limits.read` and `limits.write`)" +:type: "string" + +``` + +```{config:option} limits.read devices-disk +:required: "no" +:shortdesc: "I/O limit in byte/s (various suffixes supported, see {ref}`instances-limit-units`) or in IOPS (must be suffixed with `iops`) - see also {ref}`storage-configure-IO`" +:type: "string" + +``` + +```{config:option} limits.write devices-disk +:required: "no" +:shortdesc: "I/O limit in byte/s (various suffixes supported, see {ref}`instances-limit-units`) or in IOPS (must be suffixed with `iops`) - see also {ref}`storage-configure-IO`" +:type: "string" + +``` + +```{config:option} path devices-disk +:required: "yes" +:shortdesc: "Path inside the instance where the disk will be mounted (only for containers)" +:type: "string" + +``` + +```{config:option} pool devices-disk +:required: "no" +:shortdesc: "The storage pool to which the disk device belongs (only applicable for storage volumes managed by Incus)" +:type: "string" + +``` + +```{config:option} propagation devices-disk +:required: "no" +:shortdesc: "Controls how a bind-mount is shared between the instance and the host (can be one of `private`, the default, or `shared`, `slave`, `unbindable`, `rshared`, `rslave`, `runbindable`, `rprivate`; see the Linux Kernel [shared subtree](https://www.kernel.org/doc/Documentation/filesystems/sharedsubtree.txt) documentation for a full explanation)" +:type: "string" + +``` + +```{config:option} raw.mount.options devices-disk +:required: "no" +:shortdesc: "File system specific mount options" +:type: "string" + +``` + +```{config:option} readonly devices-disk +:default: "`false`" +:required: "no" +:shortdesc: "Controls whether to make the mount read-only" +:type: "bool" + +``` + +```{config:option} recursive devices-disk +:default: "`false`" +:required: "no" +:shortdesc: "Controls whether to recursively mount the source path" +:type: "bool" + +``` + +```{config:option} required devices-disk +:default: "`true`" +:required: "no" +:shortdesc: "Controls whether to fail if the source doesn't exist" +:type: "bool" + +``` + +```{config:option} shift devices-disk +:default: "`false`" +:required: "no" +:shortdesc: "Sets up a shifting overlay to translate the source UID/GID to match the instance (only for containers)" +:type: "bool" + +``` + +```{config:option} size devices-disk +:required: "no" +:shortdesc: "Disk size in bytes (various suffixes supported, see {ref}`instances-limit-units`) - only supported for the `rootfs` (`/`)" +:type: "string" + +``` + +```{config:option} size.state devices-disk +:required: "no" +:shortdesc: "Same as `size`, but applies to the file-system volume used for saving runtime state in VMs" +:type: "string" + +``` + +```{config:option} source devices-disk +:required: "yes" +:shortdesc: "Source of a file system or block device (see {ref}`devices-disk-types` for details)" +:type: "string" + +``` + + ```{config:option} gid devices-unix-char-block :default: "0" diff --git a/doc/reference/devices_disk.md b/doc/reference/devices_disk.md index ba43ce460f1..352742a5a61 100644 --- a/doc/reference/devices_disk.md +++ b/doc/reference/devices_disk.md @@ -99,25 +99,8 @@ Note that you cannot use initial volume configurations with custom volume option `disk` devices have the following device options: -Key | Type | Default | Required | Description -:-- | :-- | :-- | :-- | :-- -`boot.priority` | integer | - | no | Boot priority for VMs (higher value boots first) -`ceph.cluster_name` | string | `ceph` | no | The cluster name of the Ceph cluster (required for Ceph or CephFS sources) -`ceph.user_name` | string | `admin` | no | The user name of the Ceph cluster (required for Ceph or CephFS sources) -`initial.*` | n/a | - | no | {ref}`devices-disk-initial-config` that allows setting unique configurations independent of default storage pool settings -`io.bus` | string | `virtio-scsi` | no | Only for VMs: Override the bus for the device (`nvme`, `virtio-blk`, or `virtio-scsi`) -`io.cache` | string | `none` | no | Only for VMs: Override the caching mode for the device (`none`, `writeback` or `unsafe`) -`limits.max` | string | - | no | I/O limit in byte/s or IOPS for both read and write (same as setting both `limits.read` and `limits.write`) -`limits.read` | string | - | no | I/O limit in byte/s (various suffixes supported, see {ref}`instances-limit-units`) or in IOPS (must be suffixed with `iops`) - see also {ref}`storage-configure-IO` -`limits.write` | string | - | no | I/O limit in byte/s (various suffixes supported, see {ref}`instances-limit-units`) or in IOPS (must be suffixed with `iops`) - see also {ref}`storage-configure-IO` -`path` | string | - | yes | Path inside the instance where the disk will be mounted (only for containers) -`pool` | string | - | no | The storage pool to which the disk device belongs (only applicable for storage volumes managed by Incus) -`propagation` | string | - | no | Controls how a bind-mount is shared between the instance and the host (can be one of `private`, the default, or `shared`, `slave`, `unbindable`, `rshared`, `rslave`, `runbindable`, `rprivate`; see the Linux Kernel [shared subtree](https://www.kernel.org/doc/Documentation/filesystems/sharedsubtree.txt) documentation for a full explanation) -`raw.mount.options` | string | - | no | File system specific mount options -`readonly` | bool | `false` | no | Controls whether to make the mount read-only -`recursive` | bool | `false` | no | Controls whether to recursively mount the source path -`required` | bool | `true` | no | Controls whether to fail if the source doesn't exist -`shift` | bool | `false` | no | Sets up a shifting overlay to translate the source UID/GID to match the instance (only for containers) -`size` | string | - | no | Disk size in bytes (various suffixes supported, see {ref}`instances-limit-units`) - only supported for the `rootfs` (`/`) -`size.state` | string | - | no | Same as `size`, but applies to the file-system volume used for saving runtime state in VMs -`source` | string | - | yes | Source of a file system or block device (see {ref}`devices-disk-types` for details) +% Include content from [../config_options.txt](../config_options.txt) +```{include} ../config_options.txt + :start-after: + :end-before: +``` diff --git a/internal/server/device/disk.go b/internal/server/device/disk.go index 5e745038ac9..32af83ef318 100644 --- a/internal/server/device/disk.go +++ b/internal/server/device/disk.go @@ -176,26 +176,166 @@ func (d *disk) validateConfig(instConf instance.ConfigReader) error { } rules := map[string]func(string) error{ - "required": validate.Optional(validate.IsBool), - "optional": validate.Optional(validate.IsBool), // "optional" is deprecated, replaced by "required". - "readonly": validate.Optional(validate.IsBool), - "recursive": validate.Optional(validate.IsBool), - "shift": validate.Optional(validate.IsBool), - "source": validate.IsAny, - "limits.read": validate.IsAny, - "limits.write": validate.IsAny, - "limits.max": validate.IsAny, - "size": validate.Optional(validate.IsSize), - "size.state": validate.Optional(validate.IsSize), - "pool": validate.IsAny, - "propagation": validatePropagation, + // gendoc:generate(entity=devices, group=disk, key=required) + // + // --- + // type: bool + // default: `true` + // required: no + // shortdesc: Controls whether to fail if the source doesn't exist + "required": validate.Optional(validate.IsBool), + "optional": validate.Optional(validate.IsBool), // "optional" is deprecated, replaced by "required". + + // gendoc:generate(entity=devices, group=disk, key=readonly) + // + // --- + // type: bool + // default: `false` + // required: no + // shortdesc: Controls whether to make the mount read-only + "readonly": validate.Optional(validate.IsBool), + + // gendoc:generate(entity=devices, group=disk, key=recursive) + // + // --- + // type: bool + // default: `false` + // required: no + // shortdesc: Controls whether to recursively mount the source path + "recursive": validate.Optional(validate.IsBool), + + // gendoc:generate(entity=devices, group=disk, key=shift) + // + // --- + // type: bool + // default: `false` + // required: no + // shortdesc: Sets up a shifting overlay to translate the source UID/GID to match the instance (only for containers) + "shift": validate.Optional(validate.IsBool), + + // gendoc:generate(entity=devices, group=disk, key=source) + // + // --- + // type: string + // required: yes + // shortdesc: Source of a file system or block device (see {ref}`devices-disk-types` for details) + "source": validate.IsAny, + + // gendoc:generate(entity=devices, group=disk, key=limits.read) + // + // --- + // type: string + // required: no + // shortdesc: I/O limit in byte/s (various suffixes supported, see {ref}`instances-limit-units`) or in IOPS (must be suffixed with `iops`) - see also {ref}`storage-configure-IO` + "limits.read": validate.IsAny, + + // gendoc:generate(entity=devices, group=disk, key=limits.write) + // + // --- + // type: string + // required: no + // shortdesc: I/O limit in byte/s (various suffixes supported, see {ref}`instances-limit-units`) or in IOPS (must be suffixed with `iops`) - see also {ref}`storage-configure-IO` + "limits.write": validate.IsAny, + + // gendoc:generate(entity=devices, group=disk, key=limits.max) + // + // --- + // type: string + // required: no + // shortdesc: I/O limit in byte/s or IOPS for both read and write (same as setting both `limits.read` and `limits.write`) + "limits.max": validate.IsAny, + + // gendoc:generate(entity=devices, group=disk, key=size) + // + // --- + // type: string + // required: no + // shortdesc: Disk size in bytes (various suffixes supported, see {ref}`instances-limit-units`) - only supported for the `rootfs` (`/`) + "size": validate.Optional(validate.IsSize), + + // gendoc:generate(entity=devices, group=disk, key=size.state) + // + // --- + // type: string + // required: no + // shortdesc: Same as `size`, but applies to the file-system volume used for saving runtime state in VMs + "size.state": validate.Optional(validate.IsSize), + + // gendoc:generate(entity=devices, group=disk, key=pool) + // + // --- + // type: string + // required: no + // shortdesc: The storage pool to which the disk device belongs (only applicable for storage volumes managed by Incus) + "pool": validate.IsAny, + + // gendoc:generate(entity=devices, group=disk, key=propagation) + // + // --- + // type: string + // required: no + // shortdesc: Controls how a bind-mount is shared between the instance and the host (can be one of `private`, the default, or `shared`, `slave`, `unbindable`, `rshared`, `rslave`, `runbindable`, `rprivate`; see the Linux Kernel [shared subtree](https://www.kernel.org/doc/Documentation/filesystems/sharedsubtree.txt) documentation for a full explanation) + "propagation": validatePropagation, + + // gendoc:generate(entity=devices, group=disk, key=raw.mount.options) + // + // --- + // type: string + // required: no + // shortdesc: File system specific mount options "raw.mount.options": validate.IsAny, + + // gendoc:generate(entity=devices, group=disk, key=ceph.cluster_name) + // + // --- + // type: string + // default: `ceph` + // required: no + // shortdesc: The cluster name of the Ceph cluster (required for Ceph or CephFS sources) "ceph.cluster_name": validate.IsAny, - "ceph.user_name": validate.IsAny, - "boot.priority": validate.Optional(validate.IsUint32), - "path": validate.IsAny, - "io.cache": validate.Optional(validate.IsOneOf("none", "writeback", "unsafe")), - "io.bus": validate.Optional(validate.IsOneOf("nvme", "virtio-blk", "virtio-scsi")), + + // gendoc:generate(entity=devices, group=disk, key=ceph.user_name) + // + // --- + // type: string + // default: `admin` + // required: no + // shortdesc: The user name of the Ceph cluster (required for Ceph or CephFS sources) + "ceph.user_name": validate.IsAny, + + // gendoc:generate(entity=devices, group=disk, key=boot.priority) + // + // --- + // type: integer + // required: no + // shortdesc: Boot priority for VMs (higher value boots first) + "boot.priority": validate.Optional(validate.IsUint32), + + // gendoc:generate(entity=devices, group=disk, key=path) + // + // --- + // type: string + // required: yes + // shortdesc: Path inside the instance where the disk will be mounted (only for containers) + "path": validate.IsAny, + + // gendoc:generate(entity=devices, group=disk, key=io.cache) + // + // --- + // type: string + // default: `none` + // required: no + // shortdesc: Only for VMs: Override the caching mode for the device (`none`, `writeback` or `unsafe`) + "io.cache": validate.Optional(validate.IsOneOf("none", "writeback", "unsafe")), + + // gendoc:generate(entity=devices, group=disk, key=io.bus) + // + // --- + // type: string + // default: `virtio-scsi` + // required: no + // shortdesc: Only for VMs: Override the bus for the device (`nvme`, `virtio-blk`, or `virtio-scsi`) + "io.bus": validate.Optional(validate.IsOneOf("nvme", "virtio-blk", "virtio-scsi")), } err := d.config.Validate(rules) @@ -422,6 +562,13 @@ func (d *disk) validateConfig(instConf instance.ConfigReader) error { // storage driver. Currently initial configuration is only applicable to root disk devices. initialConfig := make(map[string]string) for k, v := range d.config { + + // gendoc:generate(entity=devices, group=disk, key=initial.*) + // + // --- + // type: string + // required: no + // shortdesc: Initial volume configuration for instance root disk devices prefix, newKey, found := strings.Cut(k, "initial.") if found && prefix == "" { initialConfig[newKey] = v diff --git a/internal/server/metadata/configuration.json b/internal/server/metadata/configuration.json index cf5d1986c80..febfbc006b5 100644 --- a/internal/server/metadata/configuration.json +++ b/internal/server/metadata/configuration.json @@ -22,6 +22,178 @@ } }, "devices": { + "disk": { + "keys": [ + { + "boot.priority": { + "longdesc": "", + "required": "no", + "shortdesc": "Boot priority for VMs (higher value boots first)", + "type": "integer" + } + }, + { + "ceph.cluster_name": { + "default": "`ceph`", + "longdesc": "", + "required": "no", + "shortdesc": "The cluster name of the Ceph cluster (required for Ceph or CephFS sources)", + "type": "string" + } + }, + { + "ceph.user_name": { + "default": "`admin`", + "longdesc": "", + "required": "no", + "shortdesc": "The user name of the Ceph cluster (required for Ceph or CephFS sources)", + "type": "string" + } + }, + { + "initial.*": { + "longdesc": "", + "required": "no", + "shortdesc": "Initial volume configuration for instance root disk devices", + "type": "string" + } + }, + { + "io.bus": { + "default": "`virtio-scsi`", + "longdesc": "", + "required": "no", + "shortdesc": "Only for VMs: Override the bus for the device (`nvme`, `virtio-blk`, or `virtio-scsi`)", + "type": "string" + } + }, + { + "io.cache": { + "default": "`none`", + "longdesc": "", + "required": "no", + "shortdesc": "Only for VMs: Override the caching mode for the device (`none`, `writeback` or `unsafe`)", + "type": "string" + } + }, + { + "limits.max": { + "longdesc": "", + "required": "no", + "shortdesc": "I/O limit in byte/s or IOPS for both read and write (same as setting both `limits.read` and `limits.write`)", + "type": "string" + } + }, + { + "limits.read": { + "longdesc": "", + "required": "no", + "shortdesc": "I/O limit in byte/s (various suffixes supported, see {ref}`instances-limit-units`) or in IOPS (must be suffixed with `iops`) - see also {ref}`storage-configure-IO`", + "type": "string" + } + }, + { + "limits.write": { + "longdesc": "", + "required": "no", + "shortdesc": "I/O limit in byte/s (various suffixes supported, see {ref}`instances-limit-units`) or in IOPS (must be suffixed with `iops`) - see also {ref}`storage-configure-IO`", + "type": "string" + } + }, + { + "path": { + "longdesc": "", + "required": "yes", + "shortdesc": "Path inside the instance where the disk will be mounted (only for containers)", + "type": "string" + } + }, + { + "pool": { + "longdesc": "", + "required": "no", + "shortdesc": "The storage pool to which the disk device belongs (only applicable for storage volumes managed by Incus)", + "type": "string" + } + }, + { + "propagation": { + "longdesc": "", + "required": "no", + "shortdesc": "Controls how a bind-mount is shared between the instance and the host (can be one of `private`, the default, or `shared`, `slave`, `unbindable`, `rshared`, `rslave`, `runbindable`, `rprivate`; see the Linux Kernel [shared subtree](https://www.kernel.org/doc/Documentation/filesystems/sharedsubtree.txt) documentation for a full explanation)", + "type": "string" + } + }, + { + "raw.mount.options": { + "longdesc": "", + "required": "no", + "shortdesc": "File system specific mount options", + "type": "string" + } + }, + { + "readonly": { + "default": "`false`", + "longdesc": "", + "required": "no", + "shortdesc": "Controls whether to make the mount read-only", + "type": "bool" + } + }, + { + "recursive": { + "default": "`false`", + "longdesc": "", + "required": "no", + "shortdesc": "Controls whether to recursively mount the source path", + "type": "bool" + } + }, + { + "required": { + "default": "`true`", + "longdesc": "", + "required": "no", + "shortdesc": "Controls whether to fail if the source doesn't exist", + "type": "bool" + } + }, + { + "shift": { + "default": "`false`", + "longdesc": "", + "required": "no", + "shortdesc": "Sets up a shifting overlay to translate the source UID/GID to match the instance (only for containers)", + "type": "bool" + } + }, + { + "size": { + "longdesc": "", + "required": "no", + "shortdesc": "Disk size in bytes (various suffixes supported, see {ref}`instances-limit-units`) - only supported for the `rootfs` (`/`)", + "type": "string" + } + }, + { + "size.state": { + "longdesc": "", + "required": "no", + "shortdesc": "Same as `size`, but applies to the file-system volume used for saving runtime state in VMs", + "type": "string" + } + }, + { + "source": { + "longdesc": "", + "required": "yes", + "shortdesc": "Source of a file system or block device (see {ref}`devices-disk-types` for details)", + "type": "string" + } + } + ] + }, "unix-char-block": { "keys": [ {