以获取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. java数组复制的方式和效率比较

    java中,数组的复制有以下三种方式: 1. 调用System.arraycopy(Arrays.copyOfRange可以当作第四种,但是底层调用的是System.arraycopy,所以,认为是同 ...

  2. [转]Traceroute网络排障实用指南(2)

    五.优先级与限速 5.1 Traceroute延时判断影响因素 Traceroute延时包括三点: 探测包到达一个特定路由器的时间 路由器生成IPMI TTL Exceed的时间 ICMP TTL E ...

  3. c保存lua函数

    使用下面方式可保存lua任何值,目前只实现fucntion的保存,且无参数.如果需要实现参数,可自己扩展: 可实现下面方式: CFun( lua_fun ) -- okCFun( function() ...

  4. 解决 jsp:include 引用文件时出现乱码的问题

    阐述问题前,先来看一下下面这张图片左侧iframe中的乱码页面: 这个就是让我纠结好一阵子的乱码截图: 这个乱码页面中是使用了<jsp:include>引用标签后出现了这个问题: 源码截图 ...

  5. sql server去除重复信息,

    SELECT st_id FROM ( SELECT *,ROW_NUMBER() OVER( PARTITION BY st_code ORDER BY st_code ) AS num FROM ...

  6. DevExpress中SearchLookUpEdit用法总结

    在前一个项目中用到了DevExpress,需要搜索某一个字段,来拉取出对应的相关信息,比来比去,发现SearchLookUpEdit的用户体验更好,但自己是个不折不扣的C#和DevExpress的初学 ...

  7. C#中大List的内存分配

    之前在开发中只用到List的时候几乎就是拿过来就用,从来没有考虑过List的内存分配问题,试想一个有10万元素的List的在构造和添加元素时内存是如何变化的呢?在MSDN上关于List的Capacit ...

  8. 写sql语句注意事项

    做管理系统的,无论是bs结构的还是cs结构的,都不可避免的涉及到数据库表结构的设计,sql语句的编写等.因此在开发系统的时候,表结构设计是否合理,sql语句是否标准,写出的sql性能是否优化往往会成为 ...

  9. AdapterView及其子类之三:基于ListView及ArrayAdapter实现列表

    见归档项目ListViewDemo.zip. 基本步骤如下: 1.创建主布局文件,里面包含一个ListView元素. <RelativeLayout xmlns:android="ht ...

  10. js scroll 教程

    <html><head><script language=javascript>function s(){var c = window.document.body. ...