Skip to content

Commit

Permalink
Merge pull request #139 from turtle-fly/bugfix/sync_ipmi_console_inte…
Browse files Browse the repository at this point in the history
…rface

bugfix/sync_ipmi_console_interface
  • Loading branch information
Bryan Fu authored Nov 15, 2016
2 parents 2e2e496 + c232c4a commit 116cc3a
Show file tree
Hide file tree
Showing 7 changed files with 300 additions and 35 deletions.
4 changes: 4 additions & 0 deletions etc/infrasim.full.yml.example
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,11 @@ bmc:
config_file: <path/to/your config file>
emu_file: chassis/node1/quanta_d51.emu

# SSH to this port to visit ipmi-console
ipmi_console_ssh: 9300

# Renamed from telnet_listen_port to ipmi_console_port, extracted from bmc
# ipmi-console talk with vBMC via this port
ipmi_console_port: 9000

# Used by ipmi_sim and qemu
Expand Down
33 changes: 25 additions & 8 deletions infrasim/console.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
from . import logger
from .ipmicons.command import Command_Handler
from .ipmicons.common import msg_queue
from .ipmicons import env

import re

Expand Down Expand Up @@ -88,7 +89,7 @@ def run(self):

def _start_console():
global server
server = sshim.Server(IPMI_CONSOLE, port=9300)
server = sshim.Server(IPMI_CONSOLE, port=env.PORT_SSH_FOR_CLIENT)
try:
logger.info("ipmi-console start")
server.run()
Expand Down Expand Up @@ -132,35 +133,51 @@ def _free_resource():
thread.join()


def start():
def start(instance="node-0"):
"""
Attach ipmi-console to target instance specified by
its name
:param instance: infrasim instance name
"""
daemon.daemonize("{}/{}/.ipmi_console.pid".format(config.infrasim_home, instance))

# initialize logging
common.init_logger()
# initialize environment
common.init_env(instance)
# parse the sdrs and build all sensors
sdr.parse_sdrs()
# running thread for each threshold based sensor
_spawn_sensor_thread()
_start_console()


def stop():
def stop(instance="node-0"):
"""
Stop ipmi-console of target instance specified by
its name
:param instance: infrasim instance name
"""
try:
with open("{}/.ipmi_console.pid".format(config.infrasim_home), "r") as f:
file_ipmi_console_pid = "{}/{}/.ipmi_console.pid".\
format(config.infrasim_home, instance)
with open(file_ipmi_console_pid, "r") as f:
pid = f.readline().strip()

os.kill(int(pid), signal.SIGTERM)
os.remove(file_ipmi_console_pid)
except:
pass


def console_main():
def console_main(instance="node-0"):
if len(sys.argv) < 2:
print "ipmi-console [ start | stop ]"
sys.exit(1)

if sys.argv[1] == "start":
daemon.daemonize("{}/.ipmi_console.pid".format(config.infrasim_home))
start()
start(instance)
elif sys.argv[1] == "stop":
stop()
stop(instance)
else:
pass
9 changes: 6 additions & 3 deletions infrasim/daemon.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ def atexit_cb():
si = file(stdin, 'r')
so = file(stdout, 'a+')
se = file(stderr, 'a+', 0)
os.dup2(si.fileno(), sys.stdin.fileno())
os.dup2(so.fileno(), sys.stdout.fileno())
os.dup2(se.fileno(), sys.stderr.fileno())
if hasattr(sys.stdin, "fileno"):
os.dup2(si.fileno(), sys.stdin.fileno())
if hasattr(sys.stdout, "fileno"):
os.dup2(so.fileno(), sys.stdout.fileno())
if hasattr(sys.stderr, "fileno"):
os.dup2(se.fileno(), sys.stderr.fileno())
107 changes: 96 additions & 11 deletions infrasim/ipmicons/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@
'''
import subprocess
import os
import sys
import time
import threading
import telnetlib
import logging

import socket
import Queue
import re
import env
import traceback

lock = threading.Lock()

Expand All @@ -39,6 +39,7 @@ def init_logger():
# create console handler with a higher log level
# ch = logging.StreamHandler()
# ch.setLevel(logging.ERROR)
logger.setLevel(logging.INFO)

# create formatter and add it to the handlers
formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
Expand All @@ -48,6 +49,82 @@ def init_logger():
logger.addHandler(fh)


def init_env(instance):
"""
This is to sync ipmi-console with runtime vBMC configuration.
Initial version capture infrasim instance name by infrasim-main status, while we
have a plan to give instance name to ipmi-console so that it can be attached to
target vBMC instance.
"""
logger.info("Init ipmi-console environment for infrasim instance: {}".
format(instance))

# Get runtime vbmc.conf
vbmc_conf_path = os.path.join(os.environ["HOME"], ".infrasim", instance, "data", "vbmc.conf")
if not os.path.exists(vbmc_conf_path):
msg = "{} vBMC configuration is not defined at {}".format(instance, vbmc_conf_path)
logger.error(msg)
raise Exception(msg)
else:
msg = "Target vbmc to attach is: {}".format(vbmc_conf_path)
logger.info(msg)

# Get runtime infrasim.yml
infrasim_yml_path = os.path.join(os.environ["HOME"], ".infrasim", instance, "data", "infrasim.yml")
if not os.path.exists(infrasim_yml_path):
msg = "{} infrasim instance is not defined at {}".format(instance, infrasim_yml_path)
logger.error(msg)
raise Exception(msg)
else:
msg = "Target infrasim instance to attach is: {}".format(infrasim_yml_path)
logger.info(msg)

# Get variable and set to ipmi-console env
# - PORT_TELNET_TO_VBMC
# - VBMC_IP
# - VBMC_PORT
with open(vbmc_conf_path, 'r') as fp:
conf = fp.read()

p_telnet = re.compile(r"^\s*console\s*[\d:\.]+\s+(?P<port_telnet_to_vbmc>\d+)",
re.MULTILINE)
s_telnet = p_telnet.search(conf)
if s_telnet:
env.PORT_TELNET_TO_VBMC = int(s_telnet.group("port_telnet_to_vbmc"))
logger.info("PORT_TELNET_TO_VBMC: {}".format(env.PORT_TELNET_TO_VBMC))
else:
raise Exception("PORT_TELNET_TO_VBMC is not found")

p_vbmc = re.compile(r"^\s*addr\s*(?P<vbmc_ip>[\d:\.]+)\s*(?P<vbmc_port>\d+)",
re.MULTILINE)
s_vbmc = p_vbmc.search(conf)
if s_vbmc:
ip = s_vbmc.group("vbmc_ip")
if ip == "::" or ip == "0.0.0.0":
env.VBMC_IP = "localhost"
else:
env.VBMC_IP = "ip"
logger.info("VBMC_IP: {}".format(env.VBMC_IP))
env.VBMC_PORT = int(s_vbmc.group("vbmc_port"))
logger.info("VBMC_PORT: {}".format(env.VBMC_PORT))
else:
raise Exception("VBMC_IP and VBMC_PORT is not found")

# Get variable and set to ipmi-console env
# - PORT_SSH_FOR_CLIENT
with open(infrasim_yml_path, 'r') as fp:
conf = fp.read()

p_port = re.compile(r"^\s*ipmi_console_ssh:\s*(?P<port_ssh_for_client>\d+)",
re.MULTILINE)
s_port = p_port.search(conf)
if s_port:
env.PORT_SSH_FOR_CLIENT = int(s_port.group("port_ssh_for_client"))
else:
env.PORT_SSH_FOR_CLIENT = 9300
logger.info("PORT_SSH_FOR_CLIENT: {}".format(env.PORT_SSH_FOR_CLIENT))


def get_logger():
return logger

Expand Down Expand Up @@ -79,14 +156,15 @@ def send_ipmi_sim_command(command):
logger.info("send IPMI SIM command: " + command.strip())
result = ""
try:
tn.open('localhost', '9000')
tn.open('localhost', env.PORT_TELNET_TO_VBMC)
tn.write(command)
time.sleep(0.1)
result = tn.read_some()
tn.close()
logger.info("IPMI SIM command result: " + result)
except socket.error as se:
logger.error("Unable to connect lanserv at 9000: {0}".format(se))
logger.error("Unable to connect lanserv at {0}: {1}".
format(env.PORT_TELNET_TO_VBMC, se))
finally:
lock.release()

Expand Down Expand Up @@ -115,15 +193,22 @@ def send_ipmitool_command(*cmds):

lock.acquire()
dst_cmd = ["ipmitool",
"-I", "lan", "-H", 'localhost', "-U", vbmc_user, "-P", vbmc_pass]
"-I", "lan",
"-H", env.VBMC_IP,
"-U", vbmc_user,
"-P", vbmc_pass,
"-p", str(env.VBMC_PORT)]
for cmd in cmds:
dst_cmd.append(cmd)
child = subprocess.Popen(dst_cmd,
stdout=subprocess.PIPE,
stdin=subprocess.PIPE,
stderr=subprocess.PIPE
)
(stdout, stderr) = child.communicate()
try:
child = subprocess.Popen(dst_cmd,
stdout=subprocess.PIPE,
stdin=subprocess.PIPE,
stderr=subprocess.PIPE)
(stdout, stderr) = child.communicate()
except:
logger.error(traceback.format_exc())
raise
child.wait()
logger.info("ipmitool command: " + ' '.join(dst_cmd))
logger.info("ipmitool command stdout: " + stdout.strip())
Expand Down
11 changes: 11 additions & 0 deletions infrasim/ipmicons/env.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
'''
*********************************************************
Copyright @ 2015 EMC Corporation All Rights Reserved
*********************************************************
'''
# -*- coding: utf-8 -*-

PORT_TELNET_TO_VBMC = 9000
PORT_SSH_FOR_CLIENT = 9300
VBMC_IP = "localhost"
VBMC_PORT = 623
2 changes: 0 additions & 2 deletions infrasim/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -1384,8 +1384,6 @@ def __init__(self, bmc_info={}):
self.__port_qemu_ipmi = 9002
self.__sol_device = ""



def set_type(self, vendor_type):
self.__vendor_type = vendor_type

Expand Down
Loading

0 comments on commit 116cc3a

Please sign in to comment.