diff --git a/include/Cluster.h b/include/Cluster.h index d1c10c0760..a6e8415e06 100644 --- a/include/Cluster.h +++ b/include/Cluster.h @@ -20,6 +20,7 @@ #include "PoolSQL.h" #include "ObjectCollection.h" #include "DatastorePool.h" +#include "ClusterTemplate.h" using namespace std; @@ -30,6 +31,23 @@ class Cluster : public PoolObjectSQL { public: + /** + * Returns the SYSTEM_DS attribute, or the system DS id if it is not defined + * + * @return the SYSTEM_DS attribute, or the system DS id if it is not defined + */ + int get_ds_id() + { + int ds_id; + + if ( obj_template->get("SYSTEM_DS", ds_id) == false ) + { + ds_id = DatastorePool::SYSTEM_DS_ID; + } + + return ds_id; + } + // ************************************************************************* // Object Collections (Public) // ************************************************************************* @@ -78,6 +96,7 @@ public: */ int add_datastore(int id, string& error_msg) { + // TODO: should fail for any system DS? if ( id == DatastorePool::SYSTEM_DS_ID ) { ostringstream oss; @@ -184,11 +203,9 @@ private: // Constructor // ************************************************************************* - Cluster(int id, const string& name): - PoolObjectSQL(id,CLUSTER,name,-1,-1,"","",table), - hosts("HOSTS"), - datastores("DATASTORES"), - vnets("VNETS"){}; + Cluster(int id, + const string& name, + ClusterTemplate* cl_template); virtual ~Cluster(){}; @@ -259,6 +276,14 @@ private: * @return 0 if cluster can be dropped, -1 otherwise */ int check_drop(string& error_msg); + + /** + * Factory method for cluster templates + */ + Template * get_new_template() const + { + return new ClusterTemplate; + } }; #endif /*CLUSTER_H_*/ diff --git a/include/ClusterPool.h b/include/ClusterPool.h index 365dac64e3..35712708ed 100644 --- a/include/ClusterPool.h +++ b/include/ClusterPool.h @@ -151,7 +151,7 @@ private: */ PoolObjectSQL * create() { - return new Cluster(-1,""); + return new Cluster(-1,"",0); }; }; diff --git a/include/ClusterTemplate.h b/include/ClusterTemplate.h new file mode 100644 index 0000000000..b317b2e592 --- /dev/null +++ b/include/ClusterTemplate.h @@ -0,0 +1,39 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2012, 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. */ +/* -------------------------------------------------------------------------- */ + +#ifndef CLUSTER_TEMPLATE_H_ +#define CLUSTER_TEMPLATE_H_ + +#include "Template.h" + +using namespace std; + +/** + * Cluster Template class + */ +class ClusterTemplate : public Template +{ +public: + ClusterTemplate(): + Template(false,'=',"TEMPLATE"){}; + + ~ClusterTemplate(){}; +}; + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +#endif /*CLUSTER_TEMPLATE_H_*/ diff --git a/include/Datastore.h b/include/Datastore.h index a18408b4df..2b03953032 100644 --- a/include/Datastore.h +++ b/include/Datastore.h @@ -91,6 +91,16 @@ public: { return disk_type; }; + + /** + * Returns true if this is a system datastore + * @return true if this is a system datastore + */ + bool is_system() const + { + return system_ds == 1; + }; + /** * Modifies the given VM disk attribute adding the relevant datastore * attributes @@ -134,6 +144,11 @@ private: */ string base_path; + /** + * 1 if this is a system DS + */ + int system_ds; + /** * Disk types for the Images created in this datastore */ @@ -203,7 +218,7 @@ private: } /** - * Factory method for virtual network templates + * Factory method for datastore templates */ Template * get_new_template() const { diff --git a/include/History.h b/include/History.h index 952320e62c..f9a9dd9b71 100644 --- a/include/History.h +++ b/include/History.h @@ -46,6 +46,8 @@ public: const string& hostname, const string& vmm, const string& vnm, + const string& tmm, + int ds_id, const string& vm_info); ~History(){}; @@ -89,6 +91,9 @@ private: string vmm_mad_name; string vnm_mad_name; + string tm_mad_name; + + int ds_id; time_t stime; time_t etime; diff --git a/include/Nebula.h b/include/Nebula.h index 1bab2d21b6..a3aa35b781 100644 --- a/include/Nebula.h +++ b/include/Nebula.h @@ -243,30 +243,6 @@ public: return ds_location; }; - /** - * Returns the Transfer Manager for the system datastore - * @return the tm name. - */ - string get_system_ds_tm_mad() - { - Datastore * ds; - string tm_mad = ""; - - ds = dspool->get(DatastorePool::SYSTEM_DS_ID, true); - - if ( ds == 0 ) - { - NebulaLog::log("DaS", Log::ERROR, "Can not get system datastore"); - return tm_mad; - } - - tm_mad = ds->get_tm_mad(); - - ds->unlock(); - - return tm_mad; - }; - /** * Returns the path of the log file for a VM, depending where OpenNebula is * installed, diff --git a/include/RequestManagerUpdateTemplate.h b/include/RequestManagerUpdateTemplate.h index 73880f540e..511f149ce7 100644 --- a/include/RequestManagerUpdateTemplate.h +++ b/include/RequestManagerUpdateTemplate.h @@ -170,6 +170,24 @@ public: ~DocumentUpdateTemplate(){}; }; +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + +class ClusterUpdateTemplate : public RequestManagerUpdateTemplate +{ +public: + ClusterUpdateTemplate(): + RequestManagerUpdateTemplate("ClusterUpdateTemplate", + "Updates a cluster template") + { + Nebula& nd = Nebula::instance(); + pool = nd.get_clpool(); + auth_object = PoolObjectSQL::CLUSTER; + }; + + ~ClusterUpdateTemplate(){}; +}; + /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ diff --git a/include/RequestManagerVirtualMachine.h b/include/RequestManagerVirtualMachine.h index 10b415352d..284469508e 100644 --- a/include/RequestManagerVirtualMachine.h +++ b/include/RequestManagerVirtualMachine.h @@ -57,13 +57,16 @@ protected: AuthRequest::Operation op); int get_host_information(int hid, string& name, string& vmm, string& vnm, - RequestAttributes& att, PoolObjectAuth& host_perms); + string& tm, int& ds_id, RequestAttributes& att, + PoolObjectAuth& host_perms); int add_history(VirtualMachine * vm, int hid, const string& hostname, const string& vmm_mad, const string& vnm_mad, + const string& tm_mad, + int ds_id, RequestAttributes& att); VirtualMachine * get_vm(int id, RequestAttributes& att); diff --git a/include/VirtualMachine.h b/include/VirtualMachine.h index 7a16a92e3a..8902f58913 100644 --- a/include/VirtualMachine.h +++ b/include/VirtualMachine.h @@ -242,7 +242,9 @@ public: int hid, const string& hostname, const string& vmm_mad, - const string& vnm_mad); + const string& vnm_mad, + const string& tm_mad, + int ds_id); /** * Duplicates the last history record. Only the host related fields are @@ -318,6 +320,55 @@ public: return previous_history->vnm_mad_name; }; + + /** + * Returns the datastore ID of the system DS for the host. The hasHistory() + * function MUST be called before this one. + * @return the ds id + */ + string get_ds_id() const + { + ostringstream oss; + + oss << history->ds_id; + + return oss.str(); + }; + + /** + * Returns the datastore ID of the system DS for the previous host. + * The hasPreviousHistory() function MUST be called before this one. + * @return the TM mad name + */ + string get_previous_ds_id() const + { + ostringstream oss; + + oss << previous_history->ds_id; + + return oss.str(); + }; + + /** + * Returns the TM driver name for the current host. The hasHistory() + * function MUST be called before this one. + * @return the TM mad name + */ + const string & get_tm_mad() const + { + return history->tm_mad_name; + }; + + /** + * Returns the TM driver name for the previous host. The + * hasPreviousHistory() function MUST be called before this one. + * @return the TM mad name + */ + const string & get_previous_tm_mad() const + { + return previous_history->tm_mad_name; + }; + /** * Returns the transfer filename. The transfer file is in the form: * $ONE_LOCATION/var/$VM_ID/transfer.$SEQ diff --git a/install.sh b/install.sh index 02743f1165..c0bc6a0712 100755 --- a/install.sh +++ b/install.sh @@ -925,6 +925,7 @@ ONEDB_MIGRATOR_FILES="src/onedb/2.0_to_2.9.80.rb \ src/onedb/3.3.80_to_3.4.0.rb \ src/onedb/3.4.0_to_3.4.1.rb \ src/onedb/3.4.1_to_3.5.80.rb \ + src/onedb/3.5.80_to_3.6.0.rb \ src/onedb/onedb.rb \ src/onedb/onedb_backend.rb" diff --git a/share/doc/xsd/acct.xsd b/share/doc/xsd/acct.xsd index 3a96b5d37a..e8ff06e4c9 100644 --- a/share/doc/xsd/acct.xsd +++ b/share/doc/xsd/acct.xsd @@ -21,6 +21,8 @@ + + diff --git a/share/doc/xsd/cluster.xsd b/share/doc/xsd/cluster.xsd index 17df53e31f..7fdacacb8d 100644 --- a/share/doc/xsd/cluster.xsd +++ b/share/doc/xsd/cluster.xsd @@ -27,6 +27,7 @@ + diff --git a/share/doc/xsd/datastore.xsd b/share/doc/xsd/datastore.xsd index c1f5dfac98..e3a0788e83 100644 --- a/share/doc/xsd/datastore.xsd +++ b/share/doc/xsd/datastore.xsd @@ -28,6 +28,7 @@ + diff --git a/share/doc/xsd/test.sh b/share/doc/xsd/test.sh index ede292192a..50d77e06a5 100755 --- a/share/doc/xsd/test.sh +++ b/share/doc/xsd/test.sh @@ -33,8 +33,8 @@ onegroup create newgroup # Host -onehost create host01 --im im_test --vm vmm_test --net dummy -onehost create host02 --im im_test --vm vmm_test --net dummy +onehost create host01 --im im_dummy --vm vmm_dummy --net dummy +onehost create host02 --im im_dummy --vm vmm_dummy --net dummy onecluster addhost newcluster host02 diff --git a/share/doc/xsd/vm.xsd b/share/doc/xsd/vm.xsd index 134f196d2d..81155bd02b 100644 --- a/share/doc/xsd/vm.xsd +++ b/share/doc/xsd/vm.xsd @@ -95,6 +95,8 @@ + + diff --git a/src/cli/one_helper/onecluster_helper.rb b/src/cli/one_helper/onecluster_helper.rb index aca9f36d6c..41028cb90a 100644 --- a/src/cli/one_helper/onecluster_helper.rb +++ b/src/cli/one_helper/onecluster_helper.rb @@ -99,6 +99,11 @@ class OneClusterHelper < OpenNebulaHelper::OneHelper puts str % ["NAME", cluster.name] puts + CLIHelper.print_header(str_h1 % "CLUSTER TEMPLATE", false) + puts cluster.template_str + + puts + CLIHelper.print_header("%-15s" % ["HOSTS"]) cluster.host_ids.each do |id| puts "%-15s" % [id] diff --git a/src/cli/onecluster b/src/cli/onecluster index 8cb5ac0dd3..6497e6b34e 100755 --- a/src/cli/onecluster +++ b/src/cli/onecluster @@ -173,4 +173,16 @@ cmd=CommandParser::CmdParser.new(ARGV) do cluster.delvnet(args[1].to_i) end end + + update_desc = <<-EOT.unindent + Update the template contents. If a path is not provided the editor will + be launched to modify the current content. + EOT + + command :update, update_desc, :clusterid, [:file, nil] do + helper.perform_action(args[0],options,"modified") do |obj| + str = OpenNebulaHelper.update_template(args[0], obj, args[1]) + obj.update(str) + end + end end diff --git a/src/cluster/Cluster.cc b/src/cluster/Cluster.cc index 78b93ddd28..501c9fa5a2 100644 --- a/src/cluster/Cluster.cc +++ b/src/cluster/Cluster.cc @@ -33,6 +33,29 @@ const char * Cluster::db_bootstrap = "CREATE TABLE IF NOT EXISTS cluster_pool (" "gid INTEGER, owner_u INTEGER, group_u INTEGER, other_u INTEGER, " "UNIQUE(name))"; +/* ************************************************************************ */ +/* Cluster :: Constructor/Destructor */ +/* ************************************************************************ */ + +Cluster::Cluster( + int id, + const string& name, + ClusterTemplate* cl_template): + PoolObjectSQL(id,CLUSTER,name,-1,-1,"","",table), + hosts("HOSTS"), + datastores("DATASTORES"), + vnets("VNETS") +{ + if (cl_template != 0) + { + obj_template = cl_template; + } + else + { + obj_template = new ClusterTemplate; + } +} + /* ------------------------------------------------------------------------ */ /* ------------------------------------------------------------------------ */ @@ -170,6 +193,7 @@ string& Cluster::to_xml(string& xml) const string host_collection_xml; string ds_collection_xml; string vnet_collection_xml; + string template_xml; oss << "" << @@ -179,7 +203,7 @@ string& Cluster::to_xml(string& xml) const hosts.to_xml(host_collection_xml) << datastores.to_xml(ds_collection_xml) << vnets.to_xml(vnet_collection_xml) << - + obj_template->to_xml(template_xml) << ""; xml = oss.str(); @@ -256,6 +280,18 @@ int Cluster::from_xml(const string& xml) ObjectXML::free_nodes(content); content.clear(); + // Get associated classes + ObjectXML::get_nodes("/CLUSTER/TEMPLATE", content); + + if (content.empty()) + { + return -1; + } + + rc += obj_template->from_xml_node(content[0]); + + ObjectXML::free_nodes(content); + if (rc != 0) { return -1; diff --git a/src/cluster/ClusterPool.cc b/src/cluster/ClusterPool.cc index 61d48d2aea..b3ff69e26c 100644 --- a/src/cluster/ClusterPool.cc +++ b/src/cluster/ClusterPool.cc @@ -72,7 +72,7 @@ int ClusterPool::allocate(string name, int * oid, string& error_str) } // Build a new Cluster object - cluster = new Cluster(-1, name); + cluster = new Cluster(-1, name, 0); // Insert the Object in the pool *oid = PoolSQL::allocate(cluster, error_str); diff --git a/src/datastore/Datastore.cc b/src/datastore/Datastore.cc index 8b40ddc925..bfed67afaa 100644 --- a/src/datastore/Datastore.cc +++ b/src/datastore/Datastore.cc @@ -19,6 +19,8 @@ #include "NebulaLog.h" #include "Nebula.h" +#define TO_UPPER(S) transform(S.begin(),S.end(),S.begin(),(int(*)(int))toupper) + const char * Datastore::table = "datastore_pool"; const char * Datastore::db_names = @@ -47,7 +49,8 @@ Datastore::Datastore( Clusterable(cluster_id, cluster_name), ds_mad(""), tm_mad(""), - base_path("") + base_path(""), + system_ds(0) { group_u = 1; @@ -97,6 +100,7 @@ int Datastore::insert(SqlDB *db, string& error_str) int rc; ostringstream oss; string s_disk_type; + string s_system_ds; Nebula& nd = Nebula::instance(); @@ -108,8 +112,22 @@ int Datastore::insert(SqlDB *db, string& error_str) // NAME is checked in DatastorePool::allocate get_template_attribute("DS_MAD", ds_mad); + get_template_attribute("SYSTEM", s_system_ds); - if ( ds_mad.empty() == true ) + TO_UPPER(s_system_ds); + + system_ds = (s_system_ds == "YES"); + + if ( system_ds == 1 ) + { + if ( !ds_mad.empty() ) + { + goto error_exclusive; + } + + ds_mad = "-"; + } + else if ( ds_mad.empty() == true ) { goto error_ds; } @@ -152,6 +170,10 @@ int Datastore::insert(SqlDB *db, string& error_str) return rc; +error_exclusive: + error_str = "SYSTEM datastores cannot have DS_MAD defined."; + goto error_common; + error_ds: error_str = "No DS_MAD in template."; goto error_common; @@ -273,6 +295,7 @@ string& Datastore::to_xml(string& xml) const "" << ds_mad << "" << "" << tm_mad << "" << "" << base_path << "" << + "" << system_ds << "" << "" << disk_type << "" << "" << cluster_id << "" << "" << cluster << "" << @@ -307,6 +330,7 @@ int Datastore::from_xml(const string& xml) rc += xpath(ds_mad, "/DATASTORE/DS_MAD", "not_found"); rc += xpath(tm_mad, "/DATASTORE/TM_MAD", "not_found"); rc += xpath(base_path, "/DATASTORE/BASE_PATH", "not_found"); + rc += xpath(system_ds, "/DATASTORE/SYSTEM", -1); rc += xpath(int_disk_type,"/DATASTORE/DISK_TYPE", -1); rc += xpath(cluster_id, "/DATASTORE/CLUSTER_ID", -1); @@ -354,14 +378,15 @@ int Datastore::from_xml(const string& xml) /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -int Datastore::replace_template(const string& tmpl_str, string& error) +int Datastore::replace_template(const string& tmpl_str, string& error_str) { string new_ds_mad; string new_tm_mad; + string s_system_ds; int rc; - rc = PoolObjectSQL::replace_template(tmpl_str, error); + rc = PoolObjectSQL::replace_template(tmpl_str, error_str); if ( rc != 0 ) { @@ -369,15 +394,37 @@ int Datastore::replace_template(const string& tmpl_str, string& error) } get_template_attribute("DS_MAD", new_ds_mad); + get_template_attribute("SYSTEM", s_system_ds); + + + if ( oid == DatastorePool::SYSTEM_DS_ID ) + { + system_ds = 1; + } + else if ( !s_system_ds.empty() ) + { + TO_UPPER(s_system_ds); + + system_ds = (s_system_ds == "YES"); + } + + if ( system_ds == 1 ) + { + replace_template_attribute("SYSTEM", "YES"); + + new_ds_mad = "-"; + } + else + { + obj_template->erase("SYSTEM"); + } if ( !new_ds_mad.empty() ) { ds_mad = new_ds_mad; } - else - { - replace_template_attribute("DS_MAD", ds_mad); - } + + replace_template_attribute("DS_MAD", ds_mad); get_template_attribute("TM_MAD", new_tm_mad); diff --git a/src/datastore/DatastorePool.cc b/src/datastore/DatastorePool.cc index b38318fc04..c8639eca69 100644 --- a/src/datastore/DatastorePool.cc +++ b/src/datastore/DatastorePool.cc @@ -53,7 +53,7 @@ DatastorePool::DatastorePool(SqlDB * db): // --------------------------------------------------------------------- oss << "NAME = " << SYSTEM_DS_NAME << endl - << "DS_MAD = -" << endl + << "SYSTEM = YES" << endl << "TM_MAD = shared"; ds_tmpl = new DatastoreTemplate; diff --git a/src/oca/java/src/org/opennebula/client/cluster/Cluster.java b/src/oca/java/src/org/opennebula/client/cluster/Cluster.java index fdf1b75703..1edbe4a934 100644 --- a/src/oca/java/src/org/opennebula/client/cluster/Cluster.java +++ b/src/oca/java/src/org/opennebula/client/cluster/Cluster.java @@ -30,6 +30,7 @@ public class Cluster extends PoolElement{ private static final String ALLOCATE = METHOD_PREFIX + "allocate"; private static final String DELETE = METHOD_PREFIX + "delete"; private static final String INFO = METHOD_PREFIX + "info"; + private static final String UPDATE = METHOD_PREFIX + "update"; private static final String ADDHOST = METHOD_PREFIX + "addhost"; private static final String DELHOST = METHOD_PREFIX + "delhost"; private static final String ADDDATASTORE = METHOD_PREFIX + "adddatastore"; @@ -99,6 +100,19 @@ public class Cluster extends PoolElement{ return client.call(DELETE, id); } + /** + * Replaces the cluster contents. + * + * @param client XML-RPC Client. + * @param id The id of the target cluster we want to modify. + * @param new_template New template contents. + * @return If successful the message contains the cluster id. + */ + public static OneResponse update(Client client, int id, String new_template) + { + return client.call(UPDATE, id, new_template); + } + /** * Adds a Host to this Cluster * @@ -210,6 +224,17 @@ public class Cluster extends PoolElement{ return delete(client, id); } + /** + * Replaces the cluster template. + * + * @param new_template New cluster template. + * @return If successful the message contains the cluster id. + */ + public OneResponse update(String new_template) + { + return update(client, id, new_template); + } + /** * Adds a Host to this Cluster * diff --git a/src/oca/ruby/OpenNebula/Cluster.rb b/src/oca/ruby/OpenNebula/Cluster.rb index cdec2f5703..e6abb4c7a3 100644 --- a/src/oca/ruby/OpenNebula/Cluster.rb +++ b/src/oca/ruby/OpenNebula/Cluster.rb @@ -32,7 +32,8 @@ module OpenNebula :adddatastore => "cluster.adddatastore", :deldatastore => "cluster.deldatastore", :addvnet => "cluster.addvnet", - :delvnet => "cluster.delvnet" + :delvnet => "cluster.delvnet", + :update => "cluster.update", } # Creates a Cluster description with just its identifier @@ -156,6 +157,16 @@ module OpenNebula return rc end + # Replaces the template contents + # + # @param new_template [String] New template contents + # + # @return [nil, OpenNebula::Error] nil in case of success, Error + # otherwise + def update(new_template) + super(CLUSTER_METHODS[:update], new_template) + end + # --------------------------------------------------------------------- # Helpers to get information # --------------------------------------------------------------------- diff --git a/src/onedb/3.5.80_to_3.6.0.rb b/src/onedb/3.5.80_to_3.6.0.rb new file mode 100644 index 0000000000..cf8b892eb9 --- /dev/null +++ b/src/onedb/3.5.80_to_3.6.0.rb @@ -0,0 +1,146 @@ +# -------------------------------------------------------------------------- # +# Copyright 2002-2012, 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. # +#--------------------------------------------------------------------------- # + +require "rexml/document" +include REXML + +module Migrator + def db_version + "3.6.0" + end + + def one_version + "OpenNebula 3.6.0" + end + + def up + + @db.run "ALTER TABLE cluster_pool RENAME TO old_cluster_pool;" + @db.run "CREATE TABLE cluster_pool (oid INTEGER PRIMARY KEY, name VARCHAR(128), body TEXT, uid INTEGER, gid INTEGER, owner_u INTEGER, group_u INTEGER, other_u INTEGER, UNIQUE(name));" + + @db.fetch("SELECT * FROM old_cluster_pool") do |row| + doc = Document.new(row[:body]) + + doc.root.add_element("TEMPLATE") + + @db[:cluster_pool].insert( + :oid => row[:oid], + :name => row[:name], + :body => doc.root.to_s, + :uid => row[:uid], + :gid => row[:gid], + :owner_u => row[:owner_u], + :group_u => row[:group_u], + :other_u => row[:other_u]) + end + + @db.run "DROP TABLE old_cluster_pool;" + + + @db.run "ALTER TABLE datastore_pool RENAME TO old_datastore_pool;" + @db.run "CREATE TABLE datastore_pool (oid INTEGER PRIMARY KEY, name VARCHAR(128), body TEXT, uid INTEGER, gid INTEGER, owner_u INTEGER, group_u INTEGER, other_u INTEGER, UNIQUE(name));" + + system_tm = "" + + @db.fetch("SELECT * FROM old_datastore_pool WHERE oid = 0") do |row| + doc = Document.new(row[:body]) + + doc.root.each_element("TM_MAD") { |e| + system_tm = e.text + } + + doc.root.add_element("SYSTEM").text = "1" + + @db[:datastore_pool].insert( + :oid => row[:oid], + :name => row[:name], + :body => doc.root.to_s, + :uid => row[:uid], + :gid => row[:gid], + :owner_u => row[:owner_u], + :group_u => row[:group_u], + :other_u => row[:other_u]) + end + + @db.fetch("SELECT * FROM old_datastore_pool WHERE oid > 0") do |row| + doc = Document.new(row[:body]) + + doc.root.add_element("SYSTEM").text = "0" + + @db[:datastore_pool].insert( + :oid => row[:oid], + :name => row[:name], + :body => doc.root.to_s, + :uid => row[:uid], + :gid => row[:gid], + :owner_u => row[:owner_u], + :group_u => row[:group_u], + :other_u => row[:other_u]) + end + + @db.run "DROP TABLE old_datastore_pool;" + + + @db.run "ALTER TABLE vm_pool RENAME TO old_vm_pool;" + @db.run "CREATE TABLE vm_pool (oid INTEGER PRIMARY KEY, name VARCHAR(128), body TEXT, uid INTEGER, gid INTEGER, last_poll INTEGER, state INTEGER, lcm_state INTEGER, owner_u INTEGER, group_u INTEGER, other_u INTEGER);" + + @db.fetch("SELECT * FROM old_vm_pool") do |row| + doc = Document.new(row[:body]) + + doc.root.each_element("HISTORY_RECORDS/HISTORY") { |e| + e.add_element("TMMAD").text = system_tm + e.add_element("DS_ID").text = "0" + } + + @db[:vm_pool].insert( + :oid => row[:oid], + :name => row[:name], + :body => doc.root.to_s, + :uid => row[:uid], + :gid => row[:gid], + :last_poll => row[:last_poll], + :state => row[:state], + :lcm_state => row[:lcm_state], + :owner_u => row[:owner_u], + :group_u => row[:group_u], + :other_u => row[:other_u]) + end + + @db.run "DROP TABLE old_vm_pool;" + + + @db.run "ALTER TABLE history RENAME TO old_history;" + @db.run "CREATE TABLE history (vid INTEGER, seq INTEGER, body TEXT, stime INTEGER, etime INTEGER, PRIMARY KEY(vid,seq));" + + @db.fetch("SELECT * FROM old_history") do |row| + doc = Document.new(row[:body]) + + doc.root.add_element("TMMAD").text = system_tm + doc.root.add_element("DS_ID").text = "0" + + @db[:history].insert( + :vid => row[:vid], + :seq => row[:seq], + :body => doc.root.to_s, + :stime => row[:stime], + :etime => row[:etime]) + end + + @db.run "DROP TABLE old_history;" + + return true + end +end diff --git a/src/rm/RequestManager.cc b/src/rm/RequestManager.cc index a349134855..4c2135785b 100644 --- a/src/rm/RequestManager.cc +++ b/src/rm/RequestManager.cc @@ -268,6 +268,7 @@ void RequestManager::register_xml_methods() xmlrpc_c::methodPtr user_update(new UserUpdateTemplate()); xmlrpc_c::methodPtr datastore_update(new DatastoreUpdateTemplate()); xmlrpc_c::methodPtr doc_update(new DocumentUpdateTemplate()); + xmlrpc_c::methodPtr cluster_update(new ClusterUpdateTemplate()); // Allocate Methods xmlrpc_c::methodPtr vm_allocate(new VirtualMachineAllocate()); @@ -468,6 +469,7 @@ void RequestManager::register_xml_methods() RequestManagerRegistry.addMethod("one.cluster.allocate",cluster_allocate); RequestManagerRegistry.addMethod("one.cluster.delete", cluster_delete); RequestManagerRegistry.addMethod("one.cluster.info", cluster_info); + RequestManagerRegistry.addMethod("one.cluster.update", cluster_update); RequestManagerRegistry.addMethod("one.cluster.addhost", cluster_addhost); RequestManagerRegistry.addMethod("one.cluster.delhost", cluster_delhost); diff --git a/src/rm/RequestManagerAllocate.cc b/src/rm/RequestManagerAllocate.cc index 3f05704c5f..2da96e857b 100644 --- a/src/rm/RequestManagerAllocate.cc +++ b/src/rm/RequestManagerAllocate.cc @@ -322,17 +322,6 @@ void ImageAllocate::request_execute(xmlrpc_c::paramList const& params, // ------------------------- Check Datastore exists ------------------------ - if ( ds_id == DatastorePool::SYSTEM_DS_ID ) - { - ostringstream oss; - - oss << "New images cannot be allocated in the system datastore."; - failure_response(INTERNAL, allocate_error(oss.str()), att); - - delete tmpl; - return; - } - if ((ds = dspool->get(ds_id,true)) == 0 ) { failure_response(NO_EXISTS, @@ -343,6 +332,20 @@ void ImageAllocate::request_execute(xmlrpc_c::paramList const& params, return; } + if ( ds->is_system() ) + { + ostringstream oss; + + ds->unlock(); + + oss << "New images cannot be allocated in a system datastore."; + failure_response(INTERNAL, allocate_error(oss.str()), att); + + delete tmpl; + + return; + } + ds->get_permissions(ds_perms); ds_name = ds->get_name(); diff --git a/src/rm/RequestManagerVirtualMachine.cc b/src/rm/RequestManagerVirtualMachine.cc index d4d7e7cd39..eea341cfc6 100644 --- a/src/rm/RequestManagerVirtualMachine.cc +++ b/src/rm/RequestManagerVirtualMachine.cc @@ -99,13 +99,19 @@ int RequestManagerVirtualMachine::get_host_information(int hid, string& name, string& vmm, string& vnm, + string& tm, + int& ds_id, RequestAttributes& att, PoolObjectAuth& host_perms) { Nebula& nd = Nebula::instance(); HostPool * hpool = nd.get_hpool(); - Host * host; + Host * host; + Cluster * cluster; + Datastore * ds; + + int cluster_id; host = hpool->get(hid,true); @@ -124,8 +130,65 @@ int RequestManagerVirtualMachine::get_host_information(int hid, host->get_permissions(host_perms); + cluster_id = host->get_cluster_id(); + host->unlock(); + if ( cluster_id != -1 ) + { + cluster = nd.get_clpool()->get(cluster_id, true); + + if ( cluster == 0 ) + { + failure_response(NO_EXISTS, + get_error(object_name(PoolObjectSQL::CLUSTER),cluster_id), + att); + + return -1; + } + + ds_id = cluster->get_ds_id(); + + cluster->unlock(); + } + else + { + ds_id = DatastorePool::SYSTEM_DS_ID; + } + + ds = nd.get_dspool()->get(ds_id, true); + + if ( ds == 0 ) + { + failure_response(NO_EXISTS, + get_error(object_name(PoolObjectSQL::DATASTORE),ds_id), + att); + + return -1; + } + + if ( ds->is_system() == false ) + { + ostringstream oss; + + ds->unlock(); + + oss << object_name(PoolObjectSQL::CLUSTER) + << " [" << cluster_id << "] has its SYSTEM_DS set to " + << object_name(PoolObjectSQL::DATASTORE) + << " [" << ds_id << "], but it is not a system one."; + + failure_response(INTERNAL, + request_error(oss.str(),""), + att); + + return -1; + } + + tm = ds->get_tm_mad(); + + ds->unlock(); + return 0; } @@ -156,6 +219,8 @@ int RequestManagerVirtualMachine::add_history(VirtualMachine * vm, const string& hostname, const string& vmm_mad, const string& vnm_mad, + const string& tm_mad, + int ds_id, RequestAttributes& att) { string vmdir; @@ -163,7 +228,7 @@ int RequestManagerVirtualMachine::add_history(VirtualMachine * vm, VirtualMachinePool * vmpool = static_cast(pool); - vm->add_history(hid,hostname,vmm_mad,vnm_mad); + vm->add_history(hid,hostname,vmm_mad,vnm_mad,tm_mad,ds_id); rc = vmpool->update_history(vm); @@ -308,13 +373,16 @@ void VirtualMachineDeploy::request_execute(xmlrpc_c::paramList const& paramList, string hostname; string vmm_mad; string vnm_mad; + string tm_mad; + int ds_id; int id = xmlrpc_c::value_int(paramList.getInt(1)); int hid = xmlrpc_c::value_int(paramList.getInt(2)); bool auth = false; - if (get_host_information(hid,hostname,vmm_mad,vnm_mad,att, host_perms) != 0) + if (get_host_information( + hid,hostname,vmm_mad,vnm_mad,tm_mad, ds_id, att, host_perms) != 0) { return; } @@ -341,7 +409,7 @@ void VirtualMachineDeploy::request_execute(xmlrpc_c::paramList const& paramList, return; } - if ( add_history(vm,hid,hostname,vmm_mad,vnm_mad,att) != 0) + if ( add_history(vm,hid,hostname,vmm_mad,vnm_mad,tm_mad,ds_id,att) != 0) { vm->unlock(); return; @@ -369,6 +437,8 @@ void VirtualMachineMigrate::request_execute(xmlrpc_c::paramList const& paramList string hostname; string vmm_mad; string vnm_mad; + string tm_mad; + int ds_id; int id = xmlrpc_c::value_int(paramList.getInt(1)); int hid = xmlrpc_c::value_int(paramList.getInt(2)); @@ -376,7 +446,8 @@ void VirtualMachineMigrate::request_execute(xmlrpc_c::paramList const& paramList bool auth = false; - if (get_host_information(hid,hostname,vmm_mad,vnm_mad,att, host_perms) != 0) + if (get_host_information( + hid,hostname,vmm_mad,vnm_mad,tm_mad,ds_id, att, host_perms) != 0) { return; } @@ -405,7 +476,7 @@ void VirtualMachineMigrate::request_execute(xmlrpc_c::paramList const& paramList return; } - if ( add_history(vm,hid,hostname,vmm_mad,vnm_mad,att) != 0) + if ( add_history(vm,hid,hostname,vmm_mad,vnm_mad,tm_mad,ds_id,att) != 0) { vm->unlock(); return; diff --git a/src/tm/TransferManager.cc b/src/tm/TransferManager.cc index 1862dbaf3b..d31f81cd2e 100644 --- a/src/tm/TransferManager.cc +++ b/src/tm/TransferManager.cc @@ -212,7 +212,7 @@ void TransferManager::do_action(const string &action, void * arg) int TransferManager::prolog_transfer_command( VirtualMachine * vm, const VectorAttribute * disk, - string& system_tm_mad, + string& vm_tm_mad, string& opennebula_hostname, ostream& xfr, ostringstream& os) @@ -248,7 +248,7 @@ int TransferManager::prolog_transfer_command( //MKSWAP tm_mad size host:remote_system_dir/disk.i vmid dsid(=0) xfr << "MKSWAP " - << system_tm_mad << " " + << vm_tm_mad << " " << size << " " << vm->get_hostname() << ":" << vm->get_remote_system_dir() << "/disk." << disk_index << " " @@ -273,7 +273,7 @@ int TransferManager::prolog_transfer_command( //MKIMAGE tm_mad size format host:remote_system_dir/disk.i vmid dsid(=0) xfr << "MKIMAGE " - << system_tm_mad << " " + << vm_tm_mad << " " << size << " " << format << " " << vm->get_hostname() << ":" @@ -356,7 +356,7 @@ void TransferManager::prolog_action(int vid) const VectorAttribute * disk; string files; - string system_tm_mad; + string vm_tm_mad; string opennebula_hostname; int rc; string error_str; @@ -374,17 +374,6 @@ void TransferManager::prolog_action(int vid) // ------------------------------------------------------------------------- // Setup & Transfer script // ------------------------------------------------------------------------- - system_tm_mad = nd.get_system_ds_tm_mad(); - tm_md = get(); - - if ( tm_md == 0 || system_tm_mad.empty() ) - { - NebulaLog::log("TM", Log::ERROR, "prolog, error getting drivers."); - (nd.get_lcm())->trigger(LifeCycleManager::PROLOG_FAILURE,vid); - - return; - } - vm = vmpool->get(vid,true); if (vm == 0) @@ -397,6 +386,14 @@ void TransferManager::prolog_action(int vid) goto error_history; } + vm_tm_mad = vm->get_tm_mad(); + tm_md = get(); + + if ( tm_md == 0 || vm_tm_mad.empty() ) + { + goto error_drivers; + } + xfr_name = vm->get_transfer_file() + ".prolog"; xfr.open(xfr_name.c_str(), ios::out | ios::trunc); @@ -423,7 +420,7 @@ void TransferManager::prolog_action(int vid) rc = prolog_transfer_command(vm, disk, - system_tm_mad, + vm_tm_mad, opennebula_hostname, xfr, os); @@ -447,7 +444,7 @@ void TransferManager::prolog_action(int vid) { //CONTEXT tm_mad files hostname:remote_system_dir/disk.i vmid dsid(=0) xfr << "CONTEXT " - << system_tm_mad << " " + << vm_tm_mad << " " << vm->get_context_file() << " "; if (!files.empty()) @@ -472,6 +469,11 @@ error_history: os << "VM " << vid << " has no history"; goto error_common; +error_drivers: + os.str(""); + os << "prolog, error getting drivers."; + goto error_common; + error_file: os << "could not open file: " << xfr_name; goto error_common; @@ -497,6 +499,19 @@ error_common: /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ +static bool isVolatile(const VectorAttribute * disk) +{ + string type; + + type = disk->vector_value("TYPE"); + transform(type.begin(),type.end(),type.begin(),(int(*)(int))toupper); + + return ( type == "SWAP" || type == "FS"); +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + void TransferManager::prolog_migr_action(int vid) { ofstream xfr; @@ -505,7 +520,8 @@ void TransferManager::prolog_migr_action(int vid) const VectorAttribute * disk; string tm_mad; - string system_tm_mad; + string vm_tm_mad; + string vm_ds_id; string ds_id; int disk_id; @@ -520,17 +536,6 @@ void TransferManager::prolog_migr_action(int vid) // ------------------------------------------------------------------------- // Setup & Transfer script // ------------------------------------------------------------------------- - system_tm_mad = nd.get_system_ds_tm_mad(); - tm_md = get(); - - if ( tm_md == 0 || system_tm_mad.empty() ) - { - NebulaLog::log("TM", Log::ERROR, "prolog_migr, error getting drivers."); - (nd.get_lcm())->trigger(LifeCycleManager::PROLOG_FAILURE,vid); - - return; - } - vm = vmpool->get(vid,true); if (vm == 0) @@ -538,11 +543,20 @@ void TransferManager::prolog_migr_action(int vid) return; } - if (!vm->hasHistory()) + if (!vm->hasHistory() || !vm->hasPreviousHistory()) { goto error_history; } + vm_tm_mad = vm->get_tm_mad(); + vm_ds_id = vm->get_ds_id(); + tm_md = get(); + + if ( tm_md == 0 || vm_tm_mad.empty() || vm_ds_id.empty()) + { + goto error_drivers; + } + xfr_name = vm->get_transfer_file() + ".migrate"; xfr.open(xfr_name.c_str(), ios::out | ios::trunc); @@ -566,13 +580,22 @@ void TransferManager::prolog_migr_action(int vid) continue; } - tm_mad = disk->vector_value("TM_MAD"); - ds_id = disk->vector_value("DATASTORE_ID"); disk->vector_value_str("DISK_ID", disk_id); - if ( tm_mad.empty() || ds_id.empty() ) + if ( isVolatile(disk) == true ) { - continue; + tm_mad = vm_tm_mad; + ds_id = vm_ds_id; + } + else + { + tm_mad = disk->vector_value("TM_MAD"); + ds_id = disk->vector_value("DATASTORE_ID"); + + if ( tm_mad.empty() || ds_id.empty() ) + { + continue; + } } //MV tm_mad prev_host:remote_system_dir/disk.i host:remote_system_dir/disk.i vmid dsid @@ -588,13 +611,13 @@ void TransferManager::prolog_migr_action(int vid) //MV tm_mad prev_host:remote_system_dir host:remote_system_dir VMID 0 xfr << "MV " - << system_tm_mad << " " + << vm_tm_mad << " " << vm->get_previous_hostname() << ":" << vm->get_remote_system_dir() << " " << vm->get_hostname() << ":" << vm->get_remote_system_dir() << " " << vm->get_oid() << " " - << "0" << endl; + << vm_ds_id << endl; xfr.close(); @@ -608,6 +631,11 @@ error_history: os << "prolog_migr, VM " << vid << " has no history"; goto error_common; +error_drivers: + os.str(""); + os << "prolog_migr, error getting drivers."; + goto error_common; + error_file: os.str(""); os << "prolog_migr, could not open file: " << xfr_name; @@ -632,7 +660,8 @@ void TransferManager::prolog_resume_action(int vid) const VectorAttribute * disk; string tm_mad; - string system_tm_mad; + string vm_tm_mad; + string vm_ds_id; string ds_id; int disk_id; @@ -647,17 +676,6 @@ void TransferManager::prolog_resume_action(int vid) // ------------------------------------------------------------------------- // Setup & Transfer script // ------------------------------------------------------------------------- - system_tm_mad = nd.get_system_ds_tm_mad(); - tm_md = get(); - - if ( tm_md == 0 || system_tm_mad.empty() ) - { - NebulaLog::log("TM", Log::ERROR, "prolog_resume, error getting drivers."); - (nd.get_lcm())->trigger(LifeCycleManager::PROLOG_FAILURE,vid); - - return; - } - vm = vmpool->get(vid,true); if (vm == 0) @@ -670,6 +688,15 @@ void TransferManager::prolog_resume_action(int vid) goto error_history; } + vm_tm_mad = vm->get_tm_mad(); + vm_ds_id = vm->get_ds_id(); + tm_md = get(); + + if ( tm_md == 0 || vm_tm_mad.empty() || vm_ds_id.empty()) + { + goto error_drivers; + } + xfr_name = vm->get_transfer_file() + ".resume"; xfr.open(xfr_name.c_str(), ios::out | ios::trunc); @@ -692,13 +719,22 @@ void TransferManager::prolog_resume_action(int vid) continue; } - tm_mad = disk->vector_value("TM_MAD"); - ds_id = disk->vector_value("DATASTORE_ID"); disk->vector_value_str("DISK_ID", disk_id); - if ( tm_mad.empty() || ds_id.empty() ) + if ( isVolatile(disk) == true ) { - continue; + tm_mad = vm_tm_mad; + ds_id = vm_ds_id; + } + else + { + tm_mad = disk->vector_value("TM_MAD"); + ds_id = disk->vector_value("DATASTORE_ID"); + + if ( tm_mad.empty() || ds_id.empty() ) + { + continue; + } } //MV tm_mad fe:system_dir/disk.i host:remote_system_dir/disk.i vmid dsid @@ -714,11 +750,11 @@ void TransferManager::prolog_resume_action(int vid) //MV tm_mad fe:system_dir host:remote_system_dir vmid 0 xfr << "MV " - << system_tm_mad << " " + << vm_tm_mad << " " << nd.get_nebula_hostname() << ":"<< vm->get_system_dir() << " " << vm->get_hostname() << ":" << vm->get_remote_system_dir()<< " " << vm->get_oid() << " " - << "0" << endl; + << vm_ds_id << endl; xfr.close(); @@ -732,6 +768,11 @@ error_history: os << "prolog_resume, VM " << vid << " has no history"; goto error_common; +error_drivers: + os.str(""); + os << "prolog_resume, error getting drivers."; + goto error_common; + error_file: os.str(""); os << "prolog_resume, could not open file: " << xfr_name; @@ -758,13 +799,22 @@ void TransferManager::epilog_transfer_command( string ds_id; int disk_index; - save = disk->vector_value("SAVE"); - ds_id = disk->vector_value("DATASTORE_ID"); - tm_mad = disk->vector_value("TM_MAD"); - - if ( save.empty() || ds_id.empty() || tm_mad.empty() ) + if ( isVolatile(disk) == true ) { - return; + save = "NO"; + tm_mad = vm->get_tm_mad(); + ds_id = vm->get_ds_id(); + } + else + { + save = disk->vector_value("SAVE"); + tm_mad = disk->vector_value("TM_MAD"); + ds_id = disk->vector_value("DATASTORE_ID"); + + if ( save.empty() || ds_id.empty() || tm_mad.empty() ) + { + return; + } } disk->vector_value("DISK_ID", disk_index); @@ -820,9 +870,10 @@ void TransferManager::epilog_action(int vid) { ofstream xfr; ostringstream os; - string xfr_name; - string system_tm_mad; - string error_str; + string xfr_name; + string vm_tm_mad; + string vm_ds_id; + string error_str; const VectorAttribute * disk; @@ -837,17 +888,6 @@ void TransferManager::epilog_action(int vid) // ------------------------------------------------------------------------ // Setup & Transfer script // ------------------------------------------------------------------------ - system_tm_mad = nd.get_system_ds_tm_mad(); - tm_md = get(); - - if ( tm_md == 0 || system_tm_mad.empty() ) - { - NebulaLog::log("TM", Log::ERROR, "epilog, error getting drivers."); - (nd.get_lcm())->trigger(LifeCycleManager::EPILOG_FAILURE,vid); - - return; - } - vm = vmpool->get(vid,true); if (vm == 0) @@ -860,6 +900,15 @@ void TransferManager::epilog_action(int vid) goto error_history; } + vm_tm_mad = vm->get_tm_mad(); + vm_ds_id = vm->get_ds_id(); + tm_md = get(); + + if ( tm_md == 0 || vm_tm_mad.empty() || vm_ds_id.empty()) + { + goto error_drivers; + } + xfr_name = vm->get_transfer_file() + ".epilog"; xfr.open(xfr_name.c_str(), ios::out | ios::trunc); @@ -885,12 +934,12 @@ void TransferManager::epilog_action(int vid) epilog_transfer_command(vm, disk, xfr); } - //DELETE system_tm_mad hostname:remote_system_dir vmid ds_id + //DELETE vm_tm_mad hostname:remote_system_dir vmid ds_id xfr << "DELETE " - << system_tm_mad << " " + << vm_tm_mad << " " << vm->get_hostname() << ":" << vm->get_remote_system_dir() << " " << vm->get_oid() << " " - << "0" << endl; + << vm_ds_id << endl; xfr.close(); @@ -904,6 +953,11 @@ error_history: os << "epilog, VM " << vid << " has no history"; goto error_common; +error_drivers: + os.str(""); + os << "epilog, error getting drivers."; + goto error_common; + error_file: os.str(""); os << "epilog, could not open file: " << xfr_name; @@ -924,11 +978,14 @@ void TransferManager::epilog_stop_action(int vid) { ofstream xfr; ostringstream os; - string xfr_name; - string tm_mad; - string system_tm_mad; - string ds_id; - int disk_id; + + string xfr_name; + string tm_mad; + string vm_tm_mad; + string vm_ds_id; + string ds_id; + + int disk_id; VirtualMachine * vm; Nebula& nd = Nebula::instance(); @@ -942,17 +999,6 @@ void TransferManager::epilog_stop_action(int vid) // ------------------------------------------------------------------------ // Setup & Transfer script // ------------------------------------------------------------------------ - system_tm_mad = nd.get_system_ds_tm_mad(); - tm_md = get(); - - if ( tm_md == 0 || system_tm_mad.empty() ) - { - NebulaLog::log("TM", Log::ERROR, "epilog_stop, error getting drivers."); - (nd.get_lcm())->trigger(LifeCycleManager::EPILOG_FAILURE,vid); - - return; - } - vm = vmpool->get(vid,true); if (vm == 0) @@ -965,6 +1011,15 @@ void TransferManager::epilog_stop_action(int vid) goto error_history; } + vm_tm_mad = vm->get_tm_mad(); + vm_ds_id = vm->get_ds_id(); + tm_md = get(); + + if ( tm_md == 0 || vm_tm_mad.empty() || vm_ds_id.empty()) + { + goto error_drivers; + } + xfr_name = vm->get_transfer_file() + ".stop"; xfr.open(xfr_name.c_str(), ios::out | ios::trunc); @@ -987,13 +1042,22 @@ void TransferManager::epilog_stop_action(int vid) continue; } - tm_mad = disk->vector_value("TM_MAD"); - ds_id = disk->vector_value("DATASTORE_ID"); disk->vector_value_str("DISK_ID", disk_id); - if (tm_mad.empty() || ds_id.empty()) + if ( isVolatile(disk) == true ) { - continue; + tm_mad = vm_tm_mad; + ds_id = vm_ds_id; + } + else + { + tm_mad = disk->vector_value("TM_MAD"); + ds_id = disk->vector_value("DATASTORE_ID"); + + if ( tm_mad.empty() || ds_id.empty() ) + { + continue; + } } //MV tm_mad host:remote_system_dir/disk.i fe:system_dir/disk.i vmid dsid @@ -1007,13 +1071,13 @@ void TransferManager::epilog_stop_action(int vid) << ds_id << endl; } - //MV system_tm_mad hostname:remote_system_dir fe:system_dir + //MV vm_tm_mad hostname:remote_system_dir fe:system_dir xfr << "MV " - << system_tm_mad << " " + << vm_tm_mad << " " << vm->get_hostname() << ":" << vm->get_remote_system_dir() << " " << nd.get_nebula_hostname() << ":" << vm->get_system_dir() << " " << vm->get_oid() << " " - << "0" << endl; + << vm_ds_id << endl; xfr.close(); @@ -1028,6 +1092,11 @@ error_history: os << "epilog_stop, VM " << vid << " has no history"; goto error_common; +error_drivers: + os.str(""); + os << "epilog_stop, error getting drivers."; + goto error_common; + error_file: os.str(""); os << "epilog_stop, could not open file: " << xfr_name; @@ -1048,11 +1117,14 @@ void TransferManager::epilog_delete_action(bool local, int vid) { ofstream xfr; ostringstream os; - string xfr_name; - string system_tm_mad; - string tm_mad; - string ds_id; - int disk_id; + + string xfr_name; + string vm_tm_mad; + string tm_mad; + string vm_ds_id; + string ds_id; + + int disk_id; VirtualMachine * vm; Nebula& nd = Nebula::instance(); @@ -1066,17 +1138,6 @@ void TransferManager::epilog_delete_action(bool local, int vid) // ------------------------------------------------------------------------ // Setup & Transfer script // ------------------------------------------------------------------------ - system_tm_mad = nd.get_system_ds_tm_mad(); - tm_md = get(); - - if ( tm_md == 0 || system_tm_mad.empty() ) - { - NebulaLog::log("TM", Log::ERROR, "epilog_delete, error getting drivers."); - (nd.get_lcm())->trigger(LifeCycleManager::EPILOG_FAILURE,vid); - - return; - } - vm = vmpool->get(vid,true); if (vm == 0) @@ -1088,7 +1149,16 @@ void TransferManager::epilog_delete_action(bool local, int vid) { goto error_history; } - + + vm_tm_mad = vm->get_tm_mad(); + vm_ds_id = vm->get_ds_id(); + tm_md = get(); + + if ( tm_md == 0 || vm_tm_mad.empty() || vm_ds_id.empty()) + { + goto error_drivers; + } + xfr_name = vm->get_transfer_file() + ".delete"; xfr.open(xfr_name.c_str(), ios::out | ios::trunc); @@ -1111,13 +1181,22 @@ void TransferManager::epilog_delete_action(bool local, int vid) continue; } - tm_mad = disk->vector_value("TM_MAD"); - ds_id = disk->vector_value("DATASTORE_ID"); disk->vector_value_str("DISK_ID", disk_id); - if ( tm_mad.empty() || ds_id.empty() ) + if ( isVolatile(disk) == true ) { - continue; + tm_mad = vm_tm_mad; + ds_id = vm_ds_id; + } + else + { + tm_mad = disk->vector_value("TM_MAD"); + ds_id = disk->vector_value("DATASTORE_ID"); + + if ( tm_mad.empty() || ds_id.empty() ) + { + continue; + } } if ( local ) @@ -1144,21 +1223,21 @@ void TransferManager::epilog_delete_action(bool local, int vid) if ( local ) { - //DELETE system_tm_mad fe:system_dir vmid dsid(=0) + //DELETE vm_tm_mad fe:system_dir vmid dsid(=0) xfr << "DELETE " - << system_tm_mad << " " + << vm_tm_mad << " " << nd.get_nebula_hostname() <<":"<< vm->get_system_dir() << " " << vm->get_oid() << " " - << "0"; + << vm_ds_id; } else { - //DELETE system_tm_mad hostname:remote_system_dir vmid dsid(=0) + //DELETE vm_tm_mad hostname:remote_system_dir vmid dsid(=0) xfr << "DELETE " - << system_tm_mad << " " + << vm_tm_mad << " " << vm->get_hostname() <<":"<< vm->get_remote_system_dir() << " " << vm->get_oid() << " " - << "0"; + << vm_ds_id; } xfr.close(); @@ -1173,6 +1252,11 @@ error_history: os << "epilog_delete, VM " << vid << " has no history"; goto error_common; +error_drivers: + os.str(""); + os << "epilog_delete, error getting drivers."; + goto error_common; + error_file: os.str(""); os << "epilog_delete, could not open file: " << xfr_name; @@ -1195,11 +1279,14 @@ void TransferManager::epilog_delete_previous_action(int vid) { ofstream xfr; ostringstream os; - string xfr_name; - string system_tm_mad; - string tm_mad; - string ds_id; - int disk_id; + + string xfr_name; + string vm_tm_mad; + string tm_mad; + string vm_ds_id; + string ds_id; + + int disk_id; VirtualMachine * vm; Nebula& nd = Nebula::instance(); @@ -1213,17 +1300,6 @@ void TransferManager::epilog_delete_previous_action(int vid) // ------------------------------------------------------------------------ // Setup & Transfer script // ------------------------------------------------------------------------ - system_tm_mad = nd.get_system_ds_tm_mad(); - tm_md = get(); - - if ( tm_md == 0 || system_tm_mad.empty() ) - { - NebulaLog::log("TM", Log::ERROR, "epilog_delete, error getting drivers."); - (nd.get_lcm())->trigger(LifeCycleManager::EPILOG_FAILURE,vid); - - return; - } - vm = vmpool->get(vid,true); if (vm == 0) @@ -1236,6 +1312,15 @@ void TransferManager::epilog_delete_previous_action(int vid) goto error_history; } + vm_tm_mad = vm->get_previous_tm_mad(); + vm_ds_id = vm->get_previous_ds_id(); + tm_md = get(); + + if ( tm_md == 0 || vm_tm_mad.empty() || vm_ds_id.empty() ) + { + goto error_drivers; + } + xfr_name = vm->get_transfer_file() + ".delete_prev"; xfr.open(xfr_name.c_str(),ios::out | ios::trunc); @@ -1258,13 +1343,22 @@ void TransferManager::epilog_delete_previous_action(int vid) continue; } - tm_mad = disk->vector_value("TM_MAD"); - ds_id = disk->vector_value("DATASTORE_ID"); disk->vector_value_str("DISK_ID", disk_id); - if (tm_mad.empty() || ds_id.empty()) + if ( isVolatile(disk) == true ) { - continue; + tm_mad = vm_tm_mad; + ds_id = vm_ds_id; + } + else + { + tm_mad = disk->vector_value("TM_MAD"); + ds_id = disk->vector_value("DATASTORE_ID"); + + if ( tm_mad.empty() || ds_id.empty() ) + { + continue; + } } //DELETE tm_mad prev_host:remote_system_dir/disk.i vmid ds_id @@ -1276,12 +1370,12 @@ void TransferManager::epilog_delete_previous_action(int vid) << ds_id << endl; } - //DELTE system_tm_mad prev_host:remote_system_dir vmid ds_id(=0) + //DELTE vm_tm_mad prev_host:remote_system_dir vmid ds_id(=0) xfr << "DELETE " - << system_tm_mad << " " + << vm_tm_mad << " " << vm->get_previous_hostname() <<":"<< vm->get_remote_system_dir() << " " << vm->get_oid() << " " - << "0" << endl; + << vm_ds_id << endl; xfr.close(); @@ -1295,9 +1389,14 @@ error_history: os << "epilog_delete_previous, VM " << vid << " has no history"; goto error_common; +error_drivers: + os.str(""); + os << "epilog_delete_previous, error getting drivers."; + goto error_common; + error_file: os.str(""); - os << "epilog_delete, could not open file: " << xfr_name; + os << "epilog_delete_previous, could not open file: " << xfr_name; os << ". You may need to manually clean " << vm->get_previous_hostname() << ":" << vm->get_remote_system_dir(); goto error_common; diff --git a/src/vm/History.cc b/src/vm/History.cc index 4d7580aba9..cbbe4ba072 100644 --- a/src/vm/History.cc +++ b/src/vm/History.cc @@ -44,6 +44,8 @@ History::History( hid(-1), vmm_mad_name(""), vnm_mad_name(""), + tm_mad_name(""), + ds_id(0), stime(0), etime(0), prolog_stime(0), @@ -64,6 +66,8 @@ History::History( const string& _hostname, const string& _vmm, const string& _vnm, + const string& _tmm, + int _ds_id, const string& _vm_info): oid(_oid), seq(_seq), @@ -71,6 +75,8 @@ History::History( hid(_hid), vmm_mad_name(_vmm), vnm_mad_name(_vnm), + tm_mad_name(_tmm), + ds_id(_ds_id), stime(0), etime(0), prolog_stime(0), @@ -123,7 +129,7 @@ void History::non_persistent_data() os.str(""); nd.get_configuration_attribute("DATASTORE_LOCATION", ds_location); - os << ds_location << "/" << DatastorePool::SYSTEM_DS_ID << "/" << oid; + os << ds_location << "/" << ds_id << "/" << oid; vm_rhome = os.str(); @@ -292,6 +298,8 @@ string& History::to_xml(string& xml, bool database) const "" << etime << "" << "" << vmm_mad_name << ""<< "" << vnm_mad_name << ""<< + "" << tm_mad_name << "" << + "" << ds_id << "" << "" << prolog_stime << ""<< "" << prolog_etime << ""<< "" << running_stime << ""<< @@ -328,6 +336,8 @@ int History::rebuild_attributes() rc += xpath(etime , "/HISTORY/ETIME", 0); rc += xpath(vmm_mad_name , "/HISTORY/VMMMAD", "not_found"); xpath(vnm_mad_name , "/HISTORY/VNMMAD", "dummy"); + rc += xpath(tm_mad_name , "/HISTORY/TMMAD", "not_found"); + rc += xpath(ds_id , "/HISTORY/DS_ID", 0); rc += xpath(prolog_stime , "/HISTORY/PSTIME", 0); rc += xpath(prolog_etime , "/HISTORY/PETIME", 0); rc += xpath(running_stime , "/HISTORY/RSTIME", 0); diff --git a/src/vm/VirtualMachine.cc b/src/vm/VirtualMachine.cc index 54fa086a92..2080ca731b 100644 --- a/src/vm/VirtualMachine.cc +++ b/src/vm/VirtualMachine.cc @@ -826,7 +826,9 @@ void VirtualMachine::add_history( int hid, const string& hostname, const string& vmm_mad, - const string& vnm_mad) + const string& vnm_mad, + const string& tm_mad, + int ds_id) { ostringstream os; int seq; @@ -851,6 +853,8 @@ void VirtualMachine::add_history( hostname, vmm_mad, vnm_mad, + tm_mad, + ds_id, vm_xml); history_records.push_back(history); @@ -877,6 +881,8 @@ void VirtualMachine::cp_history() history->hostname, history->vmm_mad_name, history->vnm_mad_name, + history->tm_mad_name, + history->ds_id, vm_xml); previous_history = history; @@ -906,6 +912,8 @@ void VirtualMachine::cp_previous_history() previous_history->hostname, previous_history->vmm_mad_name, previous_history->vnm_mad_name, + previous_history->tm_mad_name, + previous_history->ds_id, vm_xml); previous_history = history; @@ -1980,7 +1988,7 @@ string VirtualMachine::get_remote_system_dir() const Nebula& nd = Nebula::instance(); nd.get_configuration_attribute("DATASTORE_LOCATION", ds_location); - oss << ds_location << "/" << DatastorePool::SYSTEM_DS_ID << "/" << oid; + oss << ds_location << "/" << history->ds_id << "/" << oid; return oss.str(); } @@ -1993,7 +2001,7 @@ string VirtualMachine::get_system_dir() const ostringstream oss; Nebula& nd = Nebula::instance(); - oss << nd.get_ds_location() << DatastorePool::SYSTEM_DS_ID << "/"<< oid; + oss << nd.get_ds_location() << history->ds_id << "/"<< oid; return oss.str(); }; diff --git a/src/vmm/VirtualMachineManager.cc b/src/vmm/VirtualMachineManager.cc index ecd651acc1..1565dabfd0 100644 --- a/src/vmm/VirtualMachineManager.cc +++ b/src/vmm/VirtualMachineManager.cc @@ -1313,7 +1313,7 @@ void VirtualMachineManager::attach_action( string vm_tmpl; string* drv_msg; string tm_command; - string system_tm_mad; + string vm_tm_mad; string opennebula_hostname; string prolog_cmd; string disk_path; @@ -1352,13 +1352,13 @@ void VirtualMachineManager::attach_action( goto error_disk; } - system_tm_mad = nd.get_system_ds_tm_mad(); + vm_tm_mad = vm->get_tm_mad(); opennebula_hostname = nd.get_nebula_hostname(); rc = Nebula::instance().get_tm()->prolog_transfer_command( vm, disk, - system_tm_mad, + vm_tm_mad, opennebula_hostname, os, error_os); @@ -1445,7 +1445,7 @@ void VirtualMachineManager::detach_action( string vm_tmpl; string * drv_msg; string tm_command; - string system_tm_mad; + string vm_tm_mad; string opennebula_hostname; string epilog_cmd; string disk_path; @@ -1484,7 +1484,7 @@ void VirtualMachineManager::detach_action( goto error_disk; } - system_tm_mad = nd.get_system_ds_tm_mad(); + vm_tm_mad = vm->get_tm_mad(); opennebula_hostname = nd.get_nebula_hostname(); disk->vector_value("DISK_ID", disk_id);