Skip to content

openstack driver can create node from bootable vol#1362

Merged
Kami merged 1 commit intoapache:trunkfrom
vdloo:openstack-driver-can-create-node-from-bootable-vol
Nov 1, 2019
Merged

openstack driver can create node from bootable vol#1362
Kami merged 1 commit intoapache:trunkfrom
vdloo:openstack-driver-can-create-node-from-bootable-vol

Conversation

@vdloo
Copy link
Copy Markdown
Member

@vdloo vdloo commented Oct 30, 2019

Currently it is not possible to use the create_node method without
specifying an image. This is because in the OpenStack_1_1_NodeDriver
create_node converts the server_params like:

server_params = self._create_args_to_params(None, **kwargs)

but in case when there is no image to boot from like when you are
booting from an already existing bootable volume (which could have been
created from an image earlier), then _create_args_to_params will try to
access node.extra in order to get the imageRef, and node is None:

        if 'image' in kwargs:
            server_params['imageRef'] = kwargs.get('image').id
        else:
            server_params['imageRef'] = node.extra.get('imageId')

Booting an instance from a previously existing bootable volume like this
would fail:

In [36]: conn.create_node(ex_availability_zone='R123', port='8487d948-0840-4205-8b31-7f705a19e7f4', name='r123apitestnode', ex_keyname
    ...: ='rick', size='e55a2688-ef74-44cf-b302-9a6f960c3d74', ex_blockdevicemappings=[{'boot_index': 0, 'uuid': 'be7ee330-b454-4414-8
    ...: e9f-c70c558dd3af', 'source_type': 'volume', 'destination_type': 'volume', 'delete_on_termination': False}])

with:

/usr/local/venv/hypernode-control/src/apache-libcloud/libcloud/compute/drivers/openstack.pyc in _create_args_to_params(self, node, **kwargs)
   1495             server_params['imageRef'] = kwargs.get('image').id
   1496         else:
-> 1497             server_params['imageRef'] = node.extra.get('imageId')
   1498
   1499         if 'size' in kwargs:

AttributeError: 'NoneType' object has no attribute 'extra'

This could be circumvented by specifying image='':

In [39]: conn.create_node(ex_availability_zone='R123', port='8487d948-0840-4205-8b31-7f705a19e7f4', image='', name='r123apitestnode',
    ...: ex_keyname='rick', size='e55a2688-ef74-44cf-b302-9a6f960c3d74', ex_blockdevicemappings=[{'boot_index': 0, 'uuid': 'be7ee330-b
    ...: 454-4414-8e9f-c70c558dd3af', 'source_type': 'volume', 'destination_type': 'volume', 'delete_on_termination': False}])

This PR also changes the default imageRef to empty string '' instead of None to prevent the API from responding with an error like this when the .get would default to None so that image='' will now no longer have to be specified.

BaseHTTPError: 400 Bad Request Invalid input for field/attribute imageRef. Value: None. u'None' is not valid under any of the given schemas

For more information see https://docs.openstack.org/api-ref/compute/?expanded=create-server-detail#create-server

imageRef (Optional) | body | string | The UUID of the image to use for your server instance. This is not required in case of boot from volume. In all other cases it is required and must be a valid UUID otherwise API will return 400.

Currently it is not possible to use the create_node method without
specifying an image. This is because in the OpenStack_1_1_NodeDriver
create_node converts the server_params like:

```
server_params = self._create_args_to_params(None, **kwargs)
```

but in case when there is no image to boot from like when you are
booting from an already existing bootable volume (which could have been
created from an image earlier), then _create_args_to_params will try to
access node.extra in order to get the imageRef, and node is None:

```
        if 'image' in kwargs:
            server_params['imageRef'] = kwargs.get('image').id
        else:
            server_params['imageRef'] = node.extra.get('imageId')
```

Booting an instance from a previously existing bootable volume like this
would fail:

```
In [36]: conn.create_node(ex_availability_zone='R123', port='8487d948-0840-4205-8b31-7f705a19e7f4', name='r123apitestnode', ex_keyname
    ...: ='rick', size='e55a2688-ef74-44cf-b302-9a6f960c3d74', ex_blockdevicemappings=[{'boot_index': 0, 'uuid': 'be7ee330-b454-4414-8
    ...: e9f-c70c558dd3af', 'source_type': 'volume', 'destination_type': 'volume', 'delete_on_termination': False}])
```

with:
```
/usr/local/venv/hypernode-control/src/apache-libcloud/libcloud/compute/drivers/openstack.pyc in _create_args_to_params(self, node, **kwargs)
   1495             server_params['imageRef'] = kwargs.get('image').id
   1496         else:
-> 1497             server_params['imageRef'] = node.extra.get('imageId')
   1498
   1499         if 'size' in kwargs:

AttributeError: 'NoneType' object has no attribute 'extra'
```

This could be circumvented by specifying `image=''`:
```
In [39]: conn.create_node(ex_availability_zone='R123', port='8487d948-0840-4205-8b31-7f705a19e7f4', image='', name='r123apitestnode',
    ...: ex_keyname='rick', size='e55a2688-ef74-44cf-b302-9a6f960c3d74', ex_blockdevicemappings=[{'boot_index': 0, 'uuid': 'be7ee330-b
    ...: 454-4414-8e9f-c70c558dd3af', 'source_type': 'volume', 'destination_type': 'volume', 'delete_on_termination': False}])
```

This PR also changes the default imageRef to empty string '' instead of None to prevent the API from responding with an error like this when the .get would default to None so that `image=''` will now no longer have to be specified.
```
BaseHTTPError: 400 Bad Request Invalid input for field/attribute imageRef. Value: None. u'None' is not valid under any of the given schemas
```
@vdloo vdloo force-pushed the openstack-driver-can-create-node-from-bootable-vol branch from e2c114a to 114f09f Compare October 30, 2019 12:31
@vdloo
Copy link
Copy Markdown
Member Author

vdloo commented Oct 30, 2019

force-pushed to rebuild, failed on the seemingly unrelated:

3.5 is not installed; attempting download0.07s
worker_info
Worker information
0.18s0.01s0.00s0.01s
system_info
Build system information
0.02s0.01s0.43s128.20s120.58s0.01s0.04s0.00s0.01s0.01s0.01s0.01s0.01s0.00s0.00s0.02s0.00s0.01s0.29s0.00s0.00s0.00s0.01s0.00s0.05s0.00s0.98s0.00s0.00s0.73s0.00s4.45s0.00s1.20s
docker_mtu
docker stop/waiting
resolvconf
resolvconf stop/waiting
Downloading archive: https://storage.googleapis.com/travis-ci-language-archives/python/binaries/ubuntu/14.04/x86_64/python-3.5.tar.bz2
127.27s$ curl -sSf -o python-3.5.tar.bz2 ${archive_url}
curl: (7) Failed to connect to storage.googleapis.com port 443: Connection timed out
Unable to download 3.5 archive. The archive may not exist. Please consider a different version.

https://travis-ci.org/apache/libcloud/jobs/604933686?utm_medium=notification&utm_source=github_status in https://travis-ci.org/apache/libcloud/builds/604933683?utm_source=github_status&utm_medium=notification

Copy link
Copy Markdown
Member

@Kami Kami left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 👍

@Kami Kami merged commit 9e3296d into apache:trunk Nov 1, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants