I tried it today, I use a default pylxd.client.Client()
in my python code and initially got a unix socket exception:
pylxd.exceptions.ClientConnectionFailed: ('Connection aborted.', FileNotFoundError(2, 'No such file or directory'))
Had a quick peek at the code and worked out by default it uses /var/lib/lxd/unix.socket
unless the LXD_DIR environment variable is set, in which case it will use $LXD_DIR/unix.socket
. So I set the environment variable in the shell as follows:
export LXD_DIR=/var/lib/incus
Then ran the python again and hit the following exception at the point where it is creating a new instance using an image:
conftest.py:305: in new_container
container = client.containers.create(config, wait=True)
../../../../.local/share/virtualenvs/test.1-hxo-P72l/lib/python3.10/site-packages/pylxd/models/instance.py:323: in create
response = client.api[cls._endpoint].post(json=config, target=target)
../../../../.local/share/virtualenvs/test.1-hxo-P72l/lib/python3.10/site-packages/pylxd/client.py:216: in post
self._assert_response(response, allowed_status_codes=(200, 201, 202))
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <pylxd.client._APINode object at 0x7f9a039801c0>, response = <Response [404]>, allowed_status_codes = (200, 201, 202)
stream = False, is_api = True
def _assert_response(
self, response, allowed_status_codes=(200,), stream=False, is_api=True
):
"""Assert properties of the response.
LXD's API clearly defines specific responses. If the API
response is something unexpected (i.e. an error), then
we need to raise an exception and have the call points
handle the errors or just let the issue be raised to the
user.
"""
if response.status_code not in allowed_status_codes:
if response.status_code == 404:
> raise exceptions.NotFound(response)
E pylxd.exceptions.NotFound: not found
../../../../.local/share/virtualenvs/test.1-hxo-P72l/lib/python3.10/site-packages/pylxd/client.py:144: NotFound
Ran again with the debugger I see what was in the request attached to this 404 response:
(Pdb) print(response.request)
<PreparedRequest [POST]>
(Pdb) print(response.request.url)
http+unix://%2Fvar%2Flib%2Fincus%2Funix.socket/1.0/containers
(Pdb) print(response.request.path_url)
/1.0/containers
Pdb) print(response.request.headers)
{'User-Agent': 'python-requests/2.31.0', 'Accept-Encoding': 'gzip, deflate, br', 'Accept': '*/*', 'Connection': 'keep-alive', 'Content-Length': '87', 'Content-Type': 'application/json'}
(Pdb) print(response.request.body)
b'{"name": "psp-dbmaster", "source": {"type": "image", "alias": "centos/7/psp/dbmaster"}}'
(Pdb)
Looking at the Incus API spec there is no method named containers
. The LXD API spec also does not contain a containers
method. I’m assuming that in LXD this method was renamed from containers
to instances
(see Incus API POST instances) and in LXD there is a redirect, but in Incus there is not?
On a machine with both incus and lxd installed I can run the following curl commands:
curl --unix-socket /var/lib/lxd/unix.socket http://localhost/1.0/containers
200
curl --unix-socket /var/lib/lxd/unix.socket http://localhost/1.0/instances
200
curl --unix-socket /var/lib/incus/unix.socket http://localhost/1.0/containers
404
curl --unix-socket /var/lib/incus/unix.socket http://localhost/1.0/instances
200
So I will need to patch pylxd client.py to replace the containers method name with instances. To be continued…