[lxc-devel] [pylxd/master] Don't allow local connection clients to migrate
rockstar on Github
lxc-bot at linuxcontainers.org
Fri Sep 16 15:45:48 UTC 2016
A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 739 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20160916/d30a3e0e/attachment.bin>
-------------- next part --------------
From c943a07b79d42aa72574a9c1c4c70bbce3441817 Mon Sep 17 00:00:00 2001
From: Paul Hummer <paul.hummer at canonical.com>
Date: Fri, 16 Sep 2016 09:17:33 -0600
Subject: [PATCH 1/2] Don't allow local connection clients to attempt a
migration.
Fixes #162
---
pylxd/models/container.py | 3 +++
pylxd/tests/models/test_container.py | 17 +++++++++++++++++
2 files changed, 20 insertions(+)
diff --git a/pylxd/models/container.py b/pylxd/models/container.py
index f7ef5d3..8acc243 100644
--- a/pylxd/models/container.py
+++ b/pylxd/models/container.py
@@ -231,6 +231,9 @@ def migrate(self, new_client, wait=False):
first or criu must be installed on the source and destination
machines.
"""
+ if self.api._api_endpoint.startswith('http+unix'):
+ raise ValueError('Cannot migrate from a local client connection')
+
self.sync() # Make sure the object isn't stale
response = self.api.post(json={'migration': True})
operation = self.client.operations.get(response.json()['operation'])
diff --git a/pylxd/tests/models/test_container.py b/pylxd/tests/models/test_container.py
index e2044a5..1cb12c0 100644
--- a/pylxd/tests/models/test_container.py
+++ b/pylxd/tests/models/test_container.py
@@ -191,6 +191,23 @@ def test_migrate(self):
self.assertEqual('an-container', an_migrated_container.name)
self.assertEqual(client2, an_migrated_container.client)
+ @mock.patch('pylxd.client._APINode.get')
+ def test_migrate_local_client(self, get):
+ """Migration from local clients is not supported."""
+ # Mock out the _APINode for the local instance.
+ response = mock.Mock()
+ response.json.return_value = {'metadata': {'fake': 'response'}}
+ response.status_code = 200
+ get.return_value = response
+
+ from pylxd.client import Client
+
+ client2 = Client(endpoint='http+unix://pylxd2.test')
+ an_container = models.Container(
+ client2, name='an-container')
+
+ self.assertRaises(ValueError, an_container.migrate, self.client)
+
def test_publish(self):
"""Containers can be published."""
self.add_rule({
From 85095e8374f0be8acdd4f600fb3eed375a7be0ff Mon Sep 17 00:00:00 2001
From: Paul Hummer <paul.hummer at canonical.com>
Date: Fri, 16 Sep 2016 09:37:46 -0600
Subject: [PATCH 2/2] Update _APINode to have a cleaner interface.
Stop reaching into private attributes.
---
pylxd/client.py | 17 ++++++++++++-----
pylxd/models/container.py | 2 +-
2 files changed, 13 insertions(+), 6 deletions(-)
diff --git a/pylxd/client.py b/pylxd/client.py
index e18028c..675e4a2 100644
--- a/pylxd/client.py
+++ b/pylxd/client.py
@@ -75,6 +75,14 @@ def _assert_response(self, response, allowed_status_codes=(200,)):
# Missing 'type' in response
raise exceptions.LXDAPIException(response)
+ @property
+ def scheme(self):
+ return parse.urlparse(self.api._api_endpoint).scheme
+
+ @property
+ def netloc(self):
+ return parse.urlparse(self.api._api_endpoint).netloc
+
def get(self, *args, **kwargs):
"""Perform an HTTP GET."""
response = self.session.get(self._api_endpoint, *args, **kwargs)
@@ -213,16 +221,15 @@ def authenticate(self, password):
@property
def websocket_url(self):
- parsed = parse.urlparse(self.api._api_endpoint)
- if parsed.scheme in ('http', 'https'):
- host = parsed.netloc
- if parsed.scheme == 'http':
+ if self.api.scheme in ('http', 'https'):
+ host = self.api.netloc
+ if self.api.scheme == 'http':
scheme = 'ws'
else:
scheme = 'wss'
else:
scheme = 'ws+unix'
- host = parse.unquote(parsed.netloc)
+ host = parse.unquote(self.api.netloc)
url = parse.urlunparse((scheme, host, '', '', '', ''))
return url
diff --git a/pylxd/models/container.py b/pylxd/models/container.py
index 8acc243..3bbf5d2 100644
--- a/pylxd/models/container.py
+++ b/pylxd/models/container.py
@@ -231,7 +231,7 @@ def migrate(self, new_client, wait=False):
first or criu must be installed on the source and destination
machines.
"""
- if self.api._api_endpoint.startswith('http+unix'):
+ if self.api.scheme in ('http+unix',):
raise ValueError('Cannot migrate from a local client connection')
self.sync() # Make sure the object isn't stale
More information about the lxc-devel
mailing list