[libvirt] ESXi support

Hello everyone I am really new to libvirt and I have to use it with ESXi. I was writing code for listing the virtual machines in a ESXi server. If I connect me with the virsh to the ESXi server, it works. But since I can not create any certificates on the server (ESXi does not have any console...) I have to use the no_verify option (esx://host/?no_verify=1) I want to do the same with the API, but when I use this string in the uri parameter of the following code conn = virConnectOpenAuth(uri, virConnectAuthPtrDefault, 0); the system returns "libvir: Remote error : Cannot access CA certificate '/etc/pki/CA/cacert.pem': No such file or directory No connection to hypervisor" What method can I use to be able to connect to the server by ignoring the missing certificate? Another question is: Are there any example codes for using ESX(i), because as I said I am really new with libvirt and I did not find any examples. Thanks a lot for your help. Adrian

2010/7/3 adrian wyssen <wyssenadrian@gmail.com>:
Hello everyone I am really new to libvirt and I have to use it with ESXi. I was writing code for listing the virtual machines in a ESXi server. If I connect me with the virsh to the ESXi server, it works. But since I can not create any certificates on the server (ESXi does not have any console...) I have to use the no_verify option (esx://host/?no_verify=1) I want to do the same with the API, but when I use this string in the uri parameter of the following code conn = virConnectOpenAuth(uri, virConnectAuthPtrDefault, 0); the system returns "libvir: Remote error : Cannot access CA certificate '/etc/pki/CA/cacert.pem': No such file or directory No connection to hypervisor" What method can I use to be able to connect to the server by ignoring the missing certificate? Another question is: Are there any example codes for using ESX(i), because as I said I am really new with libvirt and I did not find any examples. Thanks a lot for your help. Adrian
The certificates libvirt is complaining about have nothing to do with the certificates for ESX(i). By default libvirt uses a TLS connection to a remote libvirtd (a daemon). This daemon is used to allow remote management of hypervisors that don't have remote capabilities on their own, like QEMU. For ESX(i) this daemon is not necessary, because libvirt directly uses the remote SOAP API provided by the ESX(i) server. By default libvirt uses a HTTPS connection to the ESX(i) server. Proper HTTPS requires correctly configured SSL certificates, this certificates are different from the certificates for libvirt's TLS connection to libvirtd. In case of a default ESX(i) installation the ESX(i) server has auto-generated self-signed certificates. And in general those cannot be verified by your client because your client doesn't have the cacert.pem that corresponds to the private key that the ESX(i) server used to sign the auto-generated self-signed certificates. That's the reason why libvirt allows you to disable those certificate check by appending ?no_verify=1 to the URI. libvirt complains here about the for the TLS connection to a remote libvirtd. This is a bit cryptic error that appears because libvirt don't know what to do with the URI you gave to it and as last option it tries to connect to a libvirtd on the remote server hoping that the libvirtd there knows what to do with the URI. The typical reason why this happens is that your libvirt is build without ESX support. But you said 'virsh -c esx://host/?no_verify=1'. Therefore, I assume that's not the case here. Could it be that you have multiple version of libvirt installed? One that has ESX support enabled and is used by virsh and one that has ESX support disabled and that your program links against? Regarding example code: There is no special ESX libvirt example code, because libvirt is designed to provide hypervisor independent API. You can take a look at the examples directory. For example the hellolibvirt example: ./examples/hellolibvirt/hellolibvirt esx://host/?no_verify=1 If that still gives you that certificate error, try: LIBVIRT_DEBUG=1 LIBVIRT_LOG_OUTPUTS=1:stderr ./examples/hellolibvirt/hellolibvirt esx://host/?no_verify=1 It should list lines like 13:13:23.189: debug : virRegisterDriver:927 : registering ESX as driver 5 ... 13:13:23.189: debug : do_open:1242 : trying driver 5 (ESX) ... If there is no virRegisterDriver or do_open line regarding ESX then your libvirt is build without ESX support. But i wonder why virsh works then. Recent (unreleased) libvirt has better error reporting for this situation and tells you when you try to use an URI scheme that was disabled, instead of reporting unexpected certificate errors. Matthias

Hi Matthias, Thanks for your excellent explanation. It works now with the hellolibvirt example. I still have a problem. It don't want to be forced to enter a password. So I tried to set the URI to esx://user:pass@ESX_host/?no_verify=1. But that does not work. It anyway asks for password. Providing the user in the URI works, but not the password. I know that this is not secure at all passing the password in the URI, but the script has to be able to run automatically. Is there another way to provide username and password, for example by using virConnectOpenAuth() not with the virConnectAuthPtrDefault but with an array containing the username and password already? Remember, I can not exchange public key or something, since I use ESXi 4.0. Thank you so much for your help. Adrian 2010/7/3 Matthias Bolte <matthias.bolte@googlemail.com>
2010/7/3 adrian wyssen <wyssenadrian@gmail.com>:
Hello everyone I am really new to libvirt and I have to use it with ESXi. I was writing code for listing the virtual machines in a ESXi server. If I connect me with the virsh to the ESXi server, it works. But since I can not create any certificates on the server (ESXi does not have any console...) I have to use the no_verify option (esx://host/?no_verify=1) I want to do the same with the API, but when I use this string in the uri parameter of the following code conn = virConnectOpenAuth(uri, virConnectAuthPtrDefault, 0); the system returns "libvir: Remote error : Cannot access CA certificate '/etc/pki/CA/cacert.pem': No such file or directory No connection to hypervisor" What method can I use to be able to connect to the server by ignoring the missing certificate? Another question is: Are there any example codes for using ESX(i), because as I said I am really new with libvirt and I did not find any examples. Thanks a lot for your help. Adrian
The certificates libvirt is complaining about have nothing to do with the certificates for ESX(i).
By default libvirt uses a TLS connection to a remote libvirtd (a daemon). This daemon is used to allow remote management of hypervisors that don't have remote capabilities on their own, like QEMU. For ESX(i) this daemon is not necessary, because libvirt directly uses the remote SOAP API provided by the ESX(i) server.
By default libvirt uses a HTTPS connection to the ESX(i) server. Proper HTTPS requires correctly configured SSL certificates, this certificates are different from the certificates for libvirt's TLS connection to libvirtd. In case of a default ESX(i) installation the ESX(i) server has auto-generated self-signed certificates. And in general those cannot be verified by your client because your client doesn't have the cacert.pem that corresponds to the private key that the ESX(i) server used to sign the auto-generated self-signed certificates.
That's the reason why libvirt allows you to disable those certificate check by appending ?no_verify=1 to the URI.
libvirt complains here about the for the TLS connection to a remote libvirtd. This is a bit cryptic error that appears because libvirt don't know what to do with the URI you gave to it and as last option it tries to connect to a libvirtd on the remote server hoping that the libvirtd there knows what to do with the URI.
The typical reason why this happens is that your libvirt is build without ESX support. But you said 'virsh -c esx://host/?no_verify=1'. Therefore, I assume that's not the case here.
Could it be that you have multiple version of libvirt installed? One that has ESX support enabled and is used by virsh and one that has ESX support disabled and that your program links against?
Regarding example code: There is no special ESX libvirt example code, because libvirt is designed to provide hypervisor independent API.
You can take a look at the examples directory. For example the hellolibvirt example:
./examples/hellolibvirt/hellolibvirt esx://host/?no_verify=1
If that still gives you that certificate error, try:
LIBVIRT_DEBUG=1 LIBVIRT_LOG_OUTPUTS=1:stderr ./examples/hellolibvirt/hellolibvirt esx://host/?no_verify=1
It should list lines like
13:13:23.189: debug : virRegisterDriver:927 : registering ESX as driver 5 ... 13:13:23.189: debug : do_open:1242 : trying driver 5 (ESX) ...
If there is no virRegisterDriver or do_open line regarding ESX then your libvirt is build without ESX support. But i wonder why virsh works then.
Recent (unreleased) libvirt has better error reporting for this situation and tells you when you try to use an URI scheme that was disabled, instead of reporting unexpected certificate errors.
Matthias

2010/7/5 adrian wyssen <wyssenadrian@gmail.com>:
Hi Matthias, Thanks for your excellent explanation. It works now with the hellolibvirt example. I still have a problem. It don't want to be forced to enter a password. So I tried to set the URI to esx://user:pass@ESX_host/?no_verify=1. But that does not work. It anyway asks for password. Providing the user in the URI works, but not the password. I know that this is not secure at all passing the password in the URI, but the script has to be able to run automatically. Is there another way to provide username and password, for example by using virConnectOpenAuth() not with the virConnectAuthPtrDefault but with an array containing the username and password already? Remember, I can not exchange public key or something, since I use ESXi 4.0. Thank you so much for your help. Adrian
Passing the password in the URI is not supported for security reasons. The URI is not considered to be private information. So there is currently no way to automate this for virsh. But if you write you own program using libvirt you can use virConnectOpenAuth and pass your own virConnectAuth. I just posted a patch for a new C example (based on hellolibvirt) that demonstrates how to do this. I CCed you to the patch so you should already have it in your inbox to try it. Matthias
participants (2)
-
adrian wyssen
-
Matthias Bolte