canonical / pylxd

Python module for LXD
https://pylxd.readthedocs.io/en/latest/
Apache License 2.0
256 stars 134 forks source link

Getting "TypeError: Object of type 'object' is not JSON serializable" Error When Trying to Publish Image #404

Open bocajspear1 opened 4 years ago

bocajspear1 commented 4 years ago

I have code that creates a temporary container, runs commands, then publishes the container locally as an image.

The code is as follows:

temp_container = self.mm.lxd.containers.create({
    'name': container_name, 
    'source': {
        'type': 'image', 
        'alias': template,
        'mode': 'pull'
    },
    'config': {

    },
    "devices": {
        "eth0": {
            "type": "nic",
            "nictype": "bridged",
            "parent": switch
        }
    },
}, wait=True)

temp_container.start(wait=True)
status, stdout, stderr = temp_container.execute(["/bin/sh", "-c", "sleep 5"])
for command in commands:
    self.print("Ran: " + command)
    status, stdout, stderr = temp_container.execute(["/bin/sh", "-c", command])
    if status != 0:
        self.print("Command failed!")
        self.print(stdout)
        self.print(stderr)
        temp_container.stop(wait=True)
        temp_container.delete(wait=True)

        return False

temp_container.stop(wait=True)

image = temp_container.publish(wait=True)

However, when I call publish, I get an error:

  File "/home/user/fakernet/lib/base_module.py", line 326, in lxd_build_image
    image = temp_container.publish(wait=True)
  File "/home/user/fakernet/venv/lib/python3.6/site-packages/pylxd/models/instance.py", line 593, in publish
    response = self.client.api.images.post(json=data)
  File "/home/user/fakernet/venv/lib/python3.6/site-packages/pylxd/client.py", line 174, in post
    response = self.session.post(self._api_endpoint, *args, **kwargs)
  File "/home/user/fakernet/venv/lib/python3.6/site-packages/requests/sessions.py", line 578, in post
    return self.request('POST', url, data=data, json=json, **kwargs)
  File "/home/user/fakernet/venv/lib/python3.6/site-packages/requests/sessions.py", line 516, in request
    prep = self.prepare_request(req)
  File "/home/user/fakernet/venv/lib/python3.6/site-packages/requests/sessions.py", line 459, in prepare_request
    hooks=merge_hooks(request.hooks, self.hooks),
  File "/home/user/fakernet/venv/lib/python3.6/site-packages/requests/models.py", line 317, in prepare
    self.prepare_body(data, files, json)
  File "/home/user/fakernet/venv/lib/python3.6/site-packages/requests/models.py", line 468, in prepare_body
    body = complexjson.dumps(json)
  File "/usr/lib/python3.6/json/__init__.py", line 231, in dumps
    return _default_encoder.encode(obj)
  File "/usr/lib/python3.6/json/encoder.py", line 199, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "/usr/lib/python3.6/json/encoder.py", line 257, in iterencode
    return _iterencode(o, 0)
  File "/usr/lib/python3.6/json/encoder.py", line 180, in default
    o.__class__.__name__)
TypeError: Object of type 'object' is not JSON serializable

To look at the data being sent, I modified requests/models.py to print out the data it's trying to convert to JSON, and noted that the type field is an object.

{'public': False, 'source': {'type': <object object at 0x7f8954fc2710>, 'name': 'hop-alpine-310-temp'}}

I noted that in the tests, this value is manually set in integration/test_containers.py:

# Hack to get around mocked data
self.container.type = 'container'

When I do this in my code, the publish completes without an error.

godfryd commented 4 years ago

I observe the same problem.