kvm生成一台新机器后,并不能自动分配新的ip。本文介绍了基于php语言,结合libvirt一系列的工具,实现通过命令行对虚拟机进行克隆和自动ip分配的方案。

前置条件

克隆来源的domain里边的文件已经被删除:/etc/udev/rules.d/70-persistent-net.rules。

实现流程

process.png

实现代码

<?php
$opts = getopt('d:', [
'ip:',
'old:',
'new:',
]);
if (empty($opts)) {
help();
}
define('IMG_DIR', '/data/vm-images/');
function help()
{
echo <<
Usage: php clone.php --ip [ip] --old [domain] --new [domain]
ip 创建的domain的ip,选填
old 从哪个domain复制,默认为standard
new 新domain的名称,必填
HELP;
exit(1);
}
$ip = '';
if (isset($opts['ip'])) {
$ip = $opts['ip'];
}
$old = 'standard';
if (isset($opts['old'])) {
$old = $opts['old'];
}
if (!isset($opts['new'])) {
help();
}
$new = $opts['new'];
$file = IMG_DIR.$new.'.img';
echo '克隆镜像'.PHP_EOL;
$cmd = sprintf('virt-clone -o %s -n %s -f %s', $old, $new, $file);
echo $cmd.PHP_EOL;
system($cmd, $status);
if ($status === 0) {
echo '镜像克隆成功'.PHP_EOL;
}
if (!$ip) {
exit;
}
$cmd = sprintf('cat /etc/libvirt/qemu/%s.xml |grep -E "(uuid|<mac address)"', $new);
exec($cmd, $lines, $status);
if ($status !== 0) {
die('获取配置失败');
}
$uuid = '';
$mac = '';
foreach($lines as $line) {
if (preg_match('#uuid>([^<]+)<#', $line, $ms)) {
$uuid = $ms[1];
} elseif (preg_match('#address\=\'([^\']+)\'#', $line, $ms)) {
$mac = $ms[1];
}
}
var_dump($uuid, $mac);
unset($lines);
echo "获取网卡配置".PHP_EOL;
$domFile = '/etc/sysconfig/network-scripts/ifcfg-eth0';
$cmd = sprintf('virt-cat -d %s %s', $new, $domFile);
echo $cmd.PHP_EOL;
exec($cmd, $lines, $status);
if ($status !== 0) {
die('获取网卡配置失败');
}
foreach($lines as &$line) {
list($key, $value) = explode('=', $line);
switch($key) {
case 'HWADDR':
$line = $key.'='.$mac;
break;
case 'IPADDR':
$line = $key.'='.$ip;
break;
case 'UUID':
$line = $key.'='.$uuid;
break;
}
}
$ethFile = __DIR__.'/tmp/'.$new.'/ifcfg-eth0';
if (!is_dir(dirname($ethFile))) {
mkdir(dirname($ethFile), 0755, true);
}
file_put_contents($ethFile, implode("\n", $lines));
unset($lines);
echo "替换网卡文件".PHP_EOL;
$cmd = sprintf('virt-copy-in -d %s %s %s', $new, $ethFile, dirname($domFile));
echo $cmd.PHP_EOL;
system($cmd, $status);
if ($status !==0) {
die("写入网卡文件失败");
}
echo "写入网卡文件成功".PHP_EOL;
echo "克隆成功!".PHP_EOL;

标签: php, kvm

添加新评论