[lxc-devel] [pylxd/master] Add support for LXD storage pools
ChrisMacNaughton on Github
lxc-bot at linuxcontainers.org
Wed Jul 12 07:23:44 UTC 2017
A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 417 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20170712/3342b713/attachment.bin>
-------------- next part --------------
From 4fd212b9029cdb3a0dc2baca45392daaacf0cdf2 Mon Sep 17 00:00:00 2001
From: Chris MacNaughton <chris at centaurisolutions.nl>
Date: Wed, 12 Jul 2017 09:21:03 +0200
Subject: [PATCH] Add support for LXD storage pools
This adds basic support for storage pools as well
as tests to verify their function, taken from the
LXD REST API.
---
pylxd/client.py | 5 ++--
pylxd/managers.py | 4 +++
pylxd/models/__init__.py | 1 +
pylxd/models/storage_pool.py | 55 ++++++++++++++++++++++++++++++++++++++
pylxd/tests/mock_lxd.py | 26 ++++++++++++++++++
pylxd/tests/models/test_storage.py | 53 ++++++++++++++++++++++++++++++++++++
6 files changed, 142 insertions(+), 2 deletions(-)
create mode 100644 pylxd/models/storage_pool.py
create mode 100644 pylxd/tests/models/test_storage.py
diff --git a/pylxd/client.py b/pylxd/client.py
index d4fb2a7..1e7dd77 100644
--- a/pylxd/client.py
+++ b/pylxd/client.py
@@ -46,12 +46,12 @@ def __init__(self, api_endpoint, cert=None, verify=True, timeout=None):
def __getattr__(self, name):
return self.__class__(
- '{}/{}'.format(self._api_endpoint, name),
+ '{}/{}'.format(self._api_endpoint, name.replace('_', '-')),
cert=self.session.cert, verify=self.session.verify)
def __getitem__(self, item):
return self.__class__(
- '{}/{}'.format(self._api_endpoint, item),
+ '{}/{}'.format(self._api_endpoint, item.replace('_', '-')),
cert=self.session.cert,
verify=self.session.verify,
timeout=self._timeout)
@@ -237,6 +237,7 @@ def __init__(
self.networks = managers.NetworkManager(self)
self.operations = managers.OperationManager(self)
self.profiles = managers.ProfileManager(self)
+ self.storage_pools = managers.StoragePoolManager(self)
@property
def trusted(self):
diff --git a/pylxd/managers.py b/pylxd/managers.py
index c67e781..a7dbb7e 100644
--- a/pylxd/managers.py
+++ b/pylxd/managers.py
@@ -55,6 +55,10 @@ class SnapshotManager(BaseManager):
manager_for = 'pylxd.models.Snapshot'
+class StoragePoolManager(BaseManager):
+ manager_for = 'pylxd.models.StoragePool'
+
+
@contextmanager
def web_socket_manager(manager):
try:
diff --git a/pylxd/models/__init__.py b/pylxd/models/__init__.py
index 725fb66..5f3a42b 100644
--- a/pylxd/models/__init__.py
+++ b/pylxd/models/__init__.py
@@ -4,3 +4,4 @@
from pylxd.models.network import Network # NOQA
from pylxd.models.operation import Operation # NOQA
from pylxd.models.profile import Profile # NOQA
+from pylxd.models.storage_pool import StoragePool # NOQA
diff --git a/pylxd/models/storage_pool.py b/pylxd/models/storage_pool.py
new file mode 100644
index 0000000..f6c8101
--- /dev/null
+++ b/pylxd/models/storage_pool.py
@@ -0,0 +1,55 @@
+# Copyright (c) 2016 Canonical Ltd
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+from pylxd.models import _model as model
+
+
+class StoragePool(model.Model):
+ """A LXD storage_pool."""
+ name = model.Attribute()
+ driver = model.Attribute()
+ description = model.Attribute()
+ used_by = model.Attribute()
+ config = model.Attribute()
+ managed = model.Attribute()
+
+ @classmethod
+ def get(cls, client, name):
+ """Get a storage_pool by name."""
+ response = client.api.storage_pools[name].get()
+
+ storage_pool = cls(client, **response.json()['metadata'])
+ return storage_pool
+
+ @classmethod
+ def all(cls, client):
+ """Get all storage_pools."""
+ response = client.api.storage_pools.get()
+
+ storage_pools = []
+ for url in response.json()['metadata']:
+ name = url.split('/')[-1]
+ storage_pools.append(cls(client, name=name))
+ return storage_pools
+
+ @property
+ def api(self):
+ return self.client.api.storage_pools[self.name]
+
+ def save(self, wait=False):
+ """Save is not available for storage_pools."""
+ raise NotImplementedError('save is not implemented')
+
+ def delete(self):
+ """Delete is not available for storage_pools."""
+ raise NotImplementedError('delete is not implemented')
diff --git a/pylxd/tests/mock_lxd.py b/pylxd/tests/mock_lxd.py
index 12f3c79..d42d2f2 100644
--- a/pylxd/tests/mock_lxd.py
+++ b/pylxd/tests/mock_lxd.py
@@ -545,6 +545,32 @@ def profile_GET(request, context):
'url': r'^http://pylxd.test/1.0/networks/lo$',
},
+ # Storage Pools
+ {
+ 'json': {
+ 'type': 'sync',
+ 'metadata': [
+ 'http://pylxd.test/1.0/storage-pools/lxd',
+ ]},
+ 'method': 'GET',
+ 'url': r'^http://pylxd.test/1.0/storage-pools$',
+ },
+ {
+ 'json': {
+ 'type': 'sync',
+ 'metadata': {
+ 'config': {
+ 'size': '0',
+ 'source': '/var/lib/lxd/disks/lxd.img'
+ },
+ 'description': '',
+ 'name': 'lxd',
+ 'driver': 'zfs',
+ 'used_by': [],
+ }},
+ 'method': 'GET',
+ 'url': r'^http://pylxd.test/1.0/storage-pools/lxd$',
+ },
# Profiles
{
diff --git a/pylxd/tests/models/test_storage.py b/pylxd/tests/models/test_storage.py
new file mode 100644
index 0000000..f2373ab
--- /dev/null
+++ b/pylxd/tests/models/test_storage.py
@@ -0,0 +1,53 @@
+# Copyright (c) 2016 Canonical Ltd
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+from pylxd import models
+from pylxd.tests import testing
+
+
+class TestStoragePool(testing.PyLXDTestCase):
+ """Tests for pylxd.models.StoragePool."""
+
+ def test_all(self):
+ """A list of all storage_pools are returned."""
+ storage_pools = models.StoragePool.all(self.client)
+
+ self.assertEqual(1, len(storage_pools))
+
+ def test_get(self):
+ """Return a container."""
+ name = 'lxd'
+
+ an_storage_pool = models.StoragePool.get(self.client, name)
+
+ self.assertEqual(name, an_storage_pool.name)
+
+ def test_partial(self):
+ """A partial storage_pool is synced."""
+ an_storage_pool = models.StoragePool(self.client, name='lxd')
+
+ self.assertEqual('zfs', an_storage_pool.driver)
+
+ def test_delete(self):
+ """delete is not implemented in storage_pools."""
+ an_storage_pool = models.StoragePool(self.client, name='lxd')
+
+ with self.assertRaises(NotImplementedError):
+ an_storage_pool.delete()
+
+ def test_save(self):
+ """save is not implemented in storage_pools."""
+ an_storage_pool = models.StoragePool(self.client, name='lxd')
+
+ with self.assertRaises(NotImplementedError):
+ an_storage_pool.save()
More information about the lxc-devel
mailing list