以获取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. shell重定向

    输入重定向 和输出重定向一样,Unix 命令也可以从文件获取输入,语法为: command < file 这样,本来需要从键盘获取输入的命令会转移到文件读取内容. 注意:输出重定向是大于号(&g ...

  2. 【转】Android下编译jni库的二种方法(含示例) -- 不错

    原文网址:http://blog.sina.com.cn/s/blog_3e3fcadd01011384.html 总结如下:两种方法是:1)使用Android源码中的Make系统2)使用NDK(从N ...

  3. 安装开源项目 MultiType (基于 RecyclerView)出现的各种问题 -- 自己的第一篇博客

    一.引入开源项目的方式 使用开源项目 MultiType 的两种方式: 1.maven引入:在主Module 的 build.gradle 中加入 dependencies { ...... comp ...

  4. PSPInstance Object | Web Python

    PSPInstance Object | Web Python The PSPInstance object is available to all PSP pages through the psp ...

  5. 回溯算法-C#语言解决八皇后问题的写法与优化

    结合问题说方案,首先先说问题: 八皇后问题:在8X8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行.同一列或同一斜线上,问有多少种摆法. 嗯,这个问题已经被使用各种语言解 ...

  6. [转]ActiveMQ 即时通讯服务 浅析

    一. 概述与介绍 ActiveMQ 是Apache出品,最流行的.功能强大的即时通讯和集成模式的开源服务器.ActiveMQ 是一个完全支持JMS1.1和J2EE 1.4规范的 JMS Provide ...

  7. 很少人知道的office专用卸载工具

    Microsoft Office是微软公司开发的一套基于 Windows 操作系统的办公软件套装.常用组件有 Word.Excel.Powerpoint等.当我们不需要再用了或者想安装旧版本的话,首先 ...

  8. Unity 鼠标点击左右移动,人物跟随旋转

    上代码: using UnityEngine; using System.Collections; public class Test : MonoBehaviour { private Vector ...

  9. 自定义视图控制器切换(iOS)

    在iOS开发过程中,通常我们会使用UINavigationController,UITabbarController等苹果提供的视图控制器来切换我们的视图.在iOS5之前,如果要自定义容器视图控制器很 ...

  10. sqlplus常用操作命令2

    常用编辑命令:A[ppend] text 将text附加到当前行之后C[hange] /old /new 将当前行中的old替换为newCLear] buff[er] 清除缓冲区中的所有行DEL 删除 ...