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 ...
随机推荐
- C# 动态Linq(结合反射)
这篇文章决定对最近一个单机版Web程序用到的东西总结一下. 一.反射Linq之OrderBy 动态Linq结合反射对某字段排序: namespace 动态Linq { class Program ...
- openssl CA 自签证书,阿里云配置tomcat https
<一,openssl CA自签发证书> 1,生成私钥 openssl genrsa 1024 > private.key;
- centos directory server
http://www.aliyun.com/zixun/content/3_12_517262.html CentOS系统安装Directory Server 8.1操作方法 发布时间:2014-12 ...
- C#常用語法糖(Csharp Syntactic sugar)
首先需要声明的是“语法糖”这个词绝非贬义词,它可以给我带来方便,是一种便捷的写法,编译器会帮我们做转换:而且可以提高开发编码的效率,在性能上也不会带来损失.这让java开发人员羡慕不已,呵呵. 1. ...
- ACdream OJ 1153 (k-GCD)
题目链接: http://115.28.76.232/problem?pid=1153 题意: 从给定的n个数中取出k个数,使得他们的最大公约数最大,求这个最大的公约数 分析: 暴力分解不可取,我们能 ...
- wpf Visibility 动画
XAML实现: [xhtml] view plaincopy <Border Height="100" Width="80" CornerRadius=& ...
- 怎样给你的Android 安装文件(APK)减肥
转自: http://greenrobot.me/devpost/putting-your-apks-on-diet/ Android的apk文件越来越大了这已经是一个不争的事实. 在Android ...
- H5单页面架构:backbone + requirejs + zepto + underscore
首先,来看看整个项目结构. 跟上一篇angular类似,libs里多了underscore和zepto.三个根目录文件: index.html:唯一的html main.js:requirejs的配置 ...
- office 文件在网页中显示
1.如何在网页上显示word和excel a.可以使用office组件或aspose将word 和excel 转换为pdf 然后在网页上打开pdf,但是效果不是很好 .比如说excel 多个工作薄不是 ...
- 疯狂Android第二章:Adapter以及部分控件使用
第二章 重点:1.理解View以及各种布局的优缺点,适用场景. 2.熟练掌握adapter原理与用法. 3.熟悉其它控件的基本使用方法. /////////////////////////////// ...