Skip to content

Commit

Permalink
Mova NovaDocker driver to contrib
Browse files Browse the repository at this point in the history
We decided to deprecated NovaDocker driver in the team meeting [1].
Therefore, we moved the driver to the contrib folder. NovaDocker
was an experimental driver that attempts to leverage Nova to provide
networking to containers. However, as kuryr integration implemented,
this driver is not needed anymore.

[1] http://eavesdrop.openstack.org/meetings/zun/2017/
    zun.2017-07-11-03.00.log.html

Change-Id: I770fe13a004dc56ad20fe8eca545f05c4504e48e
  • Loading branch information
Hongbin Lu committed Sep 14, 2017
1 parent fe28a06 commit 6dc2866
Show file tree
Hide file tree
Showing 21 changed files with 60 additions and 277 deletions.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
1 change: 0 additions & 1 deletion contrib/vagrant/config/localrc
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ enable_plugin kuryr-libnetwork https://git.openstack.org/openstack/kuryr-libnetw

#Uncomment below variables and enable nova and neutron
#services to use nova docker driver
#ZUN_DRIVER=nova-docker
#IP_VERSION=4
disable_service n-api,n-cpu,n-cond,n-sch,n-novnc,n-cauth

Expand Down
4 changes: 1 addition & 3 deletions devstack/lib/zun
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ function configure_zun {

# upload_sandbox_image() - Upload sandbox image to glance
function upload_sandbox_image {
if [[ ${ZUN_DRIVER} == "docker" || ${ZUN_DRIVER} == "nova-docker" ]]; then
if [[ ${ZUN_DRIVER} == "docker" ]]; then
sudo docker pull kubernetes/pause
sudo docker save kubernetes/pause | openstack image create kubernetes/pause --public --container-format docker --disk-format raw
fi
Expand Down Expand Up @@ -183,8 +183,6 @@ function create_zun_conf {
rm -f $ZUN_CONF
if [[ ${ZUN_DRIVER} == "docker" ]]; then
iniset $ZUN_CONF DEFAULT container_driver docker.driver.DockerDriver
elif [[ ${ZUN_DRIVER} == "nova-docker" ]]; then
iniset $ZUN_CONF DEFAULT container_driver docker.driver.NovaDockerDriver
fi
if [[ ${ZUN_DB_TYPE} == "etcd" ]]; then
iniset $ZUN_CONF DEFAULT db_type etcd
Expand Down
7 changes: 0 additions & 7 deletions devstack/override-defaults

This file was deleted.

5 changes: 0 additions & 5 deletions devstack/plugin.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ set -o xtrace

echo_summary "zun's plugin.sh was called..."
source $DEST/zun/devstack/lib/zun
source $DEST/zun/devstack/lib/nova
(set -o posix; set)

if is_service_enabled zun-api zun-compute; then
Expand All @@ -26,10 +25,6 @@ if is_service_enabled zun-api zun-compute; then
create_zun_accounts
fi

if [[ ${ZUN_DRIVER} == "nova-docker" ]]; then
configure_nova_docker
fi

elif [[ "$1" == "stack" && "$2" == "extra" ]]; then
# Initialize zun
init_zun
Expand Down
1 change: 0 additions & 1 deletion zun/conf/container_driver.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
Possible values:
* ``docker.driver.DockerDriver``
* ``docker.driver.NovaDockerDriver``
Services which consume this:
Expand Down
115 changes: 0 additions & 115 deletions zun/container/docker/driver.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
from zun.common import consts
from zun.common import exception
from zun.common.i18n import _
from zun.common import nova
from zun.common import utils
from zun.common.utils import check_container_id
import zun.conf
Expand Down Expand Up @@ -799,117 +798,3 @@ def network_attach(self, context, container, network):
addresses.update(update)
container.addresses = addresses
container.save(context)


class NovaDockerDriver(DockerDriver):
capabilities = {
"support_sandbox": True,
"support_standalone": False,
}

def add_security_group(self, context, container, security_group, **kwargs):
msg = "NovaDockerDriver does not support security_groups"
raise exception.ZunException(msg)

def create_sandbox(self, context, container, key_name=None,
flavor='m1.tiny', image='kubernetes/pause',
nics='auto'):
# FIXME(hongbin): We elevate to admin privilege because the default
# policy in nova disallows non-admin users to create instance in
# specified host. This is not ideal because all nova instances will
# be created at service admin tenant now, which breaks the
# multi-tenancy model. We need to fix it.
elevated = context.elevated()
novaclient = nova.NovaClient(elevated)
name = self.get_sandbox_name(container)
if container.host != CONF.host:
raise exception.ZunException(_(
"Host mismatch: container should be created at host '%s'.") %
container.host)
# NOTE(hongbin): The format of availability zone is ZONE:HOST:NODE
# However, we just want to specify host, so it is ':HOST:'
az = ':%s:' % container.host
sandbox = novaclient.create_server(name=name, image=image,
flavor=flavor, key_name=key_name,
nics=nics, availability_zone=az)
self._ensure_active(novaclient, sandbox)
sandbox_id = self._find_container_by_server_name(name)
return sandbox_id

def _ensure_active(self, novaclient, server, timeout=300):
"""Wait until the Nova instance to become active."""
def _check_active():
return novaclient.check_active(server)

success_msg = "Created server %s successfully." % server.id
timeout_msg = ("Failed to create server %s. Timeout waiting for "
"server to become active.") % server.id
utils.poll_until(_check_active,
sleep_time=CONF.default_sleep_time,
time_out=timeout or CONF.default_timeout,
success_msg=success_msg, timeout_msg=timeout_msg)

def delete_sandbox(self, context, sandbox_id):
elevated = context.elevated()
novaclient = nova.NovaClient(elevated)
server_name = self._find_server_by_container_id(sandbox_id)
if not server_name:
LOG.warning("Cannot find server name for sandbox %s", sandbox_id)
return

server_id = novaclient.delete_server(server_name)
self._ensure_deleted(novaclient, server_id)

def stop_sandbox(self, context, sandbox_id):
elevated = context.elevated()
novaclient = nova.NovaClient(elevated)
server_name = self._find_server_by_container_id(sandbox_id)
if not server_name:
LOG.warning("Cannot find server name for sandbox %s", sandbox_id)
return
novaclient.stop_server(server_name)

def _ensure_deleted(self, novaclient, server_id, timeout=300):
"""Wait until the Nova instance to be deleted."""
def _check_delete_complete():
return novaclient.check_delete_server_complete(server_id)

success_msg = "Delete server %s successfully." % server_id
timeout_msg = ("Failed to create server %s. Timeout waiting for "
"server to be deleted.") % server_id
utils.poll_until(_check_delete_complete,
sleep_time=CONF.default_sleep_time,
time_out=timeout or CONF.default_timeout,
success_msg=success_msg, timeout_msg=timeout_msg)

def get_addresses(self, context, container):
elevated = context.elevated()
novaclient = nova.NovaClient(elevated)
sandbox_id = container.get_sandbox_id()
if sandbox_id:
server_name = self._find_server_by_container_id(sandbox_id)
if server_name:
# TODO(hongbin): Standardize the format of addresses
return novaclient.get_addresses(server_name)
else:
return None
else:
return None

def _find_container_by_server_name(self, name):
with docker_utils.docker_client() as docker:
for info in docker.list_instances(inspect=True):
if info['Config'].get('Hostname') == name:
return info['Id']
raise exception.ZunException(_(
"Cannot find container with name %s") % name)

def _find_server_by_container_id(self, container_id):
with docker_utils.docker_client() as docker:
try:
info = docker.inspect_container(container_id)
return info['Config'].get('Hostname')
except errors.APIError as e:
if e.response.status_code != 404:
raise
return None
3 changes: 0 additions & 3 deletions zun/tests/contrib/gate_hook.sh
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,6 @@ export DEVSTACK_LOCAL_CONFIG+=$'\n'"KURYR_CONFIG_DIR=/etc/kuryr-libnetwork"

if [ "$driver" = "docker" ]; then
export DEVSTACK_LOCAL_CONFIG+=$'\n'"ZUN_DRIVER=docker"
elif [ "$driver" = "nova-docker" ]; then
export DEVSTACK_LOCAL_CONFIG+=$'\n'"ZUN_DRIVER=nova-docker"
export DEVSTACK_LOCAL_CONFIG+=$'\n'"IP_VERSION=4"
fi

if [ "$db" = "etcd" ]; then
Expand Down
142 changes: 0 additions & 142 deletions zun/tests/unit/container/docker/test_docker_driver.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,11 @@
from docker import errors
import mock

from oslo_serialization import jsonutils
from oslo_utils import units

from zun.common import consts
from zun import conf
from zun.container.docker.driver import DockerDriver
from zun.container.docker.driver import NovaDockerDriver
from zun.container.docker import utils as docker_utils
from zun import objects
from zun.tests.unit.container import base
Expand Down Expand Up @@ -495,97 +493,6 @@ def test_network_attach(self, mock_list, mock_disconnect, mock_connect):
requested_network[0],
security_groups=None)


class TestNovaDockerDriver(base.DriverTestCase):
def setUp(self):
super(TestNovaDockerDriver, self).setUp()
self.driver = NovaDockerDriver()

@mock.patch(
'zun.container.docker.driver.NovaDockerDriver.get_sandbox_name')
@mock.patch('zun.common.nova.NovaClient')
@mock.patch('zun.container.docker.driver.NovaDockerDriver._ensure_active')
@mock.patch('zun.container.docker.driver.'
'NovaDockerDriver._find_container_by_server_name')
def test_create_sandbox(self, mock_find_container_by_server_name,
mock_ensure_active, mock_nova_client,
mock_get_sandbox_name):
nova_client_instance = mock.MagicMock()
nova_client_instance.create_server.return_value = 'server_instance'
mock_get_sandbox_name.return_value = 'test_sanbox_name'
mock_nova_client.return_value = nova_client_instance
mock_ensure_active.return_value = True
mock_find_container_by_server_name.return_value = \
'test_container_name_id'
mock_container = obj_utils.get_test_container(self.context,
host=conf.CONF.host)
result_sandbox_id = self.driver.create_sandbox(self.context,
mock_container)
mock_get_sandbox_name.assert_called_once_with(mock_container)
nova_client_instance.create_server.assert_called_once_with(
name='test_sanbox_name', image='kubernetes/pause',
flavor='m1.tiny', key_name=None,
nics='auto', availability_zone=':{0}:'.format(conf.CONF.host))
mock_ensure_active.assert_called_once_with(nova_client_instance,
'server_instance')
mock_find_container_by_server_name.assert_called_once_with(
'test_sanbox_name')
self.assertEqual(result_sandbox_id, 'test_container_name_id')

@mock.patch('zun.common.nova.NovaClient')
@mock.patch('zun.container.docker.driver.'
'NovaDockerDriver._find_server_by_container_id')
@mock.patch('zun.container.docker.driver.NovaDockerDriver._ensure_deleted')
def test_delete_sandbox(self, mock_ensure_delete,
mock_find_server_by_container_id, mock_nova_client
):
nova_client_instance = mock.MagicMock()
nova_client_instance.delete_server.return_value = 'delete_server_id'
mock_nova_client.return_value = nova_client_instance
mock_find_server_by_container_id.return_value = 'test_test_server_name'
mock_ensure_delete.return_value = True
self.driver.delete_sandbox(self.context, sandbox_id='test_sandbox_id')
mock_find_server_by_container_id.assert_called_once_with(
'test_sandbox_id')
nova_client_instance.delete_server.assert_called_once_with(
'test_test_server_name')
mock_ensure_delete.assert_called_once_with(nova_client_instance,
'delete_server_id')

@mock.patch('zun.common.nova.NovaClient')
@mock.patch('zun.container.docker.driver.'
'NovaDockerDriver._find_server_by_container_id')
def test_stop_sandbox(self, mock_find_server_by_container_id,
mock_nova_client):
nova_client_instance = mock.MagicMock()
nova_client_instance.stop_server.return_value = 'stop_server_id'
mock_nova_client.return_value = nova_client_instance
mock_find_server_by_container_id.return_value = 'test_test_server_name'
self.driver.stop_sandbox(self.context, sandbox_id='test_sandbox_id')
mock_find_server_by_container_id.assert_called_once_with(
'test_sandbox_id')
nova_client_instance.stop_server.assert_called_once_with(
'test_test_server_name')

@mock.patch('zun.container.docker.driver.'
'NovaDockerDriver._find_server_by_container_id')
@mock.patch('zun.common.nova.NovaClient')
def test_get_addresses(self, mock_nova_client,
mock_find_server_by_container_id):
nova_client_instance = mock.MagicMock()
nova_client_instance.get_addresses.return_value = 'test_address'
mock_nova_client.return_value = nova_client_instance
mock_find_server_by_container_id.return_value = 'test_test_server_name'
mock_container = mock.MagicMock()
mock_container.get_sandbox_id.return_value = 'test_sanbox_id'
result_address = self.driver.get_addresses(self.context,
mock_container)
mock_find_server_by_container_id.assert_called_once_with(
'test_sanbox_id')
nova_client_instance.get_addresses.assert_called_once_with(
'test_test_server_name')
self.assertEqual(result_address, 'test_address')

@mock.patch('oslo_concurrency.processutils.execute')
@mock.patch('zun.container.driver.ContainerDriver.get_host_mem')
@mock.patch(
Expand Down Expand Up @@ -620,52 +527,3 @@ def test_get_available_resources(self, mock_cpu_used, mock_info, mock_mem,
self.assertEqual('CentOS', node_obj.os)
self.assertEqual('3.10.0-123', node_obj.kernel_version)
self.assertEqual({'dev.type': 'product'}, node_obj.labels)

@mock.patch('tarfile.open')
def test_read_tar_image(self, mock_open):
fake_image = {'path': 'fake-path'}
mock_context_manager = mock.MagicMock()
mock_open.return_value = mock_context_manager
mock_file = mock.MagicMock()
mock_context_manager.__enter__.return_value = mock_file
mock_data = [{"Config": "fake_config",
"RepoTags": ["cirros:latest"],
"Layers": ["fake_layer", "fake_layer2"]}]
mock_file.extractfile.return_value.read.return_value = \
jsonutils.dumps(mock_data, separators=(',', ':'))

self.driver.read_tar_image(fake_image)
self.assertEqual('cirros', fake_image['repo'])
self.assertEqual('latest', fake_image['tag'])

@mock.patch('tarfile.open')
def test_read_tar_image_multi_tags(self, mock_open):
fake_image = {'path': 'fake-path'}
mock_context_manager = mock.MagicMock()
mock_open.return_value = mock_context_manager
mock_file = mock.MagicMock()
mock_context_manager.__enter__.return_value = mock_file
mock_data = [{"Config": "fake_config",
"RepoTags": ["cirros:latest", "cirros:0.3.4"],
"Layers": ["fake_layer", "fake_layer2"]}]
mock_file.extractfile.return_value.read.return_value = \
jsonutils.dumps(mock_data, separators=(',', ':'))

self.driver.read_tar_image(fake_image)
self.assertEqual('cirros', fake_image['repo'])
self.assertEqual('latest', fake_image['tag'])

@mock.patch('tarfile.open')
def test_read_tar_image_fail(self, mock_open):
fake_image = {'path': 'fake-path'}
mock_context_manager = mock.MagicMock()
mock_open.return_value = mock_context_manager
mock_file = mock.MagicMock()
mock_context_manager.__enter__.return_value = mock_file
mock_data = [{"Config": "fake_config"}]
mock_file.extractfile.return_value.read.return_value = \
jsonutils.dumps(mock_data, separators=(',', ':'))

self.driver.read_tar_image(fake_image)
self.assertTrue('repo' not in fake_image)
self.assertTrue('tag' not in fake_image)
Loading

0 comments on commit 6dc2866

Please sign in to comment.