Merge "Introduction of new method of SSH connection"

This commit is contained in:
Jenkins 2015-12-21 23:23:21 +00:00 committed by Gerrit Code Review
commit c5bc4943b1
10 changed files with 436 additions and 133 deletions

View File

@ -117,3 +117,8 @@ Utils
-----
.. automodule:: fuelweb_test.helpers.utils
:members:
SSH Manager
-----------
.. automodule:: fuelweb_test.helpers.ssh_manager
:members:

View File

@ -342,23 +342,22 @@ def retry(count=3, delay=30):
def custom_repo(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
with args[0].environment.d_env.get_admin_remote() as remote:
custom_pkgs = CustomRepo(remote)
try:
if settings.CUSTOM_PKGS_MIRROR:
custom_pkgs.prepare_repository()
custom_pkgs = CustomRepo()
try:
if settings.CUSTOM_PKGS_MIRROR:
custom_pkgs.prepare_repository()
except Exception:
logger.error("Unable to get custom packages from {0}\n{1}"
.format(settings.CUSTOM_PKGS_MIRROR,
traceback.format_exc()))
raise
except Exception:
logger.error("Unable to get custom packages from {0}\n{1}"
.format(settings.CUSTOM_PKGS_MIRROR,
traceback.format_exc()))
raise
try:
return func(*args, **kwargs)
except Exception:
custom_pkgs.check_puppet_logs()
raise
try:
return func(*args, **kwargs)
except Exception:
custom_pkgs.check_puppet_logs()
raise
return wrapper

View File

@ -31,7 +31,7 @@ from fuelweb_test.helpers.decorators import retry
from fuelweb_test.helpers.regenerate_repo import regenerate_centos_repo
from fuelweb_test.helpers.regenerate_repo import regenerate_ubuntu_repo
from fuelweb_test.helpers import replace_repos
from fuelweb_test.helpers.utils import cond_upload
from fuelweb_test.helpers.ssh_manager import SSHManager
from fuelweb_test.settings import MASTER_IS_CENTOS7
from fuelweb_test.settings import FUEL_PLUGIN_BUILDER_REPO
from fuelweb_test.settings import FUEL_USE_LOCAL_NTPD
@ -43,8 +43,9 @@ from fuelweb_test.settings import NESSUS_IMAGE_PATH
class BaseActions(object):
"""BaseActions.""" # TODO documentation
def __init__(self, admin_remote):
self.admin_remote = admin_remote
def __init__(self):
self.ssh_manager = SSHManager()
self.admin_ip = self.ssh_manager.admin_ip
self.container = None
def __repr__(self):
@ -62,7 +63,11 @@ class BaseActions(object):
cmd = 'dockerctl shell {0} {1}'.format(container, command)
if stdin is not None:
cmd = 'echo "{0}" | {1}'.format(stdin, cmd)
result = self.admin_remote.execute(cmd)
result = self.ssh_manager.execute_on_remote(
ip=self.admin_ip,
cmd=cmd
)
if exit_code is not None:
assert_equal(exit_code,
result['exit_code'],
@ -93,7 +98,10 @@ class BaseActions(object):
Standard output from console
"""
cmd = 'dockerctl copy {0} {1}'.format(copy_from, copy_to)
result = self.admin_remote.execute(cmd)
result = self.ssh_manager.execute_on_remote(
ip=self.admin_ip,
cmd=cmd
)
assert_equal(0, result['exit_code'],
('Command copy returned exit code "{e}", but '
'expected "0". Output: {out}; {err} ').format(
@ -105,8 +113,10 @@ class BaseActions(object):
@property
def is_container_ready(self):
result = self.admin_remote.execute("timeout 5 dockerctl check {0}"
.format(self.container))
result = self.ssh_manager.execute_on_remote(
ip=self.admin_ip,
cmd="timeout 5 dockerctl check {0}".format(self.container)
)
return result['exit_code'] == 0
def wait_for_ready_container(self, timeout=300):
@ -179,9 +189,17 @@ class BaseActions(object):
self.copy_between_node_and_container(
'{0}:{1}'.format(container, path_to_file), old_file)
self.admin_remote.download(old_file, old_file)
self.ssh_manager.download_from_remote(
ip=self.admin_ip,
destination=old_file,
target=old_file
)
self.put_value_to_local_yaml(old_file, new_file, element, value)
self.admin_remote.upload(new_file, new_file)
self.ssh_manager.upload_to_remote(
ip=self.admin_ip,
source=new_file,
target=new_file
)
self.copy_between_node_and_container(
new_file, '{0}:{1}'.format(container, path_to_file))
os.remove(old_file)
@ -204,8 +222,11 @@ class BaseActions(object):
admin_tmp_file = path_to_file
host_tmp_file = '/tmp/temp_file_{0}.yaml'.format(str(os.getpid()))
self.admin_remote.download(admin_tmp_file, host_tmp_file)
self.ssh_manager.download_from_remote(
ip=self.admin_ip,
destination=admin_tmp_file,
target=host_tmp_file
)
value = self.get_value_from_local_yaml(host_tmp_file, element)
os.remove(host_tmp_file)
return value
@ -228,11 +249,18 @@ class BaseActions(object):
admin_tmp_file = path_to_file
host_tmp_file = '/tmp/temp_file_{0}.yaml'.format(str(os.getpid()))
self.admin_remote.download(admin_tmp_file, host_tmp_file)
self.ssh_manager.download_from_remote(
ip=self.admin_ip,
destination=admin_tmp_file,
target=host_tmp_file
)
self.put_value_to_local_yaml(host_tmp_file, host_tmp_file,
element, value)
self.admin_remote.upload(host_tmp_file, admin_tmp_file)
self.ssh_manager.upload_to_remote(
ip=self.admin_ip,
source=host_tmp_file,
target=admin_tmp_file
)
if self.container:
self.copy_between_node_and_container(
admin_tmp_file, '{0}:{1}'.format(self.container, path_to_file))
@ -242,8 +270,8 @@ class BaseActions(object):
class AdminActions(BaseActions):
""" All actions relating to the admin node."""
def __init__(self, admin_remote):
super(AdminActions, self).__init__(admin_remote)
def __init__(self):
super(AdminActions, self).__init__()
@logwrap
def modify_configs(self, router):
@ -258,7 +286,8 @@ class AdminActions(BaseActions):
# for admin node
cmd = 'ntpdate -p 4 -t 0.2 -ub {0}'.format(router)
if not self.admin_remote.execute(cmd)['exit_code']:
if not self.ssh_manager.execute_on_remote(ip=self.admin_ip,
cmd=cmd)['exit_code']:
# Local ntpd on the host is alive, so
# remove all NTP sources and add the host instead.
logger.info("Switching NTPD on the Fuel admin node to use "
@ -290,43 +319,53 @@ class AdminActions(BaseActions):
ubuntu_files_count = 0
if centos_repo_path:
centos_files_count = cond_upload(
self.admin_remote, local_packages_dir,
os.path.join(centos_repo_path, 'Packages'),
"(?i).*\.rpm$")
centos_files_count = self.ssh_manager.cond_upload(
ip=self.admin_ip,
source=local_packages_dir,
target=os.path.join(centos_repo_path, 'Packages'),
condition="(?i).*\.rpm$"
)
if centos_files_count > 0:
regenerate_centos_repo(self.admin_remote, centos_repo_path)
regenerate_centos_repo(centos_repo_path)
if ubuntu_repo_path:
ubuntu_files_count = cond_upload(
self.admin_remote, local_packages_dir,
os.path.join(ubuntu_repo_path, 'pool/main'),
"(?i).*\.deb$")
ubuntu_files_count = self.ssh_manager.cond_upload(
ip=self.admin_ip,
source=local_packages_dir,
target=os.path.join(ubuntu_repo_path, 'pool/main'),
condition="(?i).*\.deb$"
)
if ubuntu_files_count > 0:
regenerate_ubuntu_repo(self.admin_remote, ubuntu_repo_path)
regenerate_ubuntu_repo(ubuntu_repo_path)
return centos_files_count, ubuntu_files_count
@logwrap
def clean_generated_image(self, distro):
images = ''.join(
self.admin_remote.execute(
"find /var/www/nailgun/targetimages/ -name"
" 'env*{}*' -printf '%P\n'".format(distro.lower())))
out = self.ssh_manager.execute_on_remote(
ip=self.admin_ip,
cmd="find /var/www/nailgun/targetimages/ -name "
"'env*{}*' -printf '%P\n'".format(distro.lower())
)
images = ''.join(out)
logger.debug("images are {}".format(images))
self.admin_remote.execute(
"find /var/www/nailgun/targetimages/ -name 'env*{}*'"
" -delete".format(distro.lower()))
self.ssh_manager.execute_on_remote(
ip=self.admin_ip,
cmd="find /var/www/nailgun/targetimages/ -name 'env*{}*'"
" -delete".format(distro.lower())
)
@logwrap
@retry(2)
def untar(self, node_ssh, name, path):
def untar(self, node_ip, name, path):
logger.info('Unpacking file')
filename, ext = os.path.splitext(name)
cmd = "tar -xpvf" if ext.endswith("tar") else "lrzuntar"
result = node_ssh.execute(
'cd {0} && {2} {1}'.format(path, name, cmd))
result = self.ssh_manager.execute_on_remote(
ip=node_ip,
cmd='cd {0} && {2} {1}'.format(path, name, cmd)
)
stdout, stderr = ''.join(result['stdout']), ''.join(result['stderr'])
logger.debug('Result from tar command is {0}\n{1}'.format(stdout,
stderr))
@ -334,6 +373,7 @@ class AdminActions(BaseActions):
def upgrade_master_node(self, rollback=False, file_upload=True):
"""This method upgrades master node with current state."""
# TODO: It will be remooved or changed
master = self.admin_remote
if file_upload:
@ -367,8 +407,10 @@ class AdminActions(BaseActions):
def get_fuel_settings(self):
cmd = 'cat {cfg_file}'.format(cfg_file=hlp_data.FUEL_SETTINGS_YAML)
result = self.admin_remote.execute(cmd)
result = self.ssh_manager.execute_on_remote(
ip=self.admin_ip,
cmd=cmd
)
if result['exit_code'] == 0:
fuel_settings = yaml.load(''.join(result['stdout']))
else:
@ -382,7 +424,10 @@ class AdminActions(BaseActions):
default_style='"',
default_flow_style=False),
hlp_data.FUEL_SETTINGS_YAML)
result = self.admin_remote.execute(cmd)
result = self.ssh_manager.execute_on_remote(
ip=self.admin_ip,
cmd=cmd
)
assert_equal(result['exit_code'], 0,
"Saving Fuel settings failed: {0}!".format(result))
@ -390,8 +435,8 @@ class AdminActions(BaseActions):
class NailgunActions(BaseActions):
"""NailgunActions.""" # TODO documentation
def __init__(self, admin_remote):
super(NailgunActions, self).__init__(admin_remote)
def __init__(self):
super(NailgunActions, self).__init__()
self.container = 'nailgun'
def update_nailgun_settings_once(self, settings):
@ -461,8 +506,8 @@ class NailgunActions(BaseActions):
class PostgresActions(BaseActions):
"""PostgresActions.""" # TODO documentation
def __init__(self, admin_remote):
super(PostgresActions, self).__init__(admin_remote)
def __init__(self):
super(PostgresActions, self).__init__()
self.container = 'postgres'
def run_query(self, db, query):
@ -493,8 +538,8 @@ class FuelPluginBuilder(BaseActions):
Initializes BaseActions.
"""
def __init__(self, admin_remote):
super(FuelPluginBuilder, self).__init__(admin_remote)
def __init__(self):
super(FuelPluginBuilder, self).__init__()
self.container = 'nailgun'
def fpb_install(self):
@ -562,7 +607,11 @@ class FuelPluginBuilder(BaseActions):
"""
self.execute_in_container(
"rm -rf {0}".format(remote_file), self.container)
self.admin_remote.upload(local_file, "/tmp/temp.file")
self.ssh_manager.upload_to_remote(
ip=self.admin_ip,
source=local_file,
target="/tmp/temp.file"
)
self.copy_between_node_and_container(
'/tmp/temp.file', '{0}:{1}'.format(self.container, remote_file))
@ -594,8 +643,8 @@ class FuelPluginBuilder(BaseActions):
class CobblerActions(BaseActions):
"""CobblerActions.""" # TODO documentation
def __init__(self, admin_remote):
super(CobblerActions, self).__init__(admin_remote)
def __init__(self):
super(CobblerActions, self).__init__()
self.container = 'cobbler'
def add_dns_upstream_server(self, dns_server_ip):
@ -613,18 +662,22 @@ class CobblerActions(BaseActions):
class DockerActions(object):
"""DockerActions.""" # TODO documentation
def __init__(self, admin_remote):
self.admin_remote = admin_remote
def __init__(self):
self.ssh_manager = SSHManager()
def list_containers(self):
return self.admin_remote.execute('dockerctl list')['stdout']
result = self.ssh_manager.execute_on_remote(
ip=self.ssh_manager.admin_ip,
cmd='dockerctl list'
)
return result['stdout']
def wait_for_ready_containers(self, timeout=300):
if MASTER_IS_CENTOS7:
return
cont_actions = []
for container in self.list_containers():
cont_action = BaseActions(self.admin_remote)
cont_action = BaseActions(self.ssh_manager)
cont_action.container = container
cont_actions.append(cont_action)
try:
@ -639,8 +692,11 @@ class DockerActions(object):
.format(failed_containers, timeout))
def restart_container(self, container):
self.admin_remote.execute('dockerctl restart {0}'.format(container))
cont_action = BaseActions(self.admin_remote)
self.ssh_manager.execute_on_remote(
ip=self.ssh_manager.admin_ip,
cmd='dockerctl restart {0}'.format(container)
)
cont_action = BaseActions(self.ssh_manager)
cont_action.container = container
cont_action.wait_for_ready_container()
@ -650,8 +706,10 @@ class DockerActions(object):
def execute_in_containers(self, cmd):
for container in self.list_containers():
self.admin_remote.execute(
"dockerctl shell {0} bash -c '{1}'".format(container, cmd))
self.ssh_manager.execute_on_remote(
ip=self.ssh_manager.admin_ip,
cmd="dockerctl shell {0} bash -c '{1}'".format(container, cmd)
)
class NessusActions(object):

View File

@ -23,19 +23,20 @@ from xml.etree import ElementTree
from fuelweb_test import logger
from fuelweb_test import settings
from fuelweb_test.helpers.utils import install_pkg
from fuelweb_test.helpers.utils import install_pkg_2
from fuelweb_test.helpers.ssh_manager import SSHManager
def regenerate_ubuntu_repo(remote, path):
def regenerate_ubuntu_repo(path):
# Ubuntu
cr = CustomRepo(remote)
cr = CustomRepo()
cr.install_tools(['dpkg', 'dpkg-devel', 'dpkg-dev'])
cr.regenerate_repo('regenerate_ubuntu_repo', path)
def regenerate_centos_repo(remote, path):
def regenerate_centos_repo(path):
# CentOS
cr = CustomRepo(remote)
cr = CustomRepo()
cr.install_tools(['createrepo'])
cr.regenerate_repo('regenerate_centos_repo', path)
@ -43,8 +44,9 @@ def regenerate_centos_repo(remote, path):
class CustomRepo(object):
"""CustomRepo.""" # TODO documentation
def __init__(self, remote):
self.remote = remote
def __init__(self):
self.ssh_manager = SSHManager()
self.ip = self.ssh_manager.admin_ip
self.path_scripts = ('{0}/fuelweb_test/helpers/'
.format(os.environ.get("WORKSPACE", "./")))
self.remote_path_scripts = '/tmp/'
@ -111,7 +113,10 @@ class CustomRepo(object):
logger.info("Installing necessary tools for {0}"
.format(settings.OPENSTACK_RELEASE))
for master_tool in master_tools:
exit_code = install_pkg(self.remote, master_tool)
exit_code = install_pkg_2(
ip=self.ip,
pkg_name=master_tool
)
assert_equal(0, exit_code, 'Cannot install package {0} '
'on admin node.'.format(master_tool))
@ -241,7 +246,10 @@ class CustomRepo(object):
.format(pkgs_local_path + path_suff,
self.custom_pkgs_mirror,
pkg["filename:"])
wget_result = self.remote.execute(wget_cmd)
wget_result = self.ssh_manager.execute_on_remote(
ip=self.ip,
cmd=wget_cmd
)
assert_equal(0, wget_result['exit_code'],
self.assert_msg(wget_cmd, wget_result['stderr']))
@ -250,12 +258,16 @@ class CustomRepo(object):
# Uploading scripts that prepare local repositories:
# 'regenerate_centos_repo' and 'regenerate_ubuntu_repo'
try:
self.remote.upload('{0}/{1}'.format(self.path_scripts,
regenerate_script),
self.remote_path_scripts)
self.remote.execute('chmod 755 {0}/{1}'
.format(self.remote_path_scripts,
regenerate_script))
self.ssh_manager.upload_to_remote(
ip=self.ip,
source='{0}/{1}'.format(self.path_scripts, regenerate_script),
target=self.remote_path_scripts
)
self.ssh_manager.execute_on_remote(
ip=self.ip,
cmd='chmod 755 {0}/{1}'.format(self.remote_path_scripts,
regenerate_script)
)
except Exception:
logger.error('Could not upload scripts for updating repositories.'
'\n{0}'.format(traceback.format_exc()))
@ -266,7 +278,10 @@ class CustomRepo(object):
regenerate_script,
local_mirror_path,
self.ubuntu_release)
script_result = self.remote.execute(script_cmd)
script_result = self.ssh_manager.execute_on_remote(
ip=self.ip,
cmd=script_cmd
)
assert_equal(0, script_result['exit_code'],
self.assert_msg(script_cmd, script_result['stderr']))
@ -301,7 +316,10 @@ class CustomRepo(object):
cmd = ('fgrep -h -e " Depends: " -e "{0}" -e "{1}" '
'/var/log/docker-logs/remote/node-*/'
'puppet*.log'.format(err_start, err_end))
result = self.remote.execute(cmd)['stdout']
result = self.ssh_manager.execute_on_remote(
ip=self.ip,
cmd=cmd
)['stdout']
err_deps = {}
err_deps_key = ''
@ -338,7 +356,10 @@ class CustomRepo(object):
cmd = ('fgrep -h -e "Error: Package: " -e " Requires: " /var/log/'
'docker-logs/remote/node-*/puppet*.log')
result = self.remote.execute(cmd)['stdout']
result = self.ssh_manager.execute_on_remote(
ip=self.ip,
cmd=cmd
)['stdout']
err_deps = {}
err_deps_key = ''

View File

@ -0,0 +1,197 @@
# Copyright 2015 Mirantis, Inc.
#
# 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 os
import posixpath
import re
from paramiko import RSAKey
from devops.models.node import SSHClient
from fuelweb_test import logger
class SingletonMeta(type):
def __init__(cls, name, bases, dict):
super(SingletonMeta, cls).__init__(name, bases, dict)
cls.instance = None
def __call__(self, *args, **kw):
if self.instance is None:
self.instance = super(SingletonMeta, self).__call__(*args, **kw)
return self.instance
def __getattr__(cls, name):
return getattr(cls(), name)
class SSHManager(object):
__metaclass__ = SingletonMeta
def __init__(self):
logger.debug('SSH_MANAGER: Run constructor SSHManager')
self.connections = {}
self.admin_ip = None
self.admin_port = None
self.login = None
self.password = None
def initialize(self, admin_ip, login, password):
""" It will be moved to __init__
:param admin_ip: ip address of admin node
:param login: user name
:param password: password for user
:return: None
"""
self.admin_ip = admin_ip
self.admin_port = 22
self.login = login
self.password = password
def _connect(self, remote):
""" Check if connection is stable and return this one
:param remote:
:return:
"""
try:
remote.execute("cd ~")
except Exception:
remote.reconnect()
return remote
def _get_keys(self):
keys = []
admin_remote = self._get_remote(self.admin_ip)
for key_string in ['/root/.ssh/id_rsa', '/root/.ssh/bootstrap.rsa']:
with admin_remote.open(key_string) as f:
keys.append(RSAKey.from_private_key(f))
return keys
def _get_remote(self, ip, port=22):
""" Function returns remote SSH connection to node by ip address
:param ip: IP of host
:param port: port for SSH
:return: SSHClient
"""
if (ip, port) not in self.connections:
logger.debug('SSH_MANAGER:Create new connection for '
'{ip}:{port}'.format(ip=ip, port=port))
keys = self._get_keys() if ip != self.admin_ip else []
self.connections[(ip, port)] = SSHClient(
host=ip,
port=port,
username=self.login,
password=self.password,
private_keys=keys
)
logger.debug('SSH_MANAGER:Return existed connection for '
'{ip}:{port}'.format(ip=ip, port=port))
logger.debug('SSH_MANAGER: Connections {0}'.format(self.connections))
return self._connect(self.connections[(ip, port)])
def execute_on_remote(self, ip, cmd, port=22):
remote = self._get_remote(ip=ip, port=port)
return remote.execute(cmd)
def open_on_remote(self, ip, path, mode='r', port=22):
remote = self._get_remote(ip=ip, port=port)
return remote.open(path, mode)
def upload_to_remote(self, ip, source, target, port=22):
remote = self._get_remote(ip=ip, port=port)
return remote.upload(source, target)
def download_from_remote(self, ip, destination, target, port=22):
remote = self._get_remote(ip=ip, port=port)
return remote.download(destination, target)
def exist_on_remote(self, ip, path, port=22):
remote = self._get_remote(ip=ip, port=port)
return remote.exist(path)
def isdir_on_remote(self, ip, path, port=22):
remote = self._get_remote(ip=ip, port=port)
return remote.isdir(path)
def isfile_on_remote(self, ip, path, port=22):
remote = self._get_remote(ip=ip, port=port)
return remote.isfile(path)
def mkdir_on_remote(self, ip, path, port=22):
remote = self._get_remote(ip=ip, port=port)
return remote.mkdir(path)
def rm_rf_on_remote(self, ip, path, port=22):
remote = self._get_remote(ip=ip, port=port)
return remote.rm_rf(path)
def cond_upload(self, ip, source, target, port=22, condition=''):
""" Upload files only if condition in regexp matches filenames
:param ip: host ip
:param source: source path
:param target: destination path
:param port: ssh port
:param condition: regexp condition
:return: count of files
"""
# remote = self._get_remote(ip=ip, port=port)
# maybe we should use SSHClient function. e.g. remote.isdir(target)
# we can move this function to some *_actions class
if self.isdir_on_remote(ip=ip, port=port, path=target):
target = posixpath.join(target, os.path.basename(source))
source = os.path.expanduser(source)
if not os.path.isdir(source):
if re.match(condition, source):
self.upload_to_remote(ip=ip, port=port,
source=source, target=target)
logger.debug("File '{0}' uploaded to the remote folder"
" '{1}'".format(source, target))
return 1
else:
logger.debug("Pattern '{0}' doesn't match the file '{1}', "
"uploading skipped".format(condition, source))
return 0
files_count = 0
for rootdir, subdirs, files in os.walk(source):
targetdir = os.path.normpath(
os.path.join(
target,
os.path.relpath(rootdir, source))).replace("\\", "/")
self.mkdir_on_remote(ip=ip, port=port, path=targetdir)
for entry in files:
local_path = os.path.join(rootdir, entry)
remote_path = posixpath.join(targetdir, entry)
if re.match(condition, local_path):
self.upload_to_remote(ip=ip,
port=port,
source=local_path,
target=remote_path)
files_count += 1
logger.debug("File '{0}' uploaded to the "
"remote folder '{1}'".format(source, target))
else:
logger.debug("Pattern '{0}' doesn't match the file '{1}', "
"uploading skipped".format(condition,
local_path))
return files_count

View File

@ -29,6 +29,7 @@ from proboscis import asserts
from fuelweb_test import logger
from fuelweb_test import logwrap
from fuelweb_test import settings
from fuelweb_test.helpers.ssh_manager import SSHManager
from fuelweb_test.settings import MASTER_IS_CENTOS7
from gates_tests.helpers import exceptions
@ -302,6 +303,34 @@ def install_pkg(remote, pkg_name):
return remote_status['exit_code']
def install_pkg_2(ip, pkg_name, port=22):
"""Install a package <pkg_name> on node
:param ip: ip of node
:param pkg_name: name of a package
:param port: ssh port
:return: exit code of installation
"""
ssh_manager = SSHManager()
remote_status = ssh_manager.execute_on_remote(
ip=ip,
port=port,
cmd="rpm -q '{0}'".format(pkg_name)
)
if remote_status['exit_code'] == 0:
logger.info("Package '{0}' already installed.".format(pkg_name))
else:
logger.info("Installing package '{0}' ...".format(pkg_name))
remote_status = ssh_manager.execute_on_remote(
ip=ip,
port=port,
cmd="yum -y install {0}".format(pkg_name)
)
logger.info("Installation of the package '{0}' has been"
" completed with exit code {1}"
.format(pkg_name, remote_status['exit_code']))
return remote_status['exit_code']
def cond_upload(remote, source, target, condition=''):
# Upload files only if condition in regexp matches filenames
if remote.isdir(target):

View File

@ -37,6 +37,7 @@ from fuelweb_test.helpers.fuel_actions import NailgunActions
from fuelweb_test.helpers.fuel_actions import PostgresActions
from fuelweb_test.helpers.fuel_actions import NessusActions
from fuelweb_test.helpers.ntp import GroupNtpSync
from fuelweb_test.helpers.ssh_manager import SSHManager
from fuelweb_test.helpers.utils import run_on_remote
from fuelweb_test.helpers.utils import TimeStat
from fuelweb_test.helpers import multiple_networks_hacks
@ -66,11 +67,23 @@ class EnvironmentModel(object):
self._fuel_web = None
if not hasattr(self, "_config"):
self._config = None
self.ssh_manager = SSHManager()
self.ssh_manager.initialize(
self.get_admin_node_ip(),
login=settings.SSH_CREDENTIALS['login'],
password=settings.SSH_CREDENTIALS['password']
)
self.admin_actions = AdminActions()
self.base_actions = BaseActions()
self.cobbler_actions = CobblerActions()
self.docker_actions = DockerActions()
self.nailgun_actions = NailgunActions()
self.postgres_actions = PostgresActions()
@property
def fuel_web(self):
if self._fuel_web is None:
self._fuel_web = FuelWebClient(self.get_admin_node_ip(), self)
self._fuel_web = FuelWebClient(self)
return self._fuel_web
def __repr__(self):
@ -83,30 +96,6 @@ class EnvironmentModel(object):
obj_id=obj_id,
ip=ip)
@property
def admin_actions(self):
return AdminActions(self.d_env.get_admin_remote())
@property
def base_actions(self):
return BaseActions(self.d_env.get_admin_remote())
@property
def nailgun_actions(self):
return NailgunActions(self.d_env.get_admin_remote())
@property
def postgres_actions(self):
return PostgresActions(self.d_env.get_admin_remote())
@property
def cobbler_actions(self):
return CobblerActions(self.d_env.get_admin_remote())
@property
def docker_actions(self):
return DockerActions(self.d_env.get_admin_remote())
@property
def admin_node_ip(self):
return self.fuel_web.admin_node_ip

View File

@ -23,6 +23,7 @@ from devops.error import DevopsCalledProcessError
from devops.error import TimeoutError
from devops.helpers.helpers import _wait
from devops.helpers.helpers import wait
from fuelweb_test.helpers.ssh_manager import SSHManager
from fuelweb_test.helpers.ssl import copy_cert_from_master
from fuelweb_test.helpers.ssl import change_cluster_ssl_config
from ipaddr import IPNetwork
@ -86,9 +87,10 @@ from fuelweb_test.settings import iface_alias
class FuelWebClient(object):
"""FuelWebClient.""" # TODO documentation
def __init__(self, admin_node_ip, environment):
self.admin_node_ip = admin_node_ip
self.client = NailgunClient(admin_node_ip)
def __init__(self, environment):
self.ssh_manager = SSHManager()
self.admin_node_ip = self.ssh_manager.admin_ip
self.client = NailgunClient(self.ssh_manager.admin_ip)
self._environment = environment
self.security = SecurityChecks(self.client, self._environment)
super(FuelWebClient, self).__init__()

View File

@ -20,6 +20,7 @@ from fuelweb_test import logger
from fuelweb_test.helpers.decorators import log_snapshot_after_test
from fuelweb_test.helpers.utils import get_test_method_name
from fuelweb_test.helpers.utils import TimeStat
from fuelweb_test.helpers.ssh_manager import SSHManager
from fuelweb_test.models.environment import EnvironmentModel
from fuelweb_test.settings import REPLACE_DEFAULT_REPOS
from fuelweb_test.settings import REPLACE_DEFAULT_REPOS_ONLY_ONCE
@ -32,8 +33,9 @@ class TestBasic(object):
"""
def __init__(self):
self.env = EnvironmentModel()
self._current_log_step = 0
self.ssh_manager = SSHManager()
self.env = EnvironmentModel()
@property
def test_program(self):

View File

@ -269,21 +269,22 @@ class CommandLineTest(test_cli_base.CommandLine):
'Some slaves do not become online after revert!!'
' Expected {0} Actual {1}'.format(nodes, online_nodes))
with self.env.d_env.get_admin_remote() as remote:
res = remote.execute('fuel --env {0} env delete'
.format(cluster_id))
assert_true(
res['exit_code'] == 0)
res = self.ssh_manager.execute_on_remote(
ip=self.ssh_manager.admin_ip,
cmd='fuel --env {0} env delete'.format(cluster_id)
)
assert_true(res['exit_code'] == 0)
with self.env.d_env.get_admin_remote() as remote:
try:
wait(lambda:
remote.execute("fuel env | awk '{print $1}'"
" | tail -n 1 | grep '^.$'")
['exit_code'] == 1, timeout=60 * 10)
except TimeoutError:
raise TimeoutError(
"cluster {0} was not deleted".format(cluster_id))
try:
wait(lambda:
self.ssh_manager.execute_on_remote(
ip=self.ssh_manager.admin_ip,
cmd="fuel env | awk '{print $1}' | tail -n 1 | "
"grep '^.$'"
)['exit_code'] == 1, timeout=60 * 10)
except TimeoutError:
raise TimeoutError(
"cluster {0} was not deleted".format(cluster_id))
assert_false(
check_cluster_presence(cluster_id, self.env.postgres_actions),