Do not use cat for file read

Do not use cat for file read:
   it's difficult for debug operations with source data
   YAMLEditor content calls get_content() if not loaded

Change-Id: I75061c067172085de0e5fb1baa051816a4a707eb
This commit is contained in:
Alexey Stepanov 2016-09-15 13:49:22 +03:00
parent be843643fb
commit d9d8c524ef
10 changed files with 145 additions and 142 deletions

View File

@ -837,9 +837,12 @@ def verify_bootstrap_on_node(ip, os_type, uuid=None):
if not uuid: if not uuid:
return return
cmd = "cat /etc/nailgun-agent/config.yaml" with ssh_manager.open_on_remote(
output = yaml.load(ssh_manager.execute_on_remote(ip, cmd)['stdout_str']) ip=ip,
actual_uuid = output.get("runtime_uuid") path='/etc/nailgun-agent/config.yaml') as f:
data = yaml.safe_load(f)
actual_uuid = data.get("runtime_uuid")
assert_equal(actual_uuid, uuid, assert_equal(actual_uuid, uuid,
"Actual uuid {0} is not the same as expected {1}" "Actual uuid {0} is not the same as expected {1}"
.format(actual_uuid, uuid)) .format(actual_uuid, uuid))

View File

@ -19,10 +19,7 @@ from devops.helpers.helpers import wait
from devops.models import DiskDevice from devops.models import DiskDevice
from devops.models import Node from devops.models import Node
from devops.models import Volume from devops.models import Volume
from proboscis.asserts import assert_equal
from proboscis.asserts import assert_true from proboscis.asserts import assert_true
# noinspection PyUnresolvedReferences
from six.moves import cStringIO
import yaml import yaml
from core.helpers.log_helpers import logwrap from core.helpers.log_helpers import logwrap
@ -221,23 +218,17 @@ class AdminActions(BaseActions):
) )
def get_fuel_settings(self): def get_fuel_settings(self):
result = self.ssh_manager.execute_on_remote( return YamlEditor(
ip=self.admin_ip, file_path=FUEL_SETTINGS_YAML,
cmd='cat {cfg_file}'.format(cfg_file=FUEL_SETTINGS_YAML) ip=self.admin_ip
) ).get_content()
return yaml.load(result['stdout_str'])
def save_fuel_settings(self, settings): def save_fuel_settings(self, settings):
cmd = 'echo \'{0}\' > {1}'.format(yaml.dump(settings, with YamlEditor(
default_style='"', file_path=FUEL_SETTINGS_YAML,
default_flow_style=False), ip=self.admin_ip
FUEL_SETTINGS_YAML) ) as data:
result = self.ssh_manager.execute( data.content = settings
ip=self.admin_ip,
cmd=cmd
)
assert_equal(result['exit_code'], 0,
"Saving Fuel settings failed: {0}!".format(result))
@logwrap @logwrap
def get_tasks_description(self, release=None): def get_tasks_description(self, release=None):
@ -249,8 +240,7 @@ class AdminActions(BaseActions):
if not release: if not release:
release = '' release = ''
cmd = "cat `find /etc/puppet/{} -name tasks.yaml`".format(release) cmd = "cat `find /etc/puppet/{} -name tasks.yaml`".format(release)
data = self.ssh_manager.execute_on_remote(self.admin_ip, cmd) return self.ssh_manager.check_call(self.admin_ip, cmd).stdout_yaml
return yaml.load(cStringIO(''.join(data['stdout'])))
class NailgunActions(BaseActions): class NailgunActions(BaseActions):
@ -258,15 +248,11 @@ class NailgunActions(BaseActions):
def update_nailgun_settings(self, settings): def update_nailgun_settings(self, settings):
cfg_file = '/etc/nailgun/settings.yaml' cfg_file = '/etc/nailgun/settings.yaml'
with self.ssh_manager.open_on_remote(self.admin_ip, cfg_file) as f: with YamlEditor(file_path=cfg_file, ip=self.admin_ip) as ng_settings:
ng_settings = yaml.load(f) ng_settings.content.update(settings)
ng_settings.update(settings) logger.debug('Uploading new nailgun settings: {}'.format(
logger.debug('Uploading new nailgun settings: {!r}'.format( ng_settings))
ng_settings))
with self.ssh_manager.open_on_remote(
self.admin_ip, cfg_file, "w") as f:
yaml.dump(ng_settings, f)
self.restart_service("nailgun") self.restart_service("nailgun")
def set_collector_address(self, host, port, ssl=False): def set_collector_address(self, host, port, ssl=False):

View File

@ -1081,7 +1081,7 @@ def get_quantity_of_numa(ip):
numa = int(SSHManager().check_call( numa = int(SSHManager().check_call(
ip=ip, ip=ip,
command="lstopo | grep NUMANode| wc -l" command="lstopo | grep -c NUMANode"
).stdout[0]) ).stdout[0])
if not numa: if not numa:
@ -1505,18 +1505,43 @@ class YamlEditor(object):
""" """
def __init__(self, file_path, ip=None, port=None): def __init__(self, file_path, ip=None, port=None):
self.file_path = file_path """YAML files editor
:type file_path: str
:type ip: str
:type port: int
"""
self.__file_path = file_path
self.ip = ip self.ip = ip
self.port = port or 22 self.port = port or 22
self.content = None self.__content = None
self.original_content = None self.__original_content = None
@property
def file_path(self):
"""Open file path
:rtype: str
"""
return self.__file_path
@property
def content(self):
if self.__content is None:
self.__content = self.get_content()
return self.__content
@content.setter
def content(self, new_content):
self.__content = new_content
def __get_file(self, mode="r"): def __get_file(self, mode="r"):
if self.ip: if self.ip:
return SSHManager().open_on_remote(self.ip, self.file_path, return SSHManager().open_on_remote(
mode=mode, port=self.port) self.ip, self.__file_path,
mode=mode, port=self.port)
else: else:
return open(self.file_path, mode) return open(self.__file_path, mode)
def get_content(self): def get_content(self):
with self.__get_file() as file_obj: with self.__get_file() as file_obj:
@ -1531,12 +1556,12 @@ class YamlEditor(object):
default_style='"') default_style='"')
def __enter__(self): def __enter__(self):
self.content = self.get_content() self.__content = self.get_content()
self.original_content = copy.deepcopy(self.content) self.__original_content = copy.deepcopy(self.content)
return self return self
def __exit__(self, x, y, z): def __exit__(self, x, y, z):
if self.content == self.original_content: if self.content == self.__original_content:
return return
self.write_content() self.write_content()

View File

@ -693,28 +693,26 @@ class EnvironmentModel(six.with_metaclass(SingletonMeta, object)):
if nameservers is None: if nameservers is None:
nameservers = [] nameservers = []
resolv_conf = self.ssh_manager.execute( with self.ssh_manager.open_on_remote(
ip=self.ssh_manager.admin_ip, ip=self.ssh_manager.admin_ip,
cmd='cat /etc/resolv.conf' path='/etc/resolv.conf',
) ) as f:
assert_equal(0, resolv_conf['exit_code'], resolv_conf = f.readlines()
'Executing "{0}" on the admin node has failed with: {1}'
.format('cat /etc/resolv.conf', resolv_conf['stderr']))
if merge: if merge:
nameservers.extend(resolv_conf['stdout']) nameservers.extend(resolv_conf)
resolv_keys = ['search', 'domain', 'nameserver'] resolv_keys = ['search', 'domain', 'nameserver']
resolv_new = "".join('{0}\n'.format(ns) for ns in nameservers resolv_new = "".join(
if any(x in ns for x in resolv_keys)) '{0}\n'.format(ns) for ns in nameservers
logger.debug('echo "{0}" > /etc/resolv.conf'.format(resolv_new)) if any(x in ns for x in resolv_keys))
echo_cmd = 'echo "{0}" > /etc/resolv.conf'.format(resolv_new) with self.ssh_manager.open_on_remote(
echo_result = self.ssh_manager.execute( ip=self.ssh_manager.admin_ip,
ip=self.ssh_manager.admin_ip, path='/etc/resolv.conf',
cmd=echo_cmd mode='w'
) ) as f:
assert_equal(0, echo_result['exit_code'], f.write(resolv_new)
'Executing "{0}" on the admin node has failed with: {1}'
.format(echo_cmd, echo_result['stderr'])) return resolv_conf
return resolv_conf['stdout']
@logwrap @logwrap
def describe_other_admin_interfaces(self, admin): def describe_other_admin_interfaces(self, admin):

View File

@ -455,8 +455,8 @@ class FuelWebClient29(object):
def get_pcm_nodes(self, ctrl_node, pure=False): def get_pcm_nodes(self, ctrl_node, pure=False):
nodes = {} nodes = {}
with self.get_ssh_for_node(ctrl_node) as remote: with self.get_ssh_for_node(ctrl_node) as remote:
pcs_status = remote.execute('pcs status nodes')['stdout'] pcm_nodes = remote.execute('pcs status nodes').stdout_yaml
pcm_nodes = yaml.load(''.join(pcs_status).strip())
for status in ('Online', 'Offline', 'Standby'): for status in ('Online', 'Offline', 'Standby'):
list_nodes = (pcm_nodes['Pacemaker Nodes'][status] or '').split() list_nodes = (pcm_nodes['Pacemaker Nodes'][status] or '').split()
if not pure: if not pure:
@ -2677,8 +2677,8 @@ class FuelWebClient29(object):
def get_nailgun_primary_node(self, slave, role='primary-controller'): def get_nailgun_primary_node(self, slave, role='primary-controller'):
# returns controller or mongo that is primary in nailgun # returns controller or mongo that is primary in nailgun
with self.get_ssh_for_node(slave.name) as remote: with self.get_ssh_for_node(slave.name) as remote:
data = yaml.load(''.join( with remote.open('/etc/astute.yaml') as f:
remote.execute('cat /etc/astute.yaml')['stdout'])) data = yaml.safe_load(f)
nodes = data['network_metadata']['nodes'] nodes = data['network_metadata']['nodes']
node_name = [node['fqdn'] for node in nodes.values() node_name = [node['fqdn'] for node in nodes.values()
if role in node['node_roles']][0] if role in node['node_roles']][0]

View File

@ -18,8 +18,6 @@ from proboscis import test
# pylint: disable=import-error # pylint: disable=import-error
# noinspection PyUnresolvedReferences # noinspection PyUnresolvedReferences
from six.moves import configparser from six.moves import configparser
# noinspection PyUnresolvedReferences
from six.moves import cStringIO
# pylint: enable=import-error # pylint: enable=import-error
from fuelweb_test.helpers import utils from fuelweb_test.helpers import utils
@ -43,11 +41,12 @@ class EMCPlugin(TestBasic):
@classmethod @classmethod
def check_emc_cinder_config(cls, ip, path): def check_emc_cinder_config(cls, ip, path):
command = 'cat {0}'.format(path) with SSHManager().open_on_remote(
conf_data = SSHManager().execute_on_remote(ip, command)['stdout_str'] ip=ip,
conf_data = cStringIO(conf_data) path=path
cinder_conf = configparser.ConfigParser() ) as f:
cinder_conf.readfp(conf_data) cinder_conf = configparser.ConfigParser()
cinder_conf.readfp(f)
asserts.assert_equal( asserts.assert_equal(
cinder_conf.get('DEFAULT', 'volume_driver'), cinder_conf.get('DEFAULT', 'volume_driver'),

View File

@ -30,6 +30,7 @@ from fuelweb_test.helpers.checkers import fail_deploy
from fuelweb_test.helpers.checkers import incomplete_deploy from fuelweb_test.helpers.checkers import incomplete_deploy
from fuelweb_test.helpers.checkers import incomplete_tasks from fuelweb_test.helpers.checkers import incomplete_tasks
from fuelweb_test.helpers.ssl_helpers import change_cluster_ssl_config from fuelweb_test.helpers.ssl_helpers import change_cluster_ssl_config
from fuelweb_test.helpers import utils
from fuelweb_test.tests.base_test_case import TestBasic from fuelweb_test.tests.base_test_case import TestBasic
from fuelweb_test import logger from fuelweb_test import logger
from fuelweb_test.helpers.utils import hiera_json_out from fuelweb_test.helpers.utils import hiera_json_out
@ -81,25 +82,24 @@ class CommandLine(TestBasic):
@logwrap @logwrap
def get_networks(self, cluster_id): def get_networks(self, cluster_id):
net_file = self.get_network_filename(cluster_id) net_file = self.get_network_filename(cluster_id)
out = self.ssh_manager.execute_on_remote( with self.ssh_manager.open_on_remote(
ip=self.ssh_manager.admin_ip, ip=self.ssh_manager.admin_ip,
cmd='cat {0}'.format(net_file), path=net_file
jsonify=True ) as f:
)['stdout_json'] return json.load(f)
return out
@logwrap @logwrap
def update_network(self, cluster_id, net_config): def update_network(self, cluster_id, net_config):
net_file = self.get_network_filename(cluster_id) net_file = self.get_network_filename(cluster_id)
data = json.dumps(net_config) with self.ssh_manager.open_on_remote(
cmd = 'echo {data} > {net_file}'.format(data=json.dumps(data), ip=self.ssh_manager.admin_ip,
net_file=net_file) path=net_file,
self.ssh_manager.execute_on_remote( mode='w'
ip=self.ssh_manager.admin_ip, ) as f:
cmd=cmd json.dump(net_config, f)
)
cmd = ('cd /tmp; fuel --env {0} network --upload --json' cmd = 'cd /tmp; fuel --env {0} network --upload --json'.format(
.format(cluster_id)) cluster_id)
self.ssh_manager.execute_on_remote( self.ssh_manager.execute_on_remote(
ip=self.ssh_manager.admin_ip, ip=self.ssh_manager.admin_ip,
cmd=cmd cmd=cmd
@ -270,24 +270,22 @@ class CommandLine(TestBasic):
ip=self.ssh_manager.admin_ip, ip=self.ssh_manager.admin_ip,
cmd=cmd cmd=cmd
) )
out = self.ssh_manager.execute_on_remote( with self.ssh_manager.open_on_remote(
ip=self.ssh_manager.admin_ip, ip=self.ssh_manager.admin_ip,
cmd='cd /tmp && cat settings_{0}.json'.format(cluster_id), path='/tmp/settings_{0}.json'.format(cluster_id)
jsonify=True ) as f:
)['stdout_json'] return json.load(f)
return out
def upload_settings(self, cluster_id, settings): def upload_settings(self, cluster_id, settings):
data = json.dumps(settings) with self.ssh_manager.open_on_remote(
cmd = 'cd /tmp && echo {data} > settings_{id}.json'.format( ip=self.ssh_manager.admin_ip,
data=json.dumps(data), path='/tmp/settings_{id}.json'.format(id=cluster_id),
id=cluster_id) mode='w'
self.ssh_manager.execute_on_remote( ) as f:
ip=self.ssh_manager.admin_ip, json.dump(settings, f)
cmd=cmd
) cmd = 'fuel --env {0} settings --upload --dir /tmp --json'.format(
cmd = ('fuel --env {0} settings --upload --dir /tmp --json'.format( cluster_id)
cluster_id))
self.ssh_manager.execute_on_remote( self.ssh_manager.execute_on_remote(
ip=self.ssh_manager.admin_ip, ip=self.ssh_manager.admin_ip,
cmd=cmd cmd=cmd
@ -402,22 +400,24 @@ class CommandLine(TestBasic):
ip=self.ssh_manager.admin_ip, ip=self.ssh_manager.admin_ip,
cmd=cmd cmd=cmd
) )
out = self.ssh_manager.execute_on_remote( with self.ssh_manager.open_on_remote(
ip=self.ssh_manager.admin_ip, ip=self.ssh_manager.admin_ip,
cmd='cd /tmp && cat node_{}/interfaces.json'.format(node_id), path='/tmp/node_{}/interfaces.json'.format(node_id)
jsonify=True ) as f:
)['stdout_json'] return json.load(f)
return out
def upload_node_interfaces(self, node_id, interfaces): def upload_node_interfaces(self, node_id, interfaces):
data = json.dumps(interfaces) self.ssh_manager.mkdir_on_remote(
cmd = 'cd /tmp && echo {data} > node_{id}/interfaces.json'.format(
data=json.dumps(data),
id=node_id)
self.ssh_manager.execute_on_remote(
ip=self.ssh_manager.admin_ip, ip=self.ssh_manager.admin_ip,
cmd=cmd path='/tmp/node_{id}'.format(id=node_id)
) )
with self.ssh_manager.open_on_remote(
ip=self.ssh_manager.admin_ip,
path='/tmp/node_{id}/interfaces.json'.format(id=node_id),
mode='w'
) as f:
json.dump(interfaces, f)
cmd = ('fuel node --node-id {} --network --upload --dir /tmp' cmd = ('fuel node --node-id {} --network --upload --dir /tmp'
' --json'.format(node_id)) ' --json'.format(node_id))
self.ssh_manager.execute_on_remote( self.ssh_manager.execute_on_remote(
@ -457,44 +457,38 @@ class CommandLine(TestBasic):
task_id = all_deployment_tasks[0]['id'] task_id = all_deployment_tasks[0]['id']
cmd = 'fuel2 task network-configuration download {0}'.format(task_id) cmd = 'fuel2 task network-configuration download {0}'.format(task_id)
out = self.ssh_manager.execute_on_remote( settings_download = self.ssh_manager.execute_on_remote(
ip=self.ssh_manager.admin_ip, ip=self.ssh_manager.admin_ip,
cmd=cmd cmd=cmd
)['stdout'] )['stdout_str']
settings_download = ''.join(out)
settings_file = settings_download.split()[-1] settings_file = settings_download.split()[-1]
out = self.ssh_manager.execute_on_remote( return utils.YamlEditor(
ip=self.ssh_manager.admin_ip, file_path=settings_file,
cmd='cat {0}'.format(settings_file), ip=self.ssh_manager.admin_ip
yamlify=True)['stdout_yaml'] ).get_content()
return out
@logwrap @logwrap
def get_cluster_config_cli(self, task_id): def get_cluster_config_cli(self, task_id):
cmd = 'fuel2 task settings download {0}'.format(task_id) cmd = 'fuel2 task settings download {0}'.format(task_id)
out = self.ssh_manager.execute_on_remote( settings_download = self.ssh_manager.execute_on_remote(
ip=self.ssh_manager.admin_ip, ip=self.ssh_manager.admin_ip,
cmd=cmd cmd=cmd
)['stdout'] )['stdout_str']
settings_download = ''.join(out)
settings_file = settings_download.split()[-1] settings_file = settings_download.split()[-1]
out = self.ssh_manager.execute_on_remote( return utils.YamlEditor(
file_path=settings_file,
ip=self.ssh_manager.admin_ip, ip=self.ssh_manager.admin_ip,
cmd='cat {0}'.format(settings_file), ).get_content()
yamlify=True)['stdout_yaml']
return out
@logwrap @logwrap
def get_deployment_info_cli(self, task_id): def get_deployment_info_cli(self, task_id):
cmd = 'fuel2 task deployment-info download {0}'.format(task_id) cmd = 'fuel2 task deployment-info download {0}'.format(task_id)
out = self.ssh_manager.execute_on_remote( settings_download = self.ssh_manager.execute_on_remote(
ip=self.ssh_manager.admin_ip, ip=self.ssh_manager.admin_ip,
cmd=cmd cmd=cmd
)['stdout'] )['stdout_str']
settings_download = ''.join(out)
settings_file = settings_download.split()[-1] settings_file = settings_download.split()[-1]
out = self.ssh_manager.execute_on_remote( return utils.YamlEditor(
file_path=settings_file,
ip=self.ssh_manager.admin_ip, ip=self.ssh_manager.admin_ip,
cmd='cat {0}'.format(settings_file), ).get_content()
yamlify=True)['stdout_yaml']
return out

View File

@ -104,7 +104,7 @@ class TestMultipath(base_test_case.TestBasic):
:rtype: int :rtype: int
""" """
cmd = "lsblk -lo NAME,TYPE,MOUNTPOINT | grep '/$' | grep lvm | wc -l" cmd = "lsblk -lo NAME,TYPE,MOUNTPOINT | grep '/$' | grep -c lvm"
ssh_manager.update_connection(ip, SSH_FUEL_CREDENTIALS['login'], ssh_manager.update_connection(ip, SSH_FUEL_CREDENTIALS['login'],
SSH_FUEL_CREDENTIALS['password'], SSH_FUEL_CREDENTIALS['password'],

View File

@ -285,7 +285,7 @@ class TestVirtRoleBaremetal(TestBasic):
with self.ssh_manager.get_remote(self.ssh_manager.admin_ip) as admin: with self.ssh_manager.get_remote(self.ssh_manager.admin_ip) as admin:
result = admin.execute_through_host( result = admin.execute_through_host(
slave_ip, slave_ip,
"cat /proc/cpuinfo | grep processor | wc -l", "grep -c processor /proc/cpuinfo",
auth=self.ssh_auth, auth=self.ssh_auth,
timeout=60) timeout=60)
asserts.assert_equal( asserts.assert_equal(

View File

@ -28,7 +28,6 @@ from proboscis import SkipTest
# noinspection PyUnresolvedReferences # noinspection PyUnresolvedReferences
from six.moves import xrange from six.moves import xrange
# pylint: enable=redefined-builtin # pylint: enable=redefined-builtin
import yaml
from core.helpers.log_helpers import logwrap from core.helpers.log_helpers import logwrap
@ -1116,8 +1115,7 @@ class TestHaFailoverBase(TestBasic):
@logwrap @logwrap
def _get_pcm_nodes(remote, pure=False): def _get_pcm_nodes(remote, pure=False):
nodes = {} nodes = {}
pcs_status = remote.execute('pcs status nodes')['stdout'] pcm_nodes = remote.execute('pcs status nodes').stdout_yaml
pcm_nodes = yaml.load(''.join(pcs_status).strip())
for status in ('Online', 'Offline', 'Standby'): for status in ('Online', 'Offline', 'Standby'):
list_nodes = (pcm_nodes['Pacemaker Nodes'] list_nodes = (pcm_nodes['Pacemaker Nodes']
[status] or '').split() [status] or '').split()