I don’t have a lot of experience with QEMU, so I may be misunderstanding what you are trying to do.
In general Nomad allocations have their own isolated file system, since different allocations are not guaranteed to run in the same host.
The artifact block is also restricted to place files only in the allocation file system to avoid security issues where a job is able to place arbitrary (and potentially malicious) files somewhere in the host file system.
If you want to share data between allocations that are in the same host, you can use host volumes. If the allocations are in different hosts you will need to setup some mechanism to share these files, like NFS for example. If you are running in a cloud environment, you may be able to use CSI as well.
I am using a shared drive which is mounted on each node to /srv/nomad/images.
The issue so far was that each client created its own allocation file system. This ended up in the image being downloaded to /srv/nomad/images/clientX/allocs/alloc/image instead of (what I expected) /srv/nomad/images since I added
config {
image_paths = ["/srv/nomad/images"]
}
}
(But this was a false and silly assumption on my side.)
I will follow your advice and dig more into host volumes.
The ideal case for me would be:
Use a shared drive for qemu base images.
Download the base image in case it is not present.
Start qemu from that base, but store the snapshot/overlay image in the alloc file system.
Delete the snapshot once the job is done.
Keep the base image (Which leads to the fact that the shared folder needs to be cleaned up manually from time to time, which should not be too hard as in the ideal case the needed images would just be re-downloaded again)
job "example" {
# ...
group "example" {
# ...
volume "images" {
type = "host"
source = "images" # This value must match the volume name in your client config.
}
# ...
task "example" {
driver = "qemu"
config {
image_path = "/srv/nomad/images/..."
# ...
}
volume_mount {
volume = "images" # This value must match the name of your volume in this job.
destination = "/srv/nomad/images"
}
}
}
}
This is probably the trickiest bit. In theory you could use an artifact to download the images, but due to the order in which artifacts are downloaded and volumes are mounted, the volume will actually mount over the downloaded artifact.
You could maybe write a custom script that runs as a prestart task in your job that checks for the image and downloads it if not available. Not a great solution though
This is where my lack of knowledge of QEMU trips me. You would need to check where the snapshot/overlays are being stored.
If the snapshot is being store in the allocation directory, then this happens automatically (not really when the job is done, but when the Nomad garbage collector runs).
Maybe this could be another custom script running as a system job? The tricky part would be making sure that no active allocation is using the image before removing it.
I hope these help, if not, feel free to ask more questions
After some time I had time and support of a colleague to come back to this issue.
Everything seems to be more complicated than expected:
The qemu task driver has no volume mounting capabilities
As you already mentioned:
Because the task driver mounts the volume, it is not possible to have artifact , template , or dispatch_payload blocks write to a volume.
We can not make use of the exec driver in combination with the host volume since we have a NFS share mounted (for reasons) and nomad fails to chown (when running as root)
Even if we could download the image to the shared directory I am not sure if it is even possible to link the overlay file to the base image, which should be located inside the alloc-dir. My understanding here is:
shared_images_volume gets mounted into /mnt/shared_storage/clientX/alloc-dir/images
curl download the “base-image-to-be-downloaded.qcow2”
Even if the shared_images_volume is unmounted after the task is finished the “base-image-to-be-downloaded.qcow2” remains accassible under /mnt/shared_storage/shared_images/base-image-to-be-downloaded.qcow2
Resulting behavior artifact stanca
“base-image-to-be-downloaded.qcow2” is downloaded into /mnt/shared_storage/clientX/alloc-dir/images/base-image-to-be-downloaded.qcow2 by the artifact stanca
Once the task driver starts it will mount the shared_images_volume into /mnt/shared_storage/clientX/alloc-dir/images and overwrite the “original” /mnt/shared_storage/clientX/alloc-dir/images with /mnt/shared_storage/clientX/alloc-dir/images <--- shared_images_volume
Remaining question
Is it possible from the Nomad storage layout that files from a “native” alloc directory can symlink/reference files from a mounted volume or from an image_paths like in the case of qemu plugin.