diff --git a/include/Cluster.h b/include/Cluster.h index 822c2a28d0..52b4d46fd2 100644 --- a/include/Cluster.h +++ b/include/Cluster.h @@ -143,6 +143,30 @@ public: return rc; } + /** + * Returns a copy of the host IDs set + */ + set get_host_ids() + { + return hosts.get_collection_copy(); + } + + /** + * Returns a copy of the datastore IDs set + */ + set get_datastore_ids() + { + return datastores.get_collection_copy(); + } + + /** + * Returns a copy of the vnet IDs set + */ + set get_vnet_ids() + { + return vnets.get_collection_copy(); + } + // ************************************************************************* // DataBase implementation (Public) // ************************************************************************* diff --git a/include/Datastore.h b/include/Datastore.h index 2e7816f8e1..181dbdeba1 100644 --- a/include/Datastore.h +++ b/include/Datastore.h @@ -97,6 +97,14 @@ public: return del_collection_id(id); }; + /** + * Returns a copy of the Image IDs set + */ + set get_image_ids() + { + return get_collection_copy(); + } + /** * Retrieves TM mad name * @return string tm mad name diff --git a/include/Host.h b/include/Host.h index 801f32cc3c..aad9cef2e4 100644 --- a/include/Host.h +++ b/include/Host.h @@ -390,6 +390,14 @@ public: return host_share.test(cpu, mem, disk); } + /** + * Returns a copy of the VM IDs set + */ + set get_vm_ids() + { + return vm_collection.get_collection_copy(); + } + /** * Factory method for host templates */ diff --git a/include/Image.h b/include/Image.h index 500e26eb76..285bd18758 100644 --- a/include/Image.h +++ b/include/Image.h @@ -479,13 +479,21 @@ public: }; /** - * Returns the Datastore ID + * Returns the Datastore name */ const string& get_ds_name() const { return ds_name; }; + /** + * Updates the Datastore name + */ + void set_ds_name(const string& name) + { + ds_name = name; + }; + /** * Clones this image template including image specific attributes: NAME, * TYPE, PATH, FSTYPE, SIZE and PERSISTENT diff --git a/include/RequestManagerRename.h b/include/RequestManagerRename.h index 0034e5b62a..ecd470b053 100644 --- a/include/RequestManagerRename.h +++ b/include/RequestManagerRename.h @@ -45,6 +45,8 @@ protected: RequestAttributes& att); virtual PoolObjectSQL * get(const string& name, int uid, bool lock) = 0; + + virtual void post_execute(int oid){}; }; /* ------------------------------------------------------------------------- */ @@ -159,6 +161,78 @@ public: }; }; +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + +class ClusterRename: public RequestManagerRename +{ +public: + ClusterRename(): + RequestManagerRename("ClusterRename", "Renames a cluster") + { + Nebula& nd = Nebula::instance(); + pool = nd.get_clpool(); + auth_object = PoolObjectSQL::CLUSTER; + }; + + ~ClusterRename(){}; + + PoolObjectSQL * get(const string& name, int uid, bool lock) + { + return static_cast(pool)->get(name, lock); + }; + + void post_execute(int oid); +}; + +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + +class DatastoreRename: public RequestManagerRename +{ +public: + DatastoreRename(): + RequestManagerRename("DatastoreRename", "Renames a datastore") + { + Nebula& nd = Nebula::instance(); + pool = nd.get_dspool(); + auth_object = PoolObjectSQL::DATASTORE; + }; + + ~DatastoreRename(){}; + + PoolObjectSQL * get(const string& name, int uid, bool lock) + { + return static_cast(pool)->get(name, lock); + }; + + void post_execute(int oid); +}; + +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + +class HostRename: public RequestManagerRename +{ +public: + HostRename(): + RequestManagerRename("HostRename", "Renames a host") + { + Nebula& nd = Nebula::instance(); + pool = nd.get_hpool(); + auth_object = PoolObjectSQL::HOST; + }; + + ~HostRename(){}; + + PoolObjectSQL * get(const string& name, int uid, bool lock) + { + return static_cast(pool)->get(name, lock); + }; + + void post_execute(int oid); +}; + /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ diff --git a/include/VirtualMachine.h b/include/VirtualMachine.h index 38e943835a..645dc0b377 100644 --- a/include/VirtualMachine.h +++ b/include/VirtualMachine.h @@ -623,6 +623,16 @@ public: return history->hostname; }; + /** + * Updates the current hostname. The hasHistory() + * function MUST be called before this one. + * @param hostname New hostname + */ + void set_hostname(const string& hostname) + { + history->hostname = hostname; + }; + /** * Returns the hostname for the previous host. The hasPreviousHistory() * function MUST be called before this one. diff --git a/src/cli/onecluster b/src/cli/onecluster index 4e61e09e09..5624ec649b 100755 --- a/src/cli/onecluster +++ b/src/cli/onecluster @@ -197,4 +197,14 @@ cmd=CommandParser::CmdParser.new(ARGV) do obj.update(str, options[:append]) end end + + rename_desc = <<-EOT.unindent + Renames the Cluster + EOT + + command :rename, rename_desc, :clusterid, :name do + helper.perform_action(args[0],options,"renamed") do |o| + o.rename(args[1]) + end + end end diff --git a/src/cli/onedatastore b/src/cli/onedatastore index 77e4c4b2c2..7c09d0cb16 100755 --- a/src/cli/onedatastore +++ b/src/cli/onedatastore @@ -174,4 +174,14 @@ cmd=CommandParser::CmdParser.new(ARGV) do obj.update(str, options[:append]) end end + + rename_desc = <<-EOT.unindent + Renames the Datastore + EOT + + command :rename, rename_desc, :datastoreid, :name do + helper.perform_action(args[0],options,"renamed") do |o| + o.rename(args[1]) + end + end end diff --git a/src/cli/onehost b/src/cli/onehost index 9c9a4d9463..108db2d3fd 100755 --- a/src/cli/onehost +++ b/src/cli/onehost @@ -213,4 +213,14 @@ cmd=CommandParser::CmdParser.new(ARGV) do host.flush end end + + rename_desc = <<-EOT.unindent + Renames the Host + EOT + + command :rename, rename_desc, :hostid, :name do + helper.perform_action(args[0],options,"renamed") do |o| + o.rename(args[1]) + end + end end diff --git a/src/oca/ruby/opennebula/cluster.rb b/src/oca/ruby/opennebula/cluster.rb index 9f0997d96c..25c9d758f8 100644 --- a/src/oca/ruby/opennebula/cluster.rb +++ b/src/oca/ruby/opennebula/cluster.rb @@ -34,6 +34,7 @@ module OpenNebula :addvnet => "cluster.addvnet", :delvnet => "cluster.delvnet", :update => "cluster.update", + :rename => "cluster.rename" } # Creates a Cluster description with just its identifier @@ -171,6 +172,16 @@ module OpenNebula super(CLUSTER_METHODS[:update], new_template, append ? 1 : 0) end + # Renames this Cluster + # + # @param name [String] New name for the Cluster. + # + # @return [nil, OpenNebula::Error] nil in case of success, Error + # otherwise + def rename(name) + return call(CLUSTER_METHODS[:rename], @pe_id, name) + end + # --------------------------------------------------------------------- # Helpers to get information # --------------------------------------------------------------------- diff --git a/src/oca/ruby/opennebula/datastore.rb b/src/oca/ruby/opennebula/datastore.rb index 6bf2a9abca..fe702abfaa 100644 --- a/src/oca/ruby/opennebula/datastore.rb +++ b/src/oca/ruby/opennebula/datastore.rb @@ -29,7 +29,8 @@ module OpenNebula :delete => "datastore.delete", :update => "datastore.update", :chown => "datastore.chown", - :chmod => "datastore.chmod" + :chmod => "datastore.chmod", + :rename => "datastore.rename" } DATASTORE_TYPES=%w{IMAGE SYSTEM FILE} @@ -146,6 +147,16 @@ module OpenNebula group_m, group_a, other_u, other_m, other_a) end + # Renames this datastore + # + # @param name [String] New name for the datastore + # + # @return [nil, OpenNebula::Error] nil in case of success, Error + # otherwise + def rename(name) + return call(DATASTORE_METHODS[:rename], @pe_id, name) + end + # --------------------------------------------------------------------- # Helpers to get information # --------------------------------------------------------------------- diff --git a/src/oca/ruby/opennebula/host.rb b/src/oca/ruby/opennebula/host.rb index 94ab6f6323..7476e01c9e 100644 --- a/src/oca/ruby/opennebula/host.rb +++ b/src/oca/ruby/opennebula/host.rb @@ -30,7 +30,8 @@ module OpenNebula :delete => "host.delete", :enable => "host.enable", :update => "host.update", - :monitoring => "host.monitoring" + :monitoring => "host.monitoring", + :rename => "host.rename" } HOST_STATES=%w{INIT MONITORING_MONITORED MONITORED ERROR DISABLED MONITORING_ERROR MONITORING_INIT MONITORING_DISABLED} @@ -176,6 +177,16 @@ module OpenNebula return @client.call(HOST_METHODS[:monitoring], @pe_id) end + # Renames this Host + # + # @param name [String] New name for the Host. + # + # @return [nil, OpenNebula::Error] nil in case of success, Error + # otherwise + def rename(name) + return call(HOST_METHODS[:rename], @pe_id, name) + end + ####################################################################### # Helpers to get Host information ####################################################################### diff --git a/src/rm/RequestManager.cc b/src/rm/RequestManager.cc index 05d9aae885..55e70802fb 100644 --- a/src/rm/RequestManager.cc +++ b/src/rm/RequestManager.cc @@ -405,6 +405,9 @@ void RequestManager::register_xml_methods() xmlrpc_c::methodPtr vn_rename(new VirtualNetworkRename()); xmlrpc_c::methodPtr image_rename(new ImageRename()); xmlrpc_c::methodPtr doc_rename(new DocumentRename()); + xmlrpc_c::methodPtr cluster_rename(new ClusterRename()); + xmlrpc_c::methodPtr datastore_rename(new DatastoreRename()); + xmlrpc_c::methodPtr host_rename(new HostRename()); /* VM related methods */ RequestManagerRegistry.addMethod("one.vm.deploy", vm_deploy); @@ -452,6 +455,7 @@ void RequestManager::register_xml_methods() RequestManagerRegistry.addMethod("one.host.delete", host_delete); RequestManagerRegistry.addMethod("one.host.info", host_info); RequestManagerRegistry.addMethod("one.host.monitoring", host_monitoring); + RequestManagerRegistry.addMethod("one.host.rename", host_rename); RequestManagerRegistry.addMethod("one.hostpool.info", hostpool_info); RequestManagerRegistry.addMethod("one.hostpool.monitoring", host_pool_monitoring); @@ -524,6 +528,7 @@ void RequestManager::register_xml_methods() RequestManagerRegistry.addMethod("one.datastore.update", datastore_update); RequestManagerRegistry.addMethod("one.datastore.chown", datastore_chown); RequestManagerRegistry.addMethod("one.datastore.chmod", datastore_chmod); + RequestManagerRegistry.addMethod("one.datastore.rename", datastore_rename); RequestManagerRegistry.addMethod("one.datastorepool.info",datastorepool_info); @@ -532,6 +537,7 @@ void RequestManager::register_xml_methods() 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.rename", cluster_rename); RequestManagerRegistry.addMethod("one.cluster.addhost", cluster_addhost); RequestManagerRegistry.addMethod("one.cluster.delhost", cluster_delhost); diff --git a/src/rm/RequestManagerRename.cc b/src/rm/RequestManagerRename.cc index 0c5ba2bcca..6ca01c0b02 100644 --- a/src/rm/RequestManagerRename.cc +++ b/src/rm/RequestManagerRename.cc @@ -113,8 +113,223 @@ void RequestManagerRename::request_execute(xmlrpc_c::paramList const& paramList, pool->update_cache_index(old_name, operms.uid, new_name, operms.uid); + post_execute(oid); + success_response(oid, att); return; } +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +void * cluster_rename_loop(void *arg) +{ + Cluster * cluster = static_cast(arg); + + if (cluster == 0) + { + return 0; + } + + const set & hosts = cluster->get_host_ids(); + const set & datastores = cluster->get_datastore_ids(); + const set & vnets = cluster->get_vnet_ids(); + + set::iterator it; + + int oid = cluster->get_oid(); + string cluster_name = cluster->get_name(); + + cluster->unlock(); + + Host * host; + HostPool* hpool = Nebula::instance().get_hpool(); + + Datastore * ds; + DatastorePool* dspool = Nebula::instance().get_dspool(); + + VirtualNetwork* vnet; + VirtualNetworkPool* vnpool = Nebula::instance().get_vnpool(); + + for (it = hosts.begin(); it != hosts.end(); it++) + { + host = hpool->get(*it, true); + + if (host != 0) + { + if (host->get_cluster_id() == oid) + { + host->set_cluster(oid, cluster_name); + hpool->update(host); + } + + host->unlock(); + } + } + + for (it = datastores.begin(); it != datastores.end(); it++) + { + ds = dspool->get(*it, true); + + if (ds != 0) + { + if (ds->get_cluster_id() == oid) + { + ds->set_cluster(oid, cluster_name); + dspool->update(ds); + } + + ds->unlock(); + } + } + + for (it = vnets.begin(); it != vnets.end(); it++) + { + vnet = vnpool->get(*it, true); + + if (vnet != 0) + { + if (vnet->get_cluster_id() == oid) + { + vnet->set_cluster(oid, cluster_name); + vnpool->update(vnet); + } + + vnet->unlock(); + } + } + + return 0; +} + +void ClusterRename::post_execute(int oid) +{ + pthread_t pthread; + + pthread_attr_t pattr; + + pthread_attr_init (&pattr); + pthread_attr_setdetachstate (&pattr, PTHREAD_CREATE_DETACHED); + + Cluster * cluster = static_cast(pool)->get(oid, true); + + pthread_create(&pthread, &pattr, cluster_rename_loop, (void *) cluster); +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +void * ds_rename_loop(void *arg) +{ + Datastore * datastore = static_cast(arg); + + if (datastore == 0) + { + return 0; + } + + const set & images = datastore->get_image_ids(); + + set::iterator it; + + int oid = datastore->get_oid(); + string image_name = datastore->get_name(); + + datastore->unlock(); + + Image * image; + ImagePool * ipool = Nebula::instance().get_ipool(); + + for (it = images.begin(); it != images.end(); it++) + { + image = ipool->get(*it, true); + + if (image != 0) + { + if (image->get_ds_id() == oid) + { + image->set_ds_name(image_name); + ipool->update(image); + } + + image->unlock(); + } + } + + return 0; +} + +void DatastoreRename::post_execute(int oid) +{ + pthread_t pthread; + + pthread_attr_t pattr; + + pthread_attr_init (&pattr); + pthread_attr_setdetachstate (&pattr, PTHREAD_CREATE_DETACHED); + + Datastore * datastore = static_cast(pool)->get(oid, true); + + pthread_create(&pthread, &pattr, ds_rename_loop, (void *) datastore); +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +void * host_rename_loop(void *arg) +{ + Host * host = static_cast(arg); + + if (host == 0) + { + return 0; + } + + const set & vms = host->get_vm_ids(); + + set::iterator it; + + int oid = host->get_oid(); + string host_name = host->get_name(); + + host->unlock(); + + VirtualMachine * vm; + VirtualMachinePool * vmpool = Nebula::instance().get_vmpool(); + + for (it = vms.begin(); it != vms.end(); it++) + { + vm = vmpool->get(*it, true); + + if (vm != 0) + { + if (vm->hasHistory() && vm->get_hid() == oid) + { + vm->set_hostname(host_name); + vmpool->update(vm); + } + + vm->unlock(); + } + } + + return 0; +} + +void HostRename::post_execute(int oid) +{ + pthread_t pthread; + + pthread_attr_t pattr; + + pthread_attr_init (&pattr); + pthread_attr_setdetachstate (&pattr, PTHREAD_CREATE_DETACHED); + + Host * host = static_cast(pool)->get(oid, true); + + pthread_create(&pthread, &pattr, host_rename_loop, (void *) host); +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */