openstack 使用cloud init 和 console-log, nbd或者libguestfs 获取VM中的硬件信息。
以获取PCI的信息为例。
基本代码:
pci.py
import base64
import guestfs
from functools import partial
import os
import six
import stat
import subprocess
import tempfile
import time
import xml.etree.ElementTree as ET from oslo_utils import encodeutils
from tempest import config
from tempest_lib.common.utils import data_utils def shell_command(cmd, log=False):
# cmd = ['sudo', 'ip', 'netns', 'exec', ns, 'ssh', "%s@%s" %(name, ip),
# "'%s;ifconfig eth1 %s/24'" % (name ip)]
p = subprocess.Popen(
cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = p.communicate()
if log:
print out
print err
if len(err):
return False
return out VM_MOUNT_POINT = "/mnt"
PCI_PATH = "/pci.info"
RC_LOCAL = "/etc/rc.local"
USER_DATA = ['#!/bin/sh -e',
'# mount -a',
'mount /dev/vdb %s' % VM_MOUNT_POINT,
'touch %s%s' % (VM_MOUNT_POINT, PCI_PATH),
'lspci > %s%s' % (VM_MOUNT_POINT, PCI_PATH),
'# umount /mnt/'
'exit 0'] PCIINFO_DELIMITER = "*" * 40 + "%s" + "*" * 40
PCIINFO_DELIMITER_BEGIN = PCIINFO_DELIMITER % "PCI INFO BEGIN"
PCIINFO_DELIMITER_END = PCIINFO_DELIMITER % "PCI INFO END" CONSOLE_DATA = ['#!/bin/sh -e',
'sudo echo "%s"' % PCIINFO_DELIMITER_BEGIN,
'sudo lspci',
'sudo echo "%s"' % PCIINFO_DELIMITER_END,
'exit 0'] def gen_rc_local_file(pci_path=PCI_PATH):
"""please remove the file: os.remove(p)
print gen_rc_local()
"""
l, p = tempfile.mkstemp("local", "rc")
f = open(p, 'w+b')
f.writelines(['#!/bin/sh -e\n',
'mount -a\n',
'touch %s%s\n' % (VM_MOUNT_POINT, pci_path),
'lspci > %s%s\n' % (VM_MOUNT_POINT, pci_path),
'umount /mnt/\n'
'exit 0\n'])
os.chmod(p, stat.S_IRWXU + stat.S_IXGRP + stat.S_IXOTH)
f.close()
return p, pci_path def gen_rc_local_dict(pci_path=PCI_PATH):
"""
usage: personality = {}
personality.append({
'path': filepath,
'contents': cont,
}) """
data = ['#!/bin/sh -e',
'mount -a',
'touch %s%s' % (VM_MOUNT_POINT, pci_path),
'lspci > %s%s' % (VM_MOUNT_POINT, pci_path),
'cd ~',
'umount /mnt/',
'exit 0']
data = "\n".join(data)
if six.PY3 and isinstance(data, str):
data = data.encode('utf-8')
cont = base64.b64encode(data).decode('utf-8')
return cont def gen_user_data(userdata=USER_DATA):
if hasattr(userdata, 'read'):
userdata = userdata.read()
# NOTE(melwitt): Text file data is converted to bytes prior to
# base64 encoding. The utf-8 encoding will fail for binary files.
if six.PY3:
try:
userdata = userdata.encode("utf-8")
except AttributeError:
# In python 3, 'bytes' object has no attribute 'encode'
pass
else:
try:
userdata = encodeutils.safe_encode(userdata)
except UnicodeDecodeError:
pass userdata_b64 = base64.b64encode(userdata).decode('utf-8')
return userdata_b64 def gen_etc_fstab():
"""
usage: personality = {}
personality.append({
'path': filepath,
'contents': cont,
}) """
data = ["/dev/root / auto rw,noauto 0 1",
"proc /proc proc defaults 0 0",
"devpts /dev/pts devpts defaults,gid=5,mode=620 0 0",
"tmpfs /dev/shm tmpfs mode=0777 0 0",
"sysfs /sys sysfs defaults 0 0",
"tmpfs /run tmpfs rw,nosuid,relatime,size=200k,mode=755 0 0",
"/dev/vdb /mnt/ auto defaults 0 0"] data = "\n".join(data)
if six.PY3 and isinstance(data, str):
data = data.encode('utf-8')
cont = base64.b64encode(data).decode('utf-8')
return cont def get_pci_info(disk, pci_path=PCI_PATH):
"""please remove the dir: os.rmdir(p)
mount the disk by guestfs and get the pci info.
need:
$ sudo chmod g+rw /boot/vmlinuz-/boot/vmlinuz-`uname -r`
$ sudo usermod -a -G root jenkins
need to install these 2 packages
$ sudo apt-get install libguestfs-tools
$ sudo apt-get install python-guestfs
need to add use to kvm group
$ sudo usermod -a -G kvm jenkins
or
$ sudo chmod 0666 /dev/kvm
ref http://libguestfs.org/guestfs-python.3.html
for debug:
$ export LIBGUESTFS_DEBUG=1
$ export LIBGUESTFS_TRACE=1
ref http://libguestfs.org/guestfs-faq.1.html#debugging-libguestfs
"""
p = tempfile.mkdtemp("guestfs", "mount")
g = guestfs.GuestFS(python_return_dict=True)
# g.add_drive_opts(disk, format="qcow2", readonly=1)
g.add_drive_opts(disk, readonly=1)
g.launch()
g.mount('/dev/sda', '/')
return g.read_lines(pci_path) def nbd_mount(f, disk, path=PCI_PATH):
"""please remove the dir: os.rmdir(p)
mount the disk by guestfs and get the pci info.
need:
$ sudo rmmod nbd
$ sudo modprobe nbd max_part=16
ref https://en.wikibooks.org/wiki/QEMU/Images
ref https://blogs.gnome.org/muelli/2010/03/mounting-qemu-qcow2-image-using-nbd/
"""
mount_point = "/mnt/nbd"
cmd = ["sudo", "modinfo", "nbd"]
out = shell_command(cmd)
if "modinfo: ERROR:" in out:
cmd = ["sudo", "modprobe", "nbd", "max_part=16"]
shell_command(cmd) if not os.path.exists(mount_point):
cmd = ["sudo", "mkdir", mount_point]
shell_command(cmd) if os.path.ismount(mount_point):
cmd = ["sudo", "umount", mount_point]
shell_command(cmd) cmd = ["sudo", "qemu-nbd", "-d", "/dev/nbd0"]
shell_command(cmd) cmd = ["sudo", "killall", "qemu-nbd"]
shell_command(cmd) # cmd = ["sudo", "qemu-nbd", "-r", "-c", "/dev/nbd0", disk]
cmd = ["sudo", "qemu-nbd", "-c", "/dev/nbd0", disk]
shell_command(cmd) cmd = ["sudo", "mount", "/dev/nbd0", mount_point]
shell_command(cmd) if not os.path.ismount(mount_point):
cmd = ["sudo", "qemu-nbd", "-d", "/dev/nbd0"]
shell_command(cmd)
raise Exception("Can't mount the VM disk!") out = f(mount_point, path) cmd = ["sudo", "umount", mount_point]
shell_command(cmd) cmd = ["sudo", "qemu-nbd", "-d", "/dev/nbd0"]
shell_command(cmd)
return out def cat_file(mount, pci_path):
cmd = ["sudo", "cat", mount + pci_path]
pci_info = shell_command(cmd, True)
if pci_info is False:
return pci_info
return pci_info.splitlines() get_pci_info_by_nbd = partial(nbd_mount, cat_file) def x_file(mount, rc_path):
cmd = ["sudo", "chmod", "a+x", mount + rc_path]
out = shell_command(cmd)
return out rc_local_add_x = partial(nbd_mount, x_file) def get_vda_path(xml):
# tree = ET.parse('/etc/libvirt/qemu/instance-0000001f.xml')
# root = tree.getroot()
root = ET.fromstring(xml)
disks = root.findall("./devices/disk[@device='disk'][@type='file']")
for d in disks:
t = d.find("target")
if t.attrib.get("dev") == "vda":
return d.find("./source").get("file") def get_config_drive_path(xml):
# tree = ET.parse('/etc/libvirt/qemu/instance-0000001f.xml')
# root = tree.getroot()
root = ET.fromstring(xml)
disks = root.findall("./devices/disk[@device='disk'][@type='file']")
for d in disks:
f = d.find("./source").get("file")
if "disk.config" in f:
return f def get_pci_output(get_console_output, server_id):
output = get_console_output(server_id, -1)['output']
lines = output.split('\n')
if (len(lines) > 0 and lines.count(PCIINFO_DELIMITER_BEGIN) > 0
and lines.count(PCIINFO_DELIMITER_END)):
begin = lines.index(PCIINFO_DELIMITER_BEGIN) + 1
end = lines.index(PCIINFO_DELIMITER_END)
return lines[begin : end] def retry_get_pci_output(get_console_output, server_id, retry=20):
while retry > 0:
out = get_pci_output(get_console_output, server_id)
if out is None:
retry = retry - 1
time.sleep(1)
else:
return out
raise Exception("Can't get the pci.info from VM!")
使用cloud-init 和console-log获取硬件信息的代码的片段。
personality = []
user_data = pci.gen_user_data("\n".join(pci.CONSOLE_DATA))
server_with_pci = (self.create_test_server(
wait_until='ACTIVE',
adminPass=admin_pass,
user_data=user_data,
personality=personality,
flavor=flavor_with_pci_id))
#print self.client.get_server_metadata_item(server_with_pci['id'],"addresses")
addresses = self.client.show_server(server_with_pci['id'])['server']
password = 'cubswin:)'
print "cirros@" + addresses["addresses"]["private"][0]["addr"]
print password
pci_info = pci.retry_get_pci_output(
self.client.get_console_output, server_with_pci["id"])
# pci_info = pci.get_pci_info(disk)
# pci_flag = linux_client.get_pci(pciid)
expect_pci = filter(lambda x: pciid in x, pci_info)
# self.assertTrue(pci_flag is not None)
self.assertTrue(not not expect_pci)
# pci_count = linux_client.get_pci_count(pciid)
pci_count = len(expect_pci)
# pci_count = pci_count.strip()
self.assertEqual(1, pci_count)
使用 使用cloud-init 和 nbd获取时候,需要mount config.drive的磁盘。
使用 file inject 和nbd获取的时候,需要开关机器。
openstack 使用cloud init 和 console-log, nbd或者libguestfs 获取VM中的硬件信息。的更多相关文章
- Javascript 将 console.log 日志打印到 html 页面中
如何将 console.log() 打印的日志输出到 html 页面中 (function () { var old = console.log; var logger = document.getE ...
- javascript的console.log用法
f1.html代码 <iframe id="frame2" name="frame1" src="ww.html"></i ...
- JS里try...catch...finally详解,以及console日志调试(console.log、console.info等)
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...
- 拦截chrome的console.log输出
console.log = function(){}; 这样 console.log(123) 将不会在输出任何调试信息
- var foo = "11"+2+"1"; console.log(foo); //1121 好多文章答案写错了,我发下给初学的朋友看到,以免一开始就学错了
体会加一个字符串'1' 和 减去一个字符串'1'的不同 var foo = "11"+2-"1"; console.log(foo); //111 consol ...
- console.log()与console.dir()
console.log()可以取代alert()或document.write(),在网页脚本中使用console.log()时,会在浏览器控制台打印出信息. console.dir()可以显示一个对 ...
- 还是只使用console.log()进行调试?好吧,其实还有更多。
在浏览器控制台中打印消息无疑可以拯救所有开发人员. console.log()消息就像您的大多数疾病的药,同时调试了代码中的一些有线问题. 那里的大多数开发人员都喜欢— 让我们在浏览器中打印消息以了解 ...
- Openstack中查看虚拟机console log的几种方法
Openstack中有时候虚拟机启动不正常,这时可以通过查看虚拟机console log能得到一些有用的信息. 有这些方法可以查看或获取虚拟机console log: 1)openstack控制台图形 ...
- openstack cloud init set password
设置代理和password #!/bin/bash cd /home/ubuntu wget otcloud-gateway.bj.intel.com/script.tar.gz ]; then cu ...
随机推荐
- StreamReader与StreamWriter
StreamReader实现了抽象基类TextReader类,而StreamWriter实现了抽象基类TextWriter.分别用于对流的读取与写入. 先从StreamReader说起 一.构造方法 ...
- 用VS2013+VELT-0.1.4进行海思平台 Linux内核 的开发
快乐虾 http://blog.csdn.net/lights_joy/(QQ群:Visual EmbedLinux Tools 375515651) 欢迎转载,但请保留作者信息 本文仅适用于vs20 ...
- 学习DSP(三)安装C2833x/C2823x C/C++ 头文件和外设示例-压缩包
进入http://www.ti.com.cn/product/cn/tms320f28335 下载C2833x/C2823x C/C++ 头文件和外设示例 即SPRC530,目前最新版本是V131.安 ...
- libcurl 多线程使用注意事项 - Balder~专栏 - 博客频道 - CSDN.NET
libcurl 多线程使用注意事项 - Balder~专栏 - 博客频道 - CSDN.NET libcurl 多线程使用注意事项 分类: C/C++学习 2012-05-24 18:48 2843人 ...
- JNI的替代者—使用JNA访问Java外部功能接口
摘自:http://www.cnblogs.com/lanxuezaipiao/p/3635556.html JNI的替代者-使用JNA访问Java外部功能接口 1. JNA简单介绍 先说JNI(Ja ...
- 用Python实现九九乘法表
1.用“#”组成的矩形的实现 代码 eight = int(input("Height:")) #用户输入高度 width = int(input("Width:&quo ...
- execute immediate的简单用法(oracle)
直接上示例代码: create or replace procedure proc_test( --参数区域 ) is --变量区域 --sql脚本 v_sql ) :=''; --记录学生数量 v_ ...
- RMAN传输表空间迁移数据
实验环境: 源数据库:oracle 10g(Release 10.2.0.1.0) 目标数据库:oracle 10g(Release 10.2.0.1.0) 待传输的表空间:TEST 1.在tes ...
- hdu 4750 Count The Pairs (2013南京网络赛)
n个点m条无向边的图,对于q个询问,每次查询点对间最小瓶颈路 >=f 的点对有多少. 最小瓶颈路显然在kruskal求得的MST上.而输入保证所有边权唯一,也就是说f[i][j]肯定唯一了. 拿 ...
- 如何把UIView转成UIImage,解决模糊失真问题
最近工作中,遇到一个需求,需要把一个UIView对象转成UIImage对象显示.经过网络搜索,找到如下答案: ? 1 2 3 4 5 6 7 8 -(UIImage*)convertViewToIma ...