I am very pleased that the LXD UI works with Incus, because this means that the Incus and LXD REST APIs are still mostly compatible. I hope it remains so. You had indicated here not to count on such compatibility and you specifically mentioned that “For the lxd-to-incus migration tool, we import both the incus and lxd clients in the same binary, specifically so we don’t rely on the incus client to talk to LXD or vice-versa.”
I would like to see more things being compatible between LXD and Incus. There may be other tools besides the LXD UI that could work in both products. I develop such a tool and I use it to launch LXD and Incus containers the same way. I resorted to writing my own API with the things that I need from each product, and implemented it for Incus and for LXD using their respective Go packages.
A central piece of the API is the Go package github.com/lxc/incus/shared/api for Incus and github.com/canonical/lxd/shared/api for LXD. I wish parts of this package could eventually be shared between the two projects and become a sort of common API (like the S3 API which is shared across many products).
Comparing api/instance.go between Incus and LXD, I see that they differ mostly in comments. The LXD version has comments that include “LXD” and “lxd”, while the Incus version has more generic terms:
// InstancePut represents the modifiable fields of an instance.
// InstancePut represents the modifiable fields of a LXD instance.
One more substantial difference is the deprecated LXD ContainerOnly field, that has been removed from Incus. This means that instance.go cannot currently be shared between the two products in Go. But the JSON representations of the instance.go types are still compatible between Incus and LXD. Is there, or can there be a specification of the API that both products can adhere to?