1
0
mirror of https://github.com/OpenNebula/one.git synced 2024-12-22 13:33:52 +03:00

Added KVM Driver support (Not finished yet, XML creation pending)

Renamed some file for coherence.

git-svn-id: http://svn.opennebula.org/trunk@31 3034c82b-c49b-4eb3-8279-a7acafdc01c0
This commit is contained in:
Constantino Vázquez Blanco 2008-07-04 16:55:49 +00:00
parent 154b5440be
commit 39f766b512
19 changed files with 413 additions and 11 deletions

35
include/LibVirtDriver.h Normal file
View File

@ -0,0 +1,35 @@
#ifndef LIBVIRT_DRIVER_H_
#define LIBVIRT_DRIVER_H_
#include <map>
#include <string>
#include <sstream>
#include "VirtualMachineManagerDriver.h"
class LibVirtDriver : public VirtualMachineManagerDriver
{
public:
LibVirtDriver(
int userid,
const map<string,string> &attrs,
bool sudo,
VirtualMachinePool * pool,
const string _emulator):
VirtualMachineManagerDriver(userid, attrs,sudo,pool),
emulator(_emulator)
{};
~LibVirtDriver(){};
private:
int deployment_description(
const VirtualMachine * vm,
const string& file_name) const;
const string emulator;
};
#endif /*LIBVIRT_DRIVER_H_*/

View File

@ -34,19 +34,25 @@ inst_cp share/etc/oned.conf etc
inst_ln share/etc/mad/defaultrc etc/mad
inst_ln share/etc/mad/im_sshrc etc/mad
inst_ln share/etc/mad/vmm_xenrc etc/mad
inst_ln share/etc/mad/vmm_kvmrc etc/mad
inst_ln share/etc/default/vmm_xen.conf etc/default
inst_ln share/etc/default/vmm_kvm.conf etc/default
inst_ln share/scripts/madcommon.sh libexec
inst_ln src/vmm_mad/xen/one_vmm_xen.rb bin
inst_ln src/vmm_mad/xen/one_vmm_xen bin
inst_ln src/im_mad/xen/one_im_ssh.rb bin
inst_ln src/im_mad/xen/one_im_ssh bin
inst_ln src/vmm_mad/kvm_ssh/one_vmm_kvm.rb bin
inst_ln src/vmm_mad/kvm_ssh/one_vmm_kvm bin
inst_cp src/im_mad/xen/one_im_ssh.conf etc/default
inst_ln src/vmm_mad/xen/one_mad.rb lib/ruby
inst_ln src/im_mad/im_ssh/one_im_ssh.rb bin
inst_ln src/im_mad/im_ssh/one_im_ssh bin
inst_cp src/im_mad/xen/im_xen.conf etc
inst_cp src/im_mad/kvm/im_kvm.conf etc
inst_ln src/im_mad/xen/one_ssh.rb lib/ruby
inst_ln src/vmm_mad/xen/one_mad.rb lib/ruby
inst_ln src/client/ruby/one.rb lib/ruby
inst_ln src/client/ruby/client_utilities.rb lib/ruby
inst_ln src/client/ruby/command_parse.rb lib/ruby

View File

@ -0,0 +1,5 @@
#
# Default configuration attributes for the KVM driver
# (all domains will use these values as defaults)
#

17
share/etc/mad/vmm_kvmrc Normal file
View File

@ -0,0 +1,17 @@
# -------------------------------------------------------------------------- #
# Copyright 2002-2008, Distributed Systems Architecture Group, Universidad #
# Complutense de Madrid (dsa-research.org) #
# #
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
# not use this file except in compliance with the License. You may obtain #
# a copy of the License at #
# #
# http://www.apache.org/licenses/LICENSE-2.0 #
# #
# Unless required by applicable law or agreed to in writing, software #
# distributed under the License is distributed on an "AS IS" BASIS, #
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
# See the License for the specific language governing permissions and #
# limitations under the License. #
#--------------------------------------------------------------------------- #

View File

@ -9,8 +9,10 @@
# HOST_MONITORING_INTERVAL: Time in seconds between host monitorization
# VM_POLLING_INTERVAL: Time in seconds between virtual machine monitorization
#
# VM_RDIR: Path to access $ONE_LOCATION/var/ on the remote nodes. Only needed
# if this path is different in the nodes and in the frontend.
# VM_RDIR: The remote nodes must have access to $ONE_LOCATION/var, so this must
# be shared between the ONE server and the remote nodes. If the mount point of
# $ONE_LOCATION/var has a different path in the remote nodes than in the ONE server,
# set here the mount point of the _remote_ nodes
#
# PORT: Port where oned will listen for xmlrpc calls.
#
@ -39,10 +41,20 @@ DEBUG_LEVEL=3
#-------------------------------------------------------------------------------
IM_MAD = [
name = "one_im",
name = "im_xen",
executable = "bin/one_im_ssh",
arguments = "etc/default/one_im_ssh.conf",
default = "etc/default/one_im_ssh.conf" ]
arguments = "etc/default/im_xen.conf",
default = "etc/default/im_xen.conf" ]
#-------------------------------------------------------------------------------
# KVM Information Driver Manager sample configuration
#-------------------------------------------------------------------------------
# VM_MAD = [
# name = "im_kvm",
# executable = "bin/one_im_ssh",
# arguments = "etc/default/im_kvm.conf",
# default = "etc/default/im_kvm.conf" ]
#-------------------------------------------------------------------------------
#-------------------------------------------------------------------------------
# Virtualization Driver Configuration
@ -58,8 +70,21 @@ IM_MAD = [
#-------------------------------------------------------------------------------
VM_MAD = [
name = "one_vmm",
name = "vmm_xen",
executable = "bin/one_vmm_xen",
default = "etc/default/vmm_xen.conf",
type = "xen" ]
#-------------------------------------------------------------------------------
# KVM Virtualization Driver Manager sample configuration
#-------------------------------------------------------------------------------
# VM_MAD = [
# name = "vmm_kvm",
# executable = "bin/one_vmm_kvm",
# default = "etc/default/kvm_xen.conf",
# type = "kvm" ]
#-------------------------------------------------------------------------------

View File

@ -0,0 +1,8 @@
# Remote directory where scripts are written
REMOTE_DIR=/tmp/ne_im_scripts
cpuarchitecture=lib/im_probes/architecture.sh
nodename=lib/im_probes/name.sh
cpu=lib/im_probes/cpu.sh
kvm=lib/im_probes/kvm.rb

77
src/im_mad/kvm/kvm.rb Executable file
View File

@ -0,0 +1,77 @@
#!/usr/bin/env ruby
######
# First, get all the posible info out of virsh
# TODO : use virsh freecell when available
######
nodeinfo_text = `virsh nodeinfo`
nodeinfo_text.split(/\n/).each{|line|
if line.match('^CPU\(s\)')
$total_cpu = line.split(":")[1].strip.to_i * 100
elsif line.match('^CPU frequency')
$cpu_speed = line.split(":")[1].strip.split(" ")[0]
elsif line.match('^Memory size')
$total_memory = line.split(":")[1].strip.split(" ")[0]
end
}
######
# for everything else, top & proc
#####
NETINTERFACE = "eth1"
top_text=`top -bin2`
top_text.gsub!(/^top.*^top.*?$/m, "") # Strip first top output
top_text.split(/\n/).each{|line|
if line.match('^Mem')
line[4..-1].split(",").each{|elemento|
temp = elemento.strip.split("k ")
if temp[1] == "used"
$used_memory = temp[0]
elsif temp[1] == "free"
$free_memory = temp[0]
end
}
elsif line.match('^Cpu')
line[7..-1].split(",").each{|elemento|
temp = elemento.strip.split("%")
if temp[1]=="id"
$free_cpu = temp[0]
used = temp[0].to_f
$used_cpu = (((100 - used)*100).round / 100).to_f.to_s
break
end
}
end
}
net_text=`cat /proc/net/dev`
net_text.split(/\n/).each{|line|
if line.match("^ *#{NETINTERFACE}")
arr = line.split(":")[1].split(" ")
$netrx = arr[0]
$nettx = arr[8]
break
end
}
puts "TOTALCPU=#{$total_cpu}"
puts "CPUSPEED=#{$cpu_speed}"
puts "TOTALMEMORY=#{$total_memory}"
puts "USEDMEMORY=#{$used_memory}"
puts "FREEMEMORY=#{$free_memory}"
puts "FREECPU=#{$free_cpu}"
puts "USEDCPU=#{$used_cpu}"
puts "NETRX=#{$netrx}"
puts "NETTX=#{$nettx}"

36
src/vmm/LibVirtDriver.cc Normal file
View File

@ -0,0 +1,36 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2008, Distributed Systems Architecture Group, Universidad */
/* Complutense de Madrid (dsa-research.org) */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); you may */
/* not use this file except in compliance with the License. You may obtain */
/* a copy of the License at */
/* */
/* http://www.apache.org/licenses/LICENSE-2.0 */
/* */
/* Unless required by applicable law or agreed to in writing, software */
/* distributed under the License is distributed on an "AS IS" BASIS, */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
/* See the License for the specific language governing permissions and */
/* limitations under the License. */
/* -------------------------------------------------------------------------- */
#include "LibVirtDriver.h"
#include "Nebula.h"
#include <sstream>
#include <fstream>
int LibVirtDriver::deployment_description(
const VirtualMachine * vm,
const string& file_name) const
{
ostringstream oss;
oss << "cp /home/tinova/kvmxml.tmpl " << file_name ;
system(oss.str().c_str());
return 0;
}

View File

@ -9,6 +9,7 @@ source_files=[
'VirtualMachineManager.cc',
'VirtualMachineManagerDriver.cc',
'XenDriver.cc',
'LibVirtDriver.cc',
]
# Build library

View File

@ -18,6 +18,7 @@
#include "VirtualMachineManager.h"
#include "Nebula.h"
#include "XenDriver.h"
#include "LibVirtDriver.h"
#include <time.h>
/* ************************************************************************** */
@ -787,7 +788,7 @@ void VirtualMachineManager::load_mads(int uid)
}
else if ( type == "KVM" )
{
vmm_driver = new KvmDriver(uid, vattr->value(),(uid != 0),vmpool);
vmm_driver = new LibVirtDriver(uid, vattr->value(),(uid != 0),vmpool,"kvm");
}
else
{

17
src/vmm_mad/kvm_ssh/one_vmm_kvm Executable file
View File

@ -0,0 +1,17 @@
#!/bin/bash
if [ -z "${ONE_LOCATION}" ]; then
echo "Please, set ONE_LOCATION variable."
exit -1
fi
. $ONE_LOCATION/libexec/madcommon.sh
# Export the vmm_mad specific rc
export_rc_vars $ONE_LOCATION/etc/mad/vmm_kvmrc
# Go to ONE_LOCATION
cd $ONE_LOCATION
# Execute the actual MAD
execute_mad $*

View File

@ -0,0 +1,174 @@
#!/usr/bin/env ruby
ONE_LOCATION=ENV["ONE_LOCATION"]
if !ONE_LOCATION
puts "ONE_LOCATION not set"
exit -1
end
$: << ONE_LOCATION+"/lib/ruby"
require 'pp'
require 'one_mad'
require 'open3'
class DM < ONEMad
def initialize
super(5, 4)
end
def action_init(args)
send_message("INIT", "SUCCESS")
log("KVM Access Driver initialized.")
end
def action_deploy(args)
std_action("DEPLOY", "create #{args[3]}", args)
end
def action_shutdown(args)
std_action("SHUTDOWN", "shutdown #{args[3]}", args)
end
def action_cancel(args)
std_action("CANCEL", "destroy #{args[3]}", args)
end
def action_checkpoint(args)
send_message("CHECKPOINT", "FAILURE", args[1], "action not supported for KVM")
end
def action_save(args)
std_action("SAVE", "save #{args[3]} #{args[4]}", args)
end
def action_restore(args)
std_action("RESTORE", "restore #{args[3]}", args)
end
def action_migrate(args)
send_message("MIGRATE", "FAILURE", args[1], "action not supported for KVM")
end
def action_poll(args)
std=Open3.popen3(
"ssh -n #{args[2]} virsh dominfo #{args[3]};"+
" echo ExitCode: $? 1>&2")
stdout=std[1].read
stderr=std[2].read
exit_code=get_exit_code(stderr)
if exit_code!=0
send_message("POLL", "FAILURE", args[1])
return nil
end
log("stdout:")
log(stdout)
log("stderr:")
log(stderr)
info = parse_virsh_dominfo(stdout)
# TODO -> Get more info, like NET info. Need to know the iface name (e.g. tap0)
send_message("POLL", "SUCCESS", args[1], info)
end
###########################
# Common action functions #
###########################
def std_action(name, command, args)
std=exec_kvm_command(args[2], command)
stdout=std[1].read
stderr=std[2].read
log("stdout:")
log(stdout)
log("stderr:")
log(stderr)
write_response(name, stdout, stderr, args)
end
def exec_kvm_command(host, command)
Open3.popen3(
"ssh -n #{host} virsh #{command} ;"+
" echo ExitCode: $? 1>&2")
end
def write_response(action, stdout, stderr, args)
exit_code=get_exit_code(stderr)
if exit_code==0
domain_name=get_domain_name(stdout)
send_message(action, "SUCCESS", args[1], domain_name)
else
error_message=get_error_message(stderr)
send_message(action, "FAILURE", args[1], error_message)
end
end
#########################################
# Get information from virsh #
#########################################
# From STDERR if exit code == 1
def get_exit_code(str)
tmp=str.scan(/^ExitCode: (\d*)$/)
return nil if !tmp[0]
tmp[0][0].to_i
end
# From STDERR if exit code == 1
def get_error_message(str)
tmp=str.scan(/^Error: (.*)$/)
return "Unknown error" if !tmp[0]
tmp[0][0]
end
# From STDOUT if exit code == 0
def get_domain_name(str)
tmp=str.scan(/^Domain (.*) created from .*$/)
return nil if !tmp[0]
tmp[0][0]
end
###############################
# Get information from virsh #
###############################
def parse_virsh_dominfo(returned_info)
info = ""
returned_info.each_line {|line|
columns=line.split(":").collect {|c| c.strip }
case columns[0]
when 'Used memory'
info += "USEDMEMORY=" + columns[1].to_i*1024
end
}
return info
end
end
dm=DM.new
dm.loop