Adding utils to install XAPI plugins to dom0
When deploy OpenStack on XenServer, we need install some XAPI plugins to dom0. This commit is to add utils for this purpose. If the os-xenapi version is different from the os-xenapi which contains the utils. Users can specify the version to the utils. So that the utils will download the right version of os-xenapi and copy plugins from there. Otherwise the utils will by default copy plugins from current installed packages. Change-Id: I269a444b952f63fd73b3825b23dc95d6e825ce8f
This commit is contained in:
parent
4cafb55ce0
commit
aa48f8223a
100
os_xenapi/tests/utils/test_xapi_plugin.py
Normal file
100
os_xenapi/tests/utils/test_xapi_plugin.py
Normal file
@ -0,0 +1,100 @@
|
||||
# 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.
|
||||
|
||||
import mock
|
||||
import os
|
||||
import shutil
|
||||
import tempfile
|
||||
|
||||
from os_xenapi.tests import base
|
||||
from os_xenapi.utils import common_function
|
||||
from os_xenapi.utils import xapi_plugin
|
||||
|
||||
|
||||
class XenapiPluginTestCase(base.TestCase):
|
||||
@mock.patch.object(tempfile, 'mkdtemp',
|
||||
return_value='/tmp/tmp1VyeJn')
|
||||
@mock.patch.object(common_function, 'execute')
|
||||
def test_get_os_xenapi_dir_with_version(self, mock_exec, mock_tmp):
|
||||
VERSION = '0.3.1'
|
||||
is_tmp, dir = xapi_plugin.get_os_xenapi_dir(VERSION)
|
||||
|
||||
self.assertEqual(2, mock_exec.call_count)
|
||||
self.assertEqual(dir, '/tmp/tmp1VyeJn')
|
||||
self.assertEqual(is_tmp, True)
|
||||
|
||||
@mock.patch.object(tempfile, 'mkdtemp')
|
||||
@mock.patch.object(common_function, 'execute')
|
||||
def test_get_os_xenapi_dir_no_version(self, mock_exec, mock_tmp):
|
||||
fake_loc = '/fake/install/loc'
|
||||
mock_exec.return_value = 'Location: %s\n' % fake_loc
|
||||
|
||||
is_tmp, dir = xapi_plugin.get_os_xenapi_dir()
|
||||
|
||||
self.assertEqual(dir, fake_loc)
|
||||
self.assertEqual(is_tmp, False)
|
||||
mock_exec.assert_called_with('pip', 'show',
|
||||
xapi_plugin.OS_XENAPI_PKG)
|
||||
mock_tmp.assert_not_called()
|
||||
|
||||
@mock.patch.object(xapi_plugin, 'get_os_xenapi_dir')
|
||||
@mock.patch.object(os, 'listdir')
|
||||
@mock.patch.object(shutil, 'rmtree')
|
||||
def test_install_plugins_to_dom0_no_version(self, mock_rm, mock_dir,
|
||||
mock_get):
|
||||
FAKE_PKG_PATH = '/fake/pkg/path'
|
||||
ssh_client = mock.Mock()
|
||||
mock_get.return_value = (False, FAKE_PKG_PATH)
|
||||
mock_dir.return_value = ['file1', 'file2']
|
||||
|
||||
xapi_plugin.install_plugins_to_dom0(ssh_client)
|
||||
|
||||
dom0_path = xapi_plugin.DOM0_PLUGIN_PATH
|
||||
local_path = '%s/%s' % (FAKE_PKG_PATH,
|
||||
xapi_plugin.PKG_PLUGIN_PATH)
|
||||
scp_expect = [mock.call('%s/file1' % local_path,
|
||||
'%s/file1' % dom0_path),
|
||||
mock.call('%s/file2' % local_path,
|
||||
'%s/file2' % dom0_path)]
|
||||
ssh_expect = [mock.call('chmod +x %s/file1' % dom0_path),
|
||||
mock.call('chmod +x %s/file2' % dom0_path)]
|
||||
self.assertEqual(scp_expect, ssh_client.scp.call_args_list)
|
||||
self.assertEqual(ssh_expect, ssh_client.ssh.call_args_list)
|
||||
# Shouldn't invoke mock_rm to remove the package dir.
|
||||
mock_rm.assert_not_called()
|
||||
|
||||
@mock.patch.object(xapi_plugin, 'get_os_xenapi_dir')
|
||||
@mock.patch.object(os, 'listdir')
|
||||
@mock.patch.object(shutil, 'rmtree')
|
||||
def test_install_plugins_to_dom0_with_version(self, mock_rm, mock_dir,
|
||||
mock_get):
|
||||
VERSION = '0.3.1'
|
||||
FAKE_PKG_PATH = '/tmp/tmp1VyeJn'
|
||||
ssh_client = mock.Mock()
|
||||
mock_get.return_value = (True, FAKE_PKG_PATH)
|
||||
mock_dir.return_value = ['file1', 'file2']
|
||||
|
||||
xapi_plugin.install_plugins_to_dom0(ssh_client, VERSION)
|
||||
|
||||
dom0_path = xapi_plugin.DOM0_PLUGIN_PATH
|
||||
local_path = '%s/%s' % (FAKE_PKG_PATH,
|
||||
xapi_plugin.PKG_PLUGIN_PATH)
|
||||
scp_expect = [mock.call('%s/file1' % local_path,
|
||||
'%s/file1' % dom0_path),
|
||||
mock.call('%s/file2' % local_path,
|
||||
'%s/file2' % dom0_path)]
|
||||
ssh_expect = [mock.call('chmod +x %s/file1' % dom0_path),
|
||||
mock.call('chmod +x %s/file2' % dom0_path)]
|
||||
self.assertEqual(scp_expect, ssh_client.scp.call_args_list)
|
||||
self.assertEqual(ssh_expect, ssh_client.ssh.call_args_list)
|
||||
# Should invoke mock_rm to remove the package dir.
|
||||
mock_rm.assert_called_with(FAKE_PKG_PATH)
|
83
os_xenapi/utils/xapi_plugin.py
Normal file
83
os_xenapi/utils/xapi_plugin.py
Normal file
@ -0,0 +1,83 @@
|
||||
#!/usr/bin/env python
|
||||
# Copyright 2017 Citrix Systems
|
||||
#
|
||||
# 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.
|
||||
"""XAPI plugin utils
|
||||
|
||||
It contains the utilities relative to XAPI plugins."""
|
||||
|
||||
import os
|
||||
import shutil
|
||||
import sys
|
||||
import tempfile
|
||||
|
||||
from os_xenapi.utils import common_function as fun
|
||||
from os_xenapi.utils.sshclient import SSHClient
|
||||
|
||||
|
||||
DOM0_PLUGIN_PATH = '/etc/xapi.d/plugins'
|
||||
PKG_PLUGIN_PATH = 'os_xenapi/dom0/etc/xapi.d/plugins'
|
||||
OS_XENAPI_PKG = 'os-xenapi'
|
||||
|
||||
|
||||
def get_os_xenapi_dir(version=None):
|
||||
# Get os-xenapi's directory.
|
||||
# return (is_tmp_dir, os_xenapi_dir), where is_tmp_dir indicates
|
||||
# if the os_xenapi_dir is a temporary directory.
|
||||
is_tmp_dir = False
|
||||
os_xenapi_dir = None
|
||||
if version:
|
||||
# If version is specified, then download the specified package.
|
||||
# And unpack the package.
|
||||
temp_dir = tempfile.mkdtemp()
|
||||
fun.execute('pip', 'download', '--no-deps', '-d', temp_dir,
|
||||
'%s==%s' % (OS_XENAPI_PKG, version))
|
||||
fun.execute('unzip', '-d', temp_dir, '%s/*.whl' % temp_dir)
|
||||
is_tmp_dir = True
|
||||
os_xenapi_dir = temp_dir
|
||||
else:
|
||||
# Check current installed os-xenapi package's location
|
||||
LOCATION_KEY = 'Location: '
|
||||
pkg_info = fun.execute('pip', 'show', OS_XENAPI_PKG).split('\n')
|
||||
for line in pkg_info:
|
||||
if line.startswith(LOCATION_KEY):
|
||||
os_xenapi_dir = line[len(LOCATION_KEY):]
|
||||
break
|
||||
return (is_tmp_dir, os_xenapi_dir)
|
||||
|
||||
|
||||
def install_plugins_to_dom0(ssh_client, version=None):
|
||||
is_tmp_dir, dir = get_os_xenapi_dir(version)
|
||||
plugin_location = '%s/%s' % (dir, PKG_PLUGIN_PATH)
|
||||
try:
|
||||
for file in os.listdir(plugin_location):
|
||||
src_file = '%s/%s' % (plugin_location, file)
|
||||
dst_file = '%s/%s' % (DOM0_PLUGIN_PATH, file)
|
||||
ssh_client.scp(src_file, dst_file)
|
||||
ssh_client.ssh('chmod +x %s' % dst_file)
|
||||
finally:
|
||||
if is_tmp_dir:
|
||||
# delete the temp directory.
|
||||
shutil.rmtree(dir)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# argv[1]: dom0's IP address
|
||||
# argv[2]: user name
|
||||
# argv[3]: user passwd
|
||||
# argv[4]: os-xenapi version (default None)
|
||||
ssh_client = SSHClient(sys.argv[1], sys.argv[2], sys.argv[3])
|
||||
version = None
|
||||
if len(sys.argv) > 4:
|
||||
version = sys.argv[4]
|
||||
install_plugins_to_dom0(ssh_client, version)
|
Loading…
Reference in New Issue
Block a user