Hi,
(disclaimer : sort of complete ruby noob ahead )
I’ve spent a few hours to get foreman (1.18) to kickstart a VM using image based provisioning on libvirt + ceph.
I know ceph isn’t quite supported using foreman because of fog probably, but as you know, small workaround exist to allow creating volumes inside such pools.
As a summary, to get image based provisioning to work, I faced a few issues - some of which are out of foreman scope I presume :
- 1st : it appears that when foreman (fog) creates the ISOuser data file, it is uploaded to the 1st pool available in libvirt. Or at least in 1.18. Looks like 1st means 1st in alphabetical order. And since for me that was a ceph pool, libvirt “volUpload” failed because that is not supported by rbd pools. Even if I chose to use an NFS pool for the VM and the backing image…
=> workaround : either hack into fog to force the pool where the ISO is uploaded (which I did for now), or probably better, just make sure the “1st” pool that’s available is an NFS or posix pool (which I’ll try later).
=> I fear that’s sort of out of scope for foreman, but poking around foreman code, I also saw that some fog things are bypassed so maybe you’ll know how to get around…
- 2nd issue, and that one is foreman related : for image based provisioning (using qcow2), the foreman code just “vol.save” the volume with a backing_volume attribute pointing to the base image, see here : vol.save line
The issue here is that this actually also works on rbd pools, but just creates an empty volume which is unrelated to the backing volume. it took me quite a number of retries to find out that for RBD, it is clone_volume which works - but I also found out that this then completely duplicates volumes on NFS pools… so I ended up with this code which is implementing that only for rbd, leaving the code as is for other pool types :
if vol.backing_volume.present?
pool = storage_pools.select { |p| p.name == vol.backing_volume.pool_name}.first
# there is at least the volume we are cloning in that pool, look at it :
pool_vol = pool.volumes.first
pool_xml = client.client.lookup_storage_pool_by_name(pool.name).xml_desc
if pool_xml.match /<pool type='rbd'>/
vol.backing_volume.clone_volume(vol.name)
vol.path = vol.backing_volume.path.gsub(vol.backing_volume.name,vol.name)
else
vol.save
end
end
I tried to use fog’s .xml or .xml_desc pool attributes, but they were either empty or unavailable so I resorted to using the libvirt connection instead.
Would you be kind enough to include this fix/enhancement/rfe into the libvirt compute model ?
Thanks