fix runners & new topology tests
Change-Id: Iad6349480024ba321bb2df6b6ffab901542c8ab8
This commit is contained in:
parent
969796b104
commit
fc4225fc99
@ -15,6 +15,8 @@ from oslo_log import log as logging
|
|||||||
from vitrage.tests.base import BaseTest
|
from vitrage.tests.base import BaseTest
|
||||||
from vitrage_tempest_tests.tests.base_mock import BaseMock
|
from vitrage_tempest_tests.tests.base_mock import BaseMock
|
||||||
|
|
||||||
|
import vitrage_tempest_tests.tests.utils as utils
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
@ -30,3 +32,85 @@ class BaseVitrageTest(BaseTest, BaseMock):
|
|||||||
entity_graph = processor.entity_graph
|
entity_graph = processor.entity_graph
|
||||||
mock_graph_output = entity_graph.output_graph()
|
mock_graph_output = entity_graph.output_graph()
|
||||||
LOG.info("The mock graph is : " + mock_graph_output)
|
LOG.info("The mock graph is : " + mock_graph_output)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_flavor_id_from_list():
|
||||||
|
text_out = utils.run_vitrage_command("nova flavor-list")
|
||||||
|
try:
|
||||||
|
flavor_id = utils.get_regex_result("\|\s+(\d+)\s+\|",
|
||||||
|
text_out.splitlines()[3])
|
||||||
|
except Exception as e:
|
||||||
|
LOG.exception("Failed to get flavor id from the list %s ", e)
|
||||||
|
return None
|
||||||
|
|
||||||
|
LOG.debug("The flavor id from the list is " + flavor_id)
|
||||||
|
return flavor_id
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_image_id_from_list():
|
||||||
|
text_out = utils.run_vitrage_command("glance image-list")
|
||||||
|
try:
|
||||||
|
image_id = utils.get_regex_result("\|\s+(.*)\s+\|",
|
||||||
|
text_out.splitlines()[3])
|
||||||
|
image_id = image_id.split(" ")[0]
|
||||||
|
except Exception as e:
|
||||||
|
LOG.exception("Failed to get image id from the list %s ", e)
|
||||||
|
return None
|
||||||
|
|
||||||
|
LOG.debug("The image id from the list is " + image_id)
|
||||||
|
return image_id
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_instance_id_by_name(vm_name):
|
||||||
|
text_out = utils.run_vitrage_command("nova list")
|
||||||
|
for line in text_out.splitlines():
|
||||||
|
if vm_name in line:
|
||||||
|
vm_id = utils.get_regex_result("\|\s+(.*)\s+\|", line)
|
||||||
|
vm_id = vm_id.split(" ")[0]
|
||||||
|
LOG.debug("The instance id from the nova list is " + vm_id)
|
||||||
|
return vm_id
|
||||||
|
return None
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_volume_id_by_name(vol_name):
|
||||||
|
text_out = utils.run_vitrage_command("cinder list")
|
||||||
|
for line in text_out.splitlines():
|
||||||
|
if vol_name in line:
|
||||||
|
vol_id = utils.get_regex_result("\|\s+(.*)\s+\|", line)
|
||||||
|
vol_id = vol_id.split(" ")[0]
|
||||||
|
LOG.debug("The volume id from the cinder list is " + vol_id)
|
||||||
|
return vol_id
|
||||||
|
return None
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def create_vm_with_exist_image(vm_name, flavor_id, image_id):
|
||||||
|
utils.run_vitrage_command("nova boot " + vm_name + " --flavor " +
|
||||||
|
flavor_id + " --image " + image_id)
|
||||||
|
|
||||||
|
text_out = utils.run_vitrage_command("nova list")
|
||||||
|
if vm_name in text_out:
|
||||||
|
LOG.debug("The expected vm exist in the nova list")
|
||||||
|
else:
|
||||||
|
LOG.error("The expected vm not exist in the nova list")
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def create_volume_with_exist_size(vol_name):
|
||||||
|
utils.run_vitrage_command("cinder create --name " + vol_name + " 5")
|
||||||
|
|
||||||
|
text_out = utils.run_vitrage_command("cinder list")
|
||||||
|
if vol_name in text_out:
|
||||||
|
LOG.debug("The expected volume exist in the cinder list")
|
||||||
|
else:
|
||||||
|
LOG.error("The expected volume not exist in the cinder list")
|
||||||
|
|
||||||
|
def attach_volume(self, vm_name, vol_name):
|
||||||
|
vm_id = self.get_instance_id_by_name(vm_name)
|
||||||
|
vol_id = self.get_volume_id_by_name(vol_name)
|
||||||
|
|
||||||
|
utils.run_vitrage_command("nova volume-attach " + vm_id + " " + vol_id)
|
||||||
|
|
||||||
|
text_out = utils.run_vitrage_command("cinder list")
|
||||||
|
if vm_id in text_out:
|
||||||
|
LOG.debug("The expected volume attached to vm")
|
||||||
|
else:
|
||||||
|
LOG.error("The expected volume did not attached to vm")
|
||||||
|
@ -11,16 +11,10 @@
|
|||||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
import json
|
|
||||||
import subprocess
|
|
||||||
import vitrage_tempest_tests.tests.utils as utils
|
|
||||||
|
|
||||||
from oslo_log import log as logging
|
from oslo_log import log as logging
|
||||||
|
|
||||||
from vitrage.api.controllers.v1.topology import TopologyController
|
|
||||||
from vitrage.common.constants import VertexProperties as VProps
|
|
||||||
from vitrage_tempest_tests.tests.api.base import BaseVitrageTest
|
from vitrage_tempest_tests.tests.api.base import BaseVitrageTest
|
||||||
|
from vitrage_tempest_tests.tests.api.topology.topology_helper \
|
||||||
|
import TopologyHelper
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -30,83 +24,35 @@ class BaseTopologyTest(BaseVitrageTest):
|
|||||||
|
|
||||||
def __init__(self, *args, **kwds):
|
def __init__(self, *args, **kwds):
|
||||||
super(BaseTopologyTest, self).__init__(*args, **kwds)
|
super(BaseTopologyTest, self).__init__(*args, **kwds)
|
||||||
self.created_graphs = []
|
|
||||||
self.name = 'tempest_graph'
|
self.name = 'tempest_graph'
|
||||||
self.depth = ''
|
self.topology_client = TopologyHelper()
|
||||||
self.query = ''
|
|
||||||
self.root = ''
|
|
||||||
self._get_env_params()
|
|
||||||
self.client = utils.get_client()
|
|
||||||
|
|
||||||
def test_get_tree(self):
|
def test_compare_graphs(self):
|
||||||
"""Wrapper that returns a test tree."""
|
|
||||||
self._get_topology('tree')
|
|
||||||
|
|
||||||
def test_get_graph(self):
|
|
||||||
"""Wrapper that returns a test graph."""
|
"""Wrapper that returns a test graph."""
|
||||||
self._get_topology('graph')
|
api_graph = self.topology_client.get_api_topology('graph')
|
||||||
|
cli_graph = self.topology_client.show_cli_topology()
|
||||||
|
|
||||||
if self._validate_graph_correctness() is False:
|
if self.topology_client.compare_graphs(api_graph, cli_graph) is False:
|
||||||
LOG.error('The graph ' + self.name + ' is not correct')
|
LOG.error('The graph ' + self.name + ' is not correct')
|
||||||
else:
|
else:
|
||||||
LOG.info('The graph ' + self.name + ' is correct')
|
LOG.info('The graph ' + self.name + ' is correct')
|
||||||
|
|
||||||
def _get_topology(self, graph_type):
|
def test_get_tree_with_vms(self):
|
||||||
"""Get Graph objects returned by the v1 client """
|
"""Wrapper that returns a test tree with created vm's"""
|
||||||
try:
|
resources = self.topology_client.create_machines(4)
|
||||||
g = TopologyController().get_graph(graph_type=graph_type,
|
cli_graph = self.topology_client.show_cli_topology()
|
||||||
depth=self.depth,
|
|
||||||
query=self.query,
|
|
||||||
root=self.root)
|
|
||||||
except Exception as e:
|
|
||||||
LOG.exception("Failed to get topology (graph_type = " +
|
|
||||||
self.graph_type + ") %s ", e)
|
|
||||||
return None
|
|
||||||
|
|
||||||
return g
|
if self.validate_graph_correctness(cli_graph, resources) is False:
|
||||||
|
LOG.error('The graph ' + self.name + ' is not correct')
|
||||||
|
else:
|
||||||
|
LOG.info('The graph ' + self.name + ' is correct')
|
||||||
|
|
||||||
def _validate_graph_correctness(self):
|
def test_get_graph_with_volume(self):
|
||||||
"""Compare Graph object to graph form terminal """
|
"""Wrapper that returns a test graph."""
|
||||||
cli_graph = self._show_topology()
|
resources = self.topology_client.create_volume()
|
||||||
if cli_graph == '':
|
cli_graph = self.topology_client.show_cli_topology()
|
||||||
LOG.error("The topology graph taken from terminal is empty")
|
|
||||||
return False
|
|
||||||
|
|
||||||
parsed_topology = json.loads(cli_graph)
|
if self.validate_graph_correctness(cli_graph, resources) is False:
|
||||||
LOG.debug("The topology graph taken from terminal is : " +
|
LOG.error('The graph ' + self.name + ' is not correct')
|
||||||
json.dumps(parsed_topology))
|
else:
|
||||||
LOG.debug("The topology graph taken by api is : %s",
|
LOG.info('The graph ' + self.name + ' is correct')
|
||||||
json.dumps(self.graph))
|
|
||||||
|
|
||||||
cli_items = sorted(parsed_topology.items())
|
|
||||||
api_items = sorted(self.graph.items())
|
|
||||||
|
|
||||||
for item in cli_items[4][1]:
|
|
||||||
item.pop(VProps.UPDATE_TIMESTAMP, None)
|
|
||||||
|
|
||||||
for item in api_items[4][1]:
|
|
||||||
item.pop(VProps.UPDATE_TIMESTAMP, None)
|
|
||||||
|
|
||||||
return cli_items == api_items
|
|
||||||
|
|
||||||
def _show_topology(self):
|
|
||||||
LOG.debug("The command is : vitrage topology show")
|
|
||||||
p = subprocess.Popen("cd /home/stack/devstack; . openrc " +
|
|
||||||
self.user + " " + self.tenant_user +
|
|
||||||
"; vitrage topology show",
|
|
||||||
shell=True,
|
|
||||||
executable="/bin/bash",
|
|
||||||
stdout=subprocess.PIPE,
|
|
||||||
stderr=subprocess.PIPE)
|
|
||||||
stdout, stderr = p.communicate()
|
|
||||||
if stderr != '':
|
|
||||||
LOG.error("The command output error is : " + stderr)
|
|
||||||
if stdout != '':
|
|
||||||
LOG.debug("The command output is : \n" + stdout)
|
|
||||||
return stdout
|
|
||||||
return None
|
|
||||||
|
|
||||||
def _get_env_params(self):
|
|
||||||
conf = utils.get_conf()
|
|
||||||
self.user = conf.keystone_authtoken.admin_user
|
|
||||||
self.tenant_user = conf.keystone_authtoken.admin_tenant_name
|
|
||||||
|
134
vitrage_tempest_tests/tests/api/topology/topology_helper.py
Normal file
134
vitrage_tempest_tests/tests/api/topology/topology_helper.py
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
# Copyright 2016 Nokia
|
||||||
|
#
|
||||||
|
# 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 json
|
||||||
|
import vitrage_tempest_tests.tests.utils as utils
|
||||||
|
|
||||||
|
from oslo_log import log as logging
|
||||||
|
|
||||||
|
from vitrage.api.controllers.v1.topology import TopologyController
|
||||||
|
from vitrage.common.constants import VertexProperties as VProps
|
||||||
|
from vitrage_tempest_tests.tests.api.base import BaseVitrageTest
|
||||||
|
|
||||||
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class TopologyHelper(BaseVitrageTest):
|
||||||
|
"""Topology test class for Vitrage API tests."""
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwds):
|
||||||
|
super(TopologyHelper, self).__init__(*args, **kwds)
|
||||||
|
self.depth = ''
|
||||||
|
self.query = ''
|
||||||
|
self.root = ''
|
||||||
|
self._get_env_params()
|
||||||
|
self.client = utils.get_client()
|
||||||
|
|
||||||
|
def get_api_topology(self, graph_type):
|
||||||
|
"""Get Graph objects returned by the v1 client """
|
||||||
|
try:
|
||||||
|
api_graph = TopologyController().get_graph(graph_type=graph_type,
|
||||||
|
depth=self.depth,
|
||||||
|
query=self.query,
|
||||||
|
root=self.root)
|
||||||
|
except Exception as e:
|
||||||
|
LOG.exception("Failed to get topology (graph_type = " +
|
||||||
|
self.graph_type + ") %s ", e)
|
||||||
|
return None
|
||||||
|
|
||||||
|
return api_graph
|
||||||
|
|
||||||
|
def _get_env_params(self):
|
||||||
|
conf = utils.get_conf()
|
||||||
|
self.user = conf.service_credentials.user
|
||||||
|
|
||||||
|
def show_cli_topology(self):
|
||||||
|
"""Get Graph objects returned by cli """
|
||||||
|
LOG.debug("The command is : vitrage topology show")
|
||||||
|
return utils.run_vitrage_command(
|
||||||
|
"cd /home/stack/devstack; . openrc " +
|
||||||
|
self.user + " " + self.user +
|
||||||
|
"; vitrage topology show")
|
||||||
|
|
||||||
|
def create_machines(self, machine_number):
|
||||||
|
flavor_id = self.get_flavor_id_from_list()
|
||||||
|
image_id = self.get_image_id_from_list()
|
||||||
|
|
||||||
|
resources = []
|
||||||
|
for r in range(start=0, stop=machine_number, step=1):
|
||||||
|
self.create_vm_with_exist_image("vm_for_test_" + str(r),
|
||||||
|
flavor_id, image_id)
|
||||||
|
resources.append("vm_for_test_" + str(r))
|
||||||
|
|
||||||
|
return resources
|
||||||
|
|
||||||
|
def create_volume(self):
|
||||||
|
flavor_id = self.get_flavor_id_from_list()
|
||||||
|
image_id = self.get_image_id_from_list()
|
||||||
|
|
||||||
|
resources = ["vm_for_vol", "vol_for_vm"]
|
||||||
|
self.create_vm_with_exist_image(resources[0], flavor_id, image_id)
|
||||||
|
self.create_volume_with_exist_size(resources[1])
|
||||||
|
self.attach_volume(resources[0], resources[1])
|
||||||
|
return resources
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def compare_graphs(api_graph, cli_graph):
|
||||||
|
"""Compare Graph object to graph form terminal """
|
||||||
|
if not api_graph:
|
||||||
|
LOG.error("The topology graph taken from rest api is empty")
|
||||||
|
return False
|
||||||
|
if not cli_graph:
|
||||||
|
LOG.error("The topology graph taken from terminal is empty")
|
||||||
|
return False
|
||||||
|
|
||||||
|
parsed_topology = json.loads(cli_graph)
|
||||||
|
LOG.debug("The topology graph taken from terminal is : " +
|
||||||
|
json.dumps(parsed_topology))
|
||||||
|
LOG.debug("The topology graph taken by api is : %s",
|
||||||
|
json.dumps(api_graph))
|
||||||
|
|
||||||
|
cli_items = sorted(parsed_topology.items())
|
||||||
|
api_items = sorted(api_graph.items())
|
||||||
|
|
||||||
|
for item in cli_items[4][1]:
|
||||||
|
item.pop(VProps.UPDATE_TIMESTAMP, None)
|
||||||
|
|
||||||
|
for item in api_items[4][1]:
|
||||||
|
item.pop(VProps.UPDATE_TIMESTAMP, None)
|
||||||
|
|
||||||
|
return cli_items == api_items
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def validate_graph_correctness(cli_graph, resources):
|
||||||
|
"""Compare Graph object to graph form terminal """
|
||||||
|
if not cli_graph:
|
||||||
|
LOG.error("The topology graph taken from terminal is empty")
|
||||||
|
return False
|
||||||
|
if not resources:
|
||||||
|
LOG.error("The resources list is empty")
|
||||||
|
return False
|
||||||
|
|
||||||
|
parsed_topology = json.loads(cli_graph)
|
||||||
|
LOG.debug("The topology graph taken from terminal is : " +
|
||||||
|
json.dumps(parsed_topology))
|
||||||
|
cli_items = sorted(parsed_topology.items())
|
||||||
|
|
||||||
|
for resource_name in resources:
|
||||||
|
for item in cli_items[4][1]:
|
||||||
|
item.pop(VProps.UPDATE_TIMESTAMP, None)
|
||||||
|
if resource_name not in cli_items[4][1]:
|
||||||
|
LOG.error("The resources " + resource_name +
|
||||||
|
"doesn't exist in the topology graph")
|
||||||
|
return False
|
||||||
|
return True
|
@ -11,11 +11,9 @@
|
|||||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
from oslo_config import cfg
|
from oslo_config import cfg
|
||||||
from oslo_log import log as logging
|
from oslo_log import log as logging
|
||||||
|
|
||||||
# noinspection PyPackageRequirements
|
|
||||||
import testtools
|
import testtools
|
||||||
import vitrage_tempest_tests.tests.utils as utils
|
import vitrage_tempest_tests.tests.utils as utils
|
||||||
|
|
||||||
@ -41,21 +39,21 @@ class RunVitrageEnv(testtools.TestCase):
|
|||||||
self._get_env_params()
|
self._get_env_params()
|
||||||
|
|
||||||
utils.change_terminal_dir('/home/stack/devstack')
|
utils.change_terminal_dir('/home/stack/devstack')
|
||||||
utils.run_from_terminal("chmod +x openrc")
|
# utils.run_from_terminal("chmod +x openrc")
|
||||||
utils.run_from_terminal("./openrc " + self.user + " " +
|
utils.get_from_terminal_enabled_bash(". openrc " + self.user + " " +
|
||||||
self.tenant_user)
|
self.user)
|
||||||
utils.run_from_terminal("openstack service create rca" +
|
utils.run_from_terminal("openstack service create rca" +
|
||||||
" --os-username " + self.user +
|
# " --os-username " + self.user +
|
||||||
" --os-password " + self.password +
|
# " --os-password " + self.password +
|
||||||
" --os-auth-url " + self.url +
|
# " --os-auth-url " + self.url +
|
||||||
" --os-project-name admin" +
|
# " --os-project-name admin" +
|
||||||
" --name vitrage")
|
" --name vitrage")
|
||||||
utils.run_from_terminal("openstack endpoint create rca" +
|
utils.run_from_terminal("openstack endpoint create rca" +
|
||||||
" --os-username " + self.user +
|
# " --os-username " + self.user +
|
||||||
" --os-username " + self.user +
|
# " --os-username " + self.user +
|
||||||
" --os-password " + self.password +
|
# " --os-password " + self.password +
|
||||||
" --os-auth-url " + self.url +
|
# " --os-auth-url " + self.url +
|
||||||
" --os-project-name admin" +
|
# " --os-project-name admin" +
|
||||||
" --adminurl http://" + self.host +
|
" --adminurl http://" + self.host +
|
||||||
":" + str(self.port) +
|
":" + str(self.port) +
|
||||||
" --internalurl http://" + self.host +
|
" --internalurl http://" + self.host +
|
||||||
@ -101,13 +99,12 @@ class RunVitrageEnv(testtools.TestCase):
|
|||||||
def _get_env_params(self):
|
def _get_env_params(self):
|
||||||
conf = utils.get_conf()
|
conf = utils.get_conf()
|
||||||
self.port = conf.api.port
|
self.port = conf.api.port
|
||||||
self.user = conf.keystone_authtoken.admin_user
|
self.user = conf.service_credentials.user
|
||||||
self.tenant_user = conf.keystone_authtoken.admin_tenant_name
|
self.password = conf.service_credentials.password
|
||||||
self.password = conf.keystone_authtoken.admin_password
|
self.url = conf.service_credentials.auth_url + "/v2.0"
|
||||||
self.identity_uri = conf.keystone_authtoken.identity_uri
|
|
||||||
self.host = utils.get_regex_result(
|
self.host = utils.get_regex_result(
|
||||||
"(\d+\.\d+\.\d+\.\d+)", self.identity_uri)
|
"(\d+\.\d+\.\d+\.\d+)", self.url)
|
||||||
self.url = "http://" + self.host + ":5000/v2.0"
|
self.identity_uri = conf.keystone_authtoken.identity_uri
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _stop_vitrage_processes():
|
def _stop_vitrage_processes():
|
||||||
|
@ -35,10 +35,4 @@ class StopVitrageEnv(testtools.TestCase):
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
def test_stop_vitrage_processes():
|
def test_stop_vitrage_processes():
|
||||||
LOG.debug("Stop vitrage processes")
|
LOG.debug("Stop vitrage processes")
|
||||||
text_out = utils.get_from_terminal("pgrep vitrage-api")
|
utils.run_from_terminal("pkill vitrage")
|
||||||
if text_out != '':
|
|
||||||
utils.run_from_terminal("kill -9 " + text_out)
|
|
||||||
|
|
||||||
text_out2 = utils.get_from_terminal("pgrep vitrage-graph")
|
|
||||||
if text_out2 != '':
|
|
||||||
utils.run_from_terminal("kill -9 " + text_out2)
|
|
||||||
|
@ -18,6 +18,7 @@ from vitrage import service
|
|||||||
import os
|
import os
|
||||||
import oslo_messaging
|
import oslo_messaging
|
||||||
import re
|
import re
|
||||||
|
import subprocess
|
||||||
import vitrage_tempest_tests.tests
|
import vitrage_tempest_tests.tests
|
||||||
|
|
||||||
extra_log_level_defaults = [
|
extra_log_level_defaults = [
|
||||||
@ -52,6 +53,21 @@ def get_from_terminal(command):
|
|||||||
return text_out
|
return text_out
|
||||||
|
|
||||||
|
|
||||||
|
def run_vitrage_command(command):
|
||||||
|
p = subprocess.Popen(command,
|
||||||
|
shell=True,
|
||||||
|
executable="/bin/bash",
|
||||||
|
stdout=subprocess.PIPE,
|
||||||
|
stderr=subprocess.PIPE)
|
||||||
|
stdout, stderr = p.communicate()
|
||||||
|
if stderr != '':
|
||||||
|
LOG.error("The command output error is : " + stderr)
|
||||||
|
if stdout != '':
|
||||||
|
LOG.debug("The command output is : \n" + stdout)
|
||||||
|
return stdout
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
def run_from_terminal(command):
|
def run_from_terminal(command):
|
||||||
proc = os.popen(command)
|
proc = os.popen(command)
|
||||||
text_out = proc.read()
|
text_out = proc.read()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user