ganeti-extstorage-interface(7)
β¨ NAME β¨
okay so bestie, this is the ganeti-extstorage-interface manual β version 3.1.0~rc2 β and it's literally the Specifications for ExtStorage providers. no cap, this is the blueprint. π
π DESCRIPTION π
So the way Ganeti handles external shared storage? It's giving each external shared storage hardware type its own ExtStorage provider. periodt.
An ExtStorage provider is literally just a set of files β executable scripts and text files β chillin' inside a directory named after the provider. π
That directory has to be present across all nodes of a nodegroup (Ganeti does not replicate it, bestie, so you gotta handle that yourself). Only then can Ganeti actually use the provider for that nodegroup β that's what makes it valid.
Also, the external shared storage hardware itself needs to be accessible by every node in that nodegroup too. no pressure. π
π REFERENCE π
There are eight required files: create, attach, detach, remove, grow, setinfo, verify (all executables) and parameters.list (a text file). That's the whole starter pack, bestie. β¨
Then there are three optional files: open, close, and snapshot β all executables. They're not mandatory, but they're iconic if you implement them. π
π Common environment π
Every command gets its input through environment variables. There's a common set of variables exported for all commands, and some commands get extra ones on top. Also heads up: all counts are zero-based β so the first one is 0, not 1. iykyk. π’
Since Ganeti version 2.5, the environment gets cleaned up before it's passed to scripts. So your scripts do not inherit the environment that the ganeti node daemon was started with. If you're depending on any non-Ganeti environment variables, you're gonna need to define or source them yourself, appropriately. that's just the rules. π
VOL_NAMEβ The name of the volume. It's unique for Ganeti and Ganeti uses it to refer to a specific volume inside the external storage. Its format isUUID.ext.diskXwhereUUIDis produced by Ganeti and is unique inside the Ganeti context.Xis the number of the disk count.VOL_SIZEβ Available only to thecreateandgrowscripts. It's the volume's size in mebibytes.VOL_NEW_SIZEβ Available only to thegrowscript. It declares the new size of the volume after grow (in mebibytes). To find the amount of grow, the script should calculate the numberVOL_NEW_SIZE - VOL_SIZE.EXTPnameβ Each ExtStorage parameter (see below) gets exported in its own variable, prefixed withEXTP_, and upper-cased. For example, afromsnapparameter will be exported asEXTP_FROMSNAP.VOL_METADATAβ Available only to thesetinfoscript. A string containing metadata to be associated with the volume. Currently, Ganeti sets this value tooriginstname+XwhereXis the instance's name.VOL_CNAMEβ The human-readable name of the Disk config object (optional).VOL_UUIDβ The uuid of the Disk config object.VOL_SNAPSHOT_NAMEβ The name of the volume's snapshot.VOL_SNAPSHOT_SIZEβ The size of the volume's snapshot.VOL_OPEN_EXCLUSIVEβ Whether the volume will be opened for exclusive access or not. This will beFalse(denoting shared access) during migration.
π₯ EXECUTABLE SCRIPTS π₯
β¨ create β¨
The create command is your go-to for making a brand new volume inside the external storage. slay.
VOL_NAME is the volume's name, and it should be unique. After creation, Ganeti will refer to this volume by this name for every other action. so don't lose it.
Ganeti produces this name dynamically and makes sure it's unique inside the Ganeti context. So please don't manually provision extra volumes inside the external storage with this type of name β that's a one-way ticket to conflicts and possible loss of data. not the vibe. π
The VOL_SIZE variable tells you the size of the new volume to create, in mebibytes.
If the script ends successfully, a new volume of size VOL_SIZE should exist inside the external storage β e.g. a lun inside a NAS appliance.
The script returns 0 on success. periodt.
β¨ attach β¨
This command makes an already-created volume visible to the physical node that's gonna host the instance. How? By mapping the already-provisioned volume to a block device inside the host node. it's giving matchmaker energy. π
The VOL_NAME variable is the volume to map.
After a successful attach, the script returns a string to its stdout β the full path of the block device the volume is mapped to. e.g. /dev/dummy1.
When attach returns, that path should be a valid block device on the host node. no cap.
The attach script should be idempotent if the volume is already mapped. If the requested volume is already mapped, just return to stdout the path that's already mapped to. easy.
If the storage tech also supports userspace access to volumes β like, say, the QEMU Hypervisor can see an RBD volume using its embedded driver for the RBD protocol β then the provider can return extra lines denoting the available userspace access URIs per hypervisor. The URI should be in this format: <hypervisor>:<uri>. For example, a RADOS provider should return kvm:rbd:<pool>/<volume name> on the second line of stdout, right after the local block device path (e.g. /dev/rbd1).
So if the access disk parameter is userspace for the ext disk template, the QEMU command ends up having file=<URI> in the -drive option. that's the tea. π΅
And if the storage tech supports only userspace access to volumes, then the first line of stdout should be an empty line β that denotes a local block device is not available. If you return neither a block device nor a URI, Ganeti will complain. so don't do that. π
β¨ detach β¨
This command unmaps an already-mapped volume from the host node. detach undoes everything attach did β by unmapping the requested volume from the block device it's mapped to. it's the breakup era. π
VOL_NAME is the volume to unmap.
detach doesn't touch the volume itself. It just unmaps it from the host node. The volume keeps existing inside the external storage β it's just not accessible by that node anymore. This script returns nothing to stdout.
The detach script should be idempotent if the volume is already unmapped. If the volume isn't mapped, the script doesn't do anything at all. periodt.
The script returns 0 on success.
β¨ remove β¨
This command removes an existing volume from the external storage. And bestie, it's permanent β the volume and all its data get deleted from inside the external storage. no take-backs. π
VOL_NAME is the volume to remove.
The script returns 0 on success.
β¨ grow β¨
This command grows an existing volume in the external storage. glow up time. β¨
VOL_NAME is the volume to grow.
VOL_SIZE is the current volume's size (in mebibytes). VOL_NEW_SIZE is the final size after the volume has been grown (in mebibytes).
The amount of grow can be easily calculated by the script, and it's:
grow_amount = VOL_NEW_SIZE - VOL_SIZE (in mebibytes)
Ganeti ensures that: VOL_NEW_SIZE > VOL_SIZE. so no shrinking, bestie.
If the script returns successfully, the volume inside the external storage will have a new size of VOL_NEW_SIZE. But heads up: this isn't immediately reflected to the instance's disk. See gnt-instance grow for more details on when the running instance becomes aware of its grown disk. patience, bestie. π§
The script returns 0 on success.
β¨ setinfo β¨
This script adds metadata to an existing volume. It's helpful when you need to keep an external, Ganeti-independent mapping between instances and volumes β primarily for recovery reasons. This is provider specific, and the provider's author chooses whether and how to implement it. If you don't wanna implement this feature, you can literally just exit with 0 β it won't harm the overall functionality of the provider. no stress. π
The VOL_METADATA variable contains the metadata of the volume.
Currently, Ganeti sets this value to originstname+X where X is the instance's name.
The script returns 0 on success.
β¨ verify β¨
The verify script checks the consistency of the external parameters (ext-params) β see below. The command should take one or more arguments denoting what checks to perform, and return a proper exit code depending on whether the validation failed or succeeded. it's giving quality control. π
Currently, Ganeti doesn't invoke this script, but it should still be present for future use and for consistency with gnt-os-interface's verify script. manifesting that future. β¨
The script should return 0 on success.
β¨ snapshot β¨
The snapshot script takes a snapshot of the given volume. say cheese. πΈ
The VOL_SNAPSHOT_NAME and VOL_SNAPSHOT_SIZE variables contain the name and size of the snapshot you're about to create.
Currently this operation is used only during gnt-backup export, and Ganeti sets those values to VOL_NAME.snap and VOL_SIZE respectively (see above).
The script returns 0 on success.
Please note: this script is optional, and not all providers should implement it. But of course, if it's not present, instance backup export will not be supported for that provider. so choose wisely. π«Ά
β¨ open β¨
The open script opens the given volume.
This makes the volume ready for I/O. it's giving pre-game. π₯
The VOL_OPEN_EXCLUSIVE variable says whether the volume will be opened for exclusive access or not. It's True by default and False (denoting shared access) during migration.
The script returns 0 on success.
Please note: this script is optional and not all providers should implement it.
β¨ close β¨
The close script closes the given volume.
This disables I/O on the volume. nap time. π΄
The script returns 0 on success.
Please note: this script is optional and not all providers should implement it.
π TEXT FILES π
π parameters.list π
This file declares the parameters your ExtStorage provider supports β one parameter per line, with name and description separated by space and/or tab. For example:
fromsnap Snapshot name to create the volume from
nas_ip The IP of the NAS appliance
Then you can use those parameters during instance add like this:
# gnt-instance add --disk=0:fromsnap="file_name",nas_ip="1.2.3.4" ...
β¨ EXAMPLES β¨
Okay bestie, real talk β these examples all assume you've already got two ExtStorage providers installed and thriving: pvdr1 and pvdr2. That's the whole vibe. Let's go π
Adding a new instance with a 10G first disk from pvdr1 and a 20G second disk from pvdr2:
# gnt-instance add -t ext --disk=0:size=10G,provider=pvdr1
--disk=1:size=20G,provider=pvdr2
Adding a new instance with a 5G first disk from provider pvdr1, and also passing it the prm1, prm2 parameters with the corresponding values val1, val2:
# gnt-instance add -t ext
--disk=0:size=5G,provider=pvdr1,prm1=val1,prm2=val2
Modifying an existing instance of disk type ext by adding a new 30G disk from provider pvdr2:
# gnt-instance modify --disk 1:add,size=30G,provider=pvdr2 <instance>
Modifying an existing instance of disk type ext by adding 2 new disks, from different providers, and passing one parameter for the first one:
# gnt-instance modify --disk 2:add,size=3G,provider=pvdr1,prm1=val1
--disk 3:add,size=5G,provider=pvdr2
<instance>
π NOTES π
Backwards compatibility
The ExtStorage Interface made its debut in Ganeti 2.7. Ganeti 2.7 and up is compatible with the ExtStorage Interface β so if you're on anything β₯ 2.7, you're golden π
Common behaviour
All the scripts should display a usage message when they get called with a wrong number of arguments, or when the first argument is -h or --help. Simple as that, no cap.
π REPORTING BUGS π
Found a bug? Spill it to the project's issue tracker, or slide into the Ganeti mailing list and talk to the developers directly. They wanna hear from you fr fr π«Ά
π SEE ALSO π
Ganeti overview and specifications:
ganeti(7)β the general overview, the main character πganeti-os-interface(7)β guest OS definitionsganeti-extstorage-interface(7)β external storage providers
Ganeti commands:
gnt-cluster(8)β cluster-wide commandsgnt-job(8)β job-related commandsgnt-node(8)β node-related commandsgnt-instance(8)β instance commandsgnt-os(8)β guest OS commandsgnt-storage(8)β storage commandsgnt-group(8)β node group commandsgnt-backup(8)β instance import/export commandsgnt-debug(8)β debug commands
Ganeti daemons:
ganeti-watcher(8)β automatic instance restarterganeti-cleaner(8)β job queue cleanerganeti-noded(8)β node daemonganeti-rapi(8)β remote API daemon
Ganeti htools:
htools(1)β generic binaryhbal(1)β cluster balancerhspace(1)β capacity calculationhail(1)β IAllocator pluginhscan(1)β data gatherer from remote clustershinfo(1)β cluster information printermon-collector(7)β data collectors interface
βοΈ COPYRIGHT βοΈ
Copyright (C) 2006-2015 Google Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
and that's the whole page, bestie!! π This one's from Ganeti, version 3.1.0~rc2, and it's filed under ganeti-extstorage-interface(7) β so now you know exactly where to find it when you inevitably forget everything I just said ππ go forth and build those disks, you absolute icon π
β¨π
π¦ where this page comes from
- debian trixie: ganeti-3.1 3.1.0~rc2-3 Β· BSD-2-Clause
- ubuntu questing: ganeti-3.1 3.1.0~rc2-4
- ubuntu resolute: ganeti-3.1 3.1.0~rc2-4build1 Β· BSD-2-Clause
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms