以获取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中的硬件信息。的更多相关文章

  1. Javascript 将 console.log 日志打印到 html 页面中

    如何将 console.log() 打印的日志输出到 html 页面中 (function () { var old = console.log; var logger = document.getE ...

  2. javascript的console.log用法

    f1.html代码 <iframe id="frame2" name="frame1" src="ww.html"></i ...

  3. JS里try...catch...finally详解,以及console日志调试(console.log、console.info等)

    <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...

  4. 拦截chrome的console.log输出

    console.log = function(){}; 这样 console.log(123) 将不会在输出任何调试信息

  5. var foo = "11"+2+"1"; console.log(foo); //1121 好多文章答案写错了,我发下给初学的朋友看到,以免一开始就学错了

    体会加一个字符串'1' 和 减去一个字符串'1'的不同 var foo = "11"+2-"1"; console.log(foo); //111 consol ...

  6. console.log()与console.dir()

    console.log()可以取代alert()或document.write(),在网页脚本中使用console.log()时,会在浏览器控制台打印出信息. console.dir()可以显示一个对 ...

  7. 还是只使用console.log()进行调试?好吧,其实还有更多。

    在浏览器控制台中打印消息无疑可以拯救所有开发人员. console.log()消息就像您的大多数疾病的药,同时调试了代码中的一些有线问题. 那里的大多数开发人员都喜欢— 让我们在浏览器中打印消息以了解 ...

  8. Openstack中查看虚拟机console log的几种方法

    Openstack中有时候虚拟机启动不正常,这时可以通过查看虚拟机console log能得到一些有用的信息. 有这些方法可以查看或获取虚拟机console log: 1)openstack控制台图形 ...

  9. openstack cloud init set password

    设置代理和password #!/bin/bash cd /home/ubuntu wget otcloud-gateway.bj.intel.com/script.tar.gz ]; then cu ...

随机推荐

  1. 【Xamarin挖墙脚系列:打造独特的Xamarin.IOS开发环境】

    苹果的产品,依赖特定的开发环境. Mac  +  Xcode  不可缺少.所以,必须有Mac系统. 1-虚拟机搭建 2-土豪有Mac电脑设备 但是我觉得还是顺带上Visual Studio才是完美.. ...

  2. ServerProperties

    Spring Boot 其默认是集成web容器的,启动方式由像普通Java程序一样,main函数入口启动.其内置Tomcat容器或Jetty容器,具体由配置来决定(默认Tomcat).当然你也可以将项 ...

  3. (转)ZOJ 3687 The Review Plan I(禁为排列)

    The Review Plan I Time Limit: 5 Seconds      Memory Limit: 65536 KB Michael takes the Discrete Mathe ...

  4. 修改MySQL 5.5的max_allowed_packet属性的方法

    今天在部署一个实验系统的时候,报出下面这个错: Your 'max_allowed_packet' variable is set to less than 16777216 Byte (16MB). ...

  5. poj 1753 Flip Game(bfs状态压缩 或 dfs枚举)

    Description Flip game squares. One side of each piece is white and the other one is black and each p ...

  6. hdu 5465 Clarke and puzzle(前缀和,异或,nim博弈)

    Problem Description Clarke is a patient with multiple personality disorder. One day, Clarke split in ...

  7. jQuery判断元素是否是隐藏的代码

    if($("#elem_id").is(":hidden")) { } 实例代码1: 复制代码 代码如下: <!DOCTYPE HTML PUBLIC & ...

  8. java笔记之String的应用

    说来这String字符串也是运用广泛了,但是String的一些使用方法你是否能够了解清楚呢? 这是我这几天来整理的String笔记,其实这也是不全面的,要想深入了解,还得自己去oracle官网看JDK ...

  9. Javascript中正则表达式的全局匹配模式

    先看一道JavaScript题目,据说是国内某知名互联网企业的JavaScript笔试题,如果对正则的全局匹配模式不了解的话可能会对下面的输出结果感到疑惑. var str = "123#a ...

  10. C# Socket学习笔记一

    小记:刚接触网络编程觉得网络是个神奇的东西,所以对它就很有兴趣,想了解下网络是如何进行进行数据传输的,那么开始第一天的学习吧!ReadyGo!!! 首先我们要了解一下几点内容: 1.网络中进程之间如何 ...