diff --git a/include/LibVirtDriver.h b/include/LibVirtDriver.h index 5f4e085d53..974aba5831 100644 --- a/include/LibVirtDriver.h +++ b/include/LibVirtDriver.h @@ -1,18 +1,18 @@ -/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ /* Copyright 2002-2010, OpenNebula Project Leads (OpenNebula.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. */ -/* -------------------------------------------------------------------------- */ +/* */ +/* 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. */ +/* -------------------------------------------------------------------------- */ #ifndef LIBVIRT_DRIVER_H_ #define LIBVIRT_DRIVER_H_ @@ -41,17 +41,31 @@ public: private: int deployment_description( - const VirtualMachine * vm, - const string& file_name) const; - + const VirtualMachine * vm, + const string& file_name) const + { + int rc = -1; + + if (emulator == "kvm") + { + rc = deployment_description_kvm(vm,file_name); + } + else if (emulator == "vmware") + { + rc = deployment_description_vmware(vm,file_name); + } + + return rc; + } + int deployment_description_kvm( - const VirtualMachine * vm, + const VirtualMachine * vm, const string& file_name) const; - + int deployment_description_vmware( - const VirtualMachine * vm, + const VirtualMachine * vm, const string& file_name) const; - + const string emulator; }; diff --git a/src/vmm/LibVirtDriverKVM.cc b/src/vmm/LibVirtDriverKVM.cc new file mode 100644 index 0000000000..f40ebbca98 --- /dev/null +++ b/src/vmm/LibVirtDriverKVM.cc @@ -0,0 +1,590 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2010, OpenNebula Project Leads (OpenNebula.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 +#include +#include + +int LibVirtDriver::deployment_description_kvm( + const VirtualMachine * vm, + const string& file_name) const +{ + ofstream file; + + int num; + vector attrs; + + string vcpu; + string memory; + + int memory_in_kb = 0; + + string kernel = ""; + string initrd = ""; + string boot = ""; + string root = ""; + string kernel_cmd = ""; + string bootloader = ""; + + const VectorAttribute * disk; + const VectorAttribute * context; + + string type = ""; + string target = ""; + string bus = ""; + string ro = ""; + bool readonly; + + const VectorAttribute * nic; + + string mac = ""; + string bridge = ""; + string script = ""; + string model = ""; + + const VectorAttribute * graphics; + + string listen = ""; + string port = ""; + string passwd = ""; + string keymap = ""; + + const VectorAttribute * input; + + const VectorAttribute * features; + + string pae = ""; + string acpi = ""; + + const VectorAttribute * raw; + string data; + + // ------------------------------------------------------------------------ + + file.open(file_name.c_str(), ios::out); + + if (file.fail() == true) + { + goto error_file; + } + + // ------------------------------------------------------------------------ + // Starting XML document + // ------------------------------------------------------------------------ + + file << "" << endl; + + // ------------------------------------------------------------------------ + // Domain name + // ------------------------------------------------------------------------ + + file << "\tone-" << vm->get_oid() << "" << endl; + + // ------------------------------------------------------------------------ + // CPU + // ------------------------------------------------------------------------ + + vm->get_template_attribute("VCPU", vcpu); + + if(vcpu.empty()) + { + get_default("VCPU", vcpu); + } + + if (!vcpu.empty()) + { + file << "\t" << vcpu << "" << endl; + } + + // ------------------------------------------------------------------------ + // Memory + // ------------------------------------------------------------------------ + + vm->get_template_attribute("MEMORY",memory); + + if (memory.empty()) + { + get_default("MEMORY",memory); + } + + if (!memory.empty()) + { + memory_in_kb = atoi(memory.c_str()) * 1024; + + file << "\t" << memory_in_kb << "" << endl; + } + else + { + goto error_memory; + } + + // ------------------------------------------------------------------------ + // OS and boot options + // ------------------------------------------------------------------------ + + file << "\t" << endl; + + if (emulator == "kvm") + { + file << "\t\thvm" << endl; + } + + num = vm->get_template_attribute("OS",attrs); + + // Get values & defaults + + if ( num > 0 ) + { + const VectorAttribute * os; + + os = dynamic_cast(attrs[0]); + + if( os != 0 ) + { + kernel = os->vector_value("KERNEL"); + initrd = os->vector_value("INITRD"); + boot = os->vector_value("BOOT"); + root = os->vector_value("ROOT"); + kernel_cmd = os->vector_value("KERNEL_CMD"); + bootloader = os->vector_value("BOOTLOADER"); + } + } + + if ( kernel.empty() ) + { + get_default("OS","KERNEL",kernel); + } + + if ( initrd.empty() ) + { + get_default("OS","INITRD",initrd); + } + + if ( bootloader.empty() ) + { + get_default("OS","BOOTLOADER",bootloader); + } + + if ( boot.empty() ) + { + get_default("OS","BOOT",boot); + + if ( boot.empty() ) + { + goto error_boot; + } + } + + if ( root.empty() ) + { + get_default("OS","ROOT",root); + } + + if ( kernel_cmd.empty() ) + { + get_default("OS","KERNEL_CMD",kernel_cmd); + } + + // Start writing to the file with the info we got + + if ( !kernel.empty() ) + { + file << "\t\t" << kernel << "" << endl; + + if ( !initrd.empty() ) + { + file << "\t\t" << initrd << "" << endl; + } + + if ( !root.empty() ) + { + kernel_cmd = "root=/dev/" + root + " " + kernel_cmd; + } + + if (!kernel_cmd.empty()) + { + file << "\t\t" << kernel_cmd << "" << endl; + } + } + else if ( !bootloader.empty() ) + { + file << "\t\t" << bootloader << "" << endl; + } + + + file << "\t\t" << endl; + + file << "\t" << endl; + + attrs.clear(); + + // ------------------------------------------------------------------------ + // Disks + // ------------------------------------------------------------------------ + + file << "\t" << endl; + + if (emulator == "kvm") + { + file << "\t\t/usr/bin/kvm" << endl; + } + + num = vm->get_template_attribute("DISK",attrs); + + for (int i=0; i < num ;i++) + { + disk = dynamic_cast(attrs[i]); + + if ( disk == 0 ) + { + continue; + } + + type = disk->vector_value("TYPE"); + target = disk->vector_value("TARGET"); + ro = disk->vector_value("READONLY"); + bus = disk->vector_value("BUS"); + + if (target.empty()) + { + goto error_disk; + } + + readonly = false; + + if ( !ro.empty() ) + { + transform(ro.begin(),ro.end(),ro.begin(),(int(*)(int))toupper); + + if ( ro == "YES" ) + { + readonly = true; + } + } + + if (type.empty() == false) + { + transform(type.begin(),type.end(),type.begin(),(int(*)(int))toupper); + } + + if ( type == "BLOCK" ) + { + file << "\t\t" << endl + << "\t\t\t" << endl; + } + else if ( type == "CDROM" ) + { + file << "\t\t" << endl + << "\t\t\t" << endl; + } + else + { + file << "\t\t" << endl + << "\t\t\t" << endl; + } + + file << "\t\t\t" << endl; + } + else + { + file << "/>" << endl; + } + + if (readonly) + { + file << "\t\t\t" << endl; + } + + file << "\t\t" << endl; + } + + attrs.clear(); + + // ------------------------------------------------------------------------ + // Context Device + // ------------------------------------------------------------------------ + + if ( vm->get_template_attribute("CONTEXT",attrs) == 1 ) + { + context = dynamic_cast(attrs[0]); + target = context->vector_value("TARGET"); + + if ( !target.empty() ) + { + file << "\t\t" << endl; + file << "\t\t\t" << endl; + file << "\t\t\t" << endl; + file << "\t\t\t" << endl; + file << "\t\t" << endl; + } + else + { + vm->log("VMM", Log::WARNING, "Could not find target device to" + " attach context, will continue without it."); + } + } + + attrs.clear(); + + // ------------------------------------------------------------------------ + // Network interfaces + // ------------------------------------------------------------------------ + + num = vm->get_template_attribute("NIC",attrs); + + for(int i=0; i(attrs[i]); + + if ( nic == 0 ) + { + continue; + } + + bridge = nic->vector_value("BRIDGE"); + mac = nic->vector_value("MAC"); + target = nic->vector_value("TARGET"); + script = nic->vector_value("SCRIPT"); + model = nic->vector_value("MODEL"); + + if ( bridge.empty() ) + { + file << "\t\t" << endl; + } + else + { + file << "\t\t" << endl; + file << "\t\t\t" << endl; + } + + if( !mac.empty() ) + { + file << "\t\t\t" << endl; + } + + if( !target.empty() ) + { + file << "\t\t\t" << endl; + } + + if( !script.empty() ) + { + file << "\t\t\t