From b1b3e471f1143b0b8aab231005c896c571ea7de2 Mon Sep 17 00:00:00 2001 From: Caio SBA Date: Sun, 10 Apr 2011 18:30:21 -0300 Subject: [PATCH] Multitenancy documentation and separation --- INSTALL.multitenancy | 36 ++++++++++++++++++++++++++++++------ lib/acts_as_searchable.rb | 4 ++-- lib/noosfero/multi_tenancy.rb | 8 +++++++- lib/postgresql_attachment_fu.rb | 2 +- test/test_helper.rb | 2 ++ vendor/plugins/acts_as_ferret/lib/acts_as_ferret.rb | 2 +- 6 files changed, 43 insertions(+), 11 deletions(-) diff --git a/INSTALL.multitenancy b/INSTALL.multitenancy index 57d748f..49aa2cf 100644 --- a/INSTALL.multitenancy +++ b/INSTALL.multitenancy @@ -11,7 +11,7 @@ organization works with a customized virtual application instance. Today this feature is available only for PostgreSQL databases. -This document assumes that you have a fully PostgresSQL default Noosfero +This document assumes that you have a new fully PostgresSQL default Noosfero installation as explained at the INSTALL file. == Separated data @@ -121,11 +121,6 @@ Run Noosfero init file as root: It's necessary to run only one instance of ferret_server. Don't worry about this, Noosfero initializer had already done this for you. -Build or rebuild the Ferret index by running the following task just -for your hosting environment, do this as noosfero user: - -$ RAILS_ENV=production rake multitenancy:reindex - == Feed updater & Delayed job Just for your information, a daemon of feed-updater and delayed_job @@ -137,3 +132,32 @@ relax. When running with PostgreSQL, Noosfero uploads stuff to a folder named the same way as the running schema. Inside the upload folder root, for example, will be public/image_uploads/env2 and public/image_uploads/env3. + +== Adding multitenancy support to an existing Noosfero environment + +If you already have a Noosfero environment, you can turn it multitenant +by following the steps below in addition to the previous steps: + +1. Reindex your database + +Rebuild the Ferret index by running the following task just +for your hosting environment, do this as noosfero user: + +$ RAILS_ENV=production rake multitenancy:reindex + +2. Move the uploaded files to the right place + +Add a directory with the same name as your schema name (by default this +name is 'public') in the root of each upload directory, for example, +public/articles/0000 will be moved to public/articles/public/0000. Do this +with the directories public/image_uploads, public/articles and public/thumbnails. + +3. Fix paths on activities + +The profile activities store static paths to the images, so it's necessary to fix +these paths. You can do this easily by setting an alias on your webserver. +On Apache you can add the three rules below, where 'public' is the schema name: + + RewriteRule ^/articles(.+) /articles/public$1 + RewriteRule ^/image_uploads(.+) /image_uploads/public$1 + RewriteRule ^/thumbnails(.+) /thumbnails/public$1 diff --git a/lib/acts_as_searchable.rb b/lib/acts_as_searchable.rb index 7f585e2..9721368 100644 --- a/lib/acts_as_searchable.rb +++ b/lib/acts_as_searchable.rb @@ -2,7 +2,7 @@ module ActsAsSearchable module ClassMethods def acts_as_searchable(options = {}) - if ActiveRecord::Base.connection.adapter_name == 'PostgreSQL' + if Noosfero::MultiTenancy.on? and ActiveRecord::Base.postgresql? options[:additional_fields] ||= {} options[:additional_fields] = Hash[*options[:additional_fields].collect{ |v| [v, {}] }.flatten] if options[:additional_fields].is_a?(Array) options[:additional_fields].merge!(:schema_name => { :index => :untokenized }) @@ -35,7 +35,7 @@ module ActsAsSearchable ferret_options[:limit] = :all - ferret_query = ActiveRecord::Base.connection.adapter_name == 'PostgreSQL' ? "+schema_name:\"#{schema_name}\" AND #{query}" : query + ferret_query = (Noosfero::MultiTenancy.on? and ActiveRecord::Base.postgresql?) ? "+schema_name:\"#{schema_name}\" AND #{query}" : query # FIXME this is a HORRIBLE HACK ids = find_ids_with_ferret(ferret_query, ferret_options)[1][0..8000].map{|r|r[:id].to_i} diff --git a/lib/noosfero/multi_tenancy.rb b/lib/noosfero/multi_tenancy.rb index 40a14d2..bb520bc 100644 --- a/lib/noosfero/multi_tenancy.rb +++ b/lib/noosfero/multi_tenancy.rb @@ -6,7 +6,7 @@ module Noosfero end def self.on? - !self.mapping.blank? + !self.mapping.blank? || self.is_hosted_environment? end def self.db_by_host=(host) @@ -26,5 +26,11 @@ module Noosfero map end + def self.is_hosted_environment? + db_file = File.join(RAILS_ROOT, 'config', 'database.yml') + db_config = YAML.load_file(db_file) + db_config.select{ |env, attr| RAILS_ENV.to_s.match(/_#{env}$/) }.any? + end + end end diff --git a/lib/postgresql_attachment_fu.rb b/lib/postgresql_attachment_fu.rb index 88e9d6c..404882b 100644 --- a/lib/postgresql_attachment_fu.rb +++ b/lib/postgresql_attachment_fu.rb @@ -9,7 +9,7 @@ module PostgresqlAttachmentFu module InstanceMethods def full_filename(thumbnail = nil) file_system_path = (thumbnail ? thumbnail_class : self).attachment_options[:path_prefix].to_s - file_system_path = File.join(file_system_path, ActiveRecord::Base.connection.schema_search_path) if ActiveRecord::Base.postgresql? + file_system_path = File.join(file_system_path, ActiveRecord::Base.connection.schema_search_path) if ActiveRecord::Base.postgresql? and Noosfero::MultiTenancy.on? File.join(RAILS_ROOT, file_system_path, *partitioned_path(thumbnail_name_for(thumbnail))) end end diff --git a/test/test_helper.rb b/test/test_helper.rb index fe59ef0..deefbab 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -189,12 +189,14 @@ class Test::Unit::TestCase adapter = ActiveRecord::Base.connection.class adapter.any_instance.stubs(:adapter_name).returns('PostgreSQL') adapter.any_instance.stubs(:schema_search_path).returns(schema_name) + Noosfero::MultiTenancy.stubs(:on?).returns(true) reload_for_ferret end def uses_sqlite adapter = ActiveRecord::Base.connection.class adapter.any_instance.stubs(:adapter_name).returns('SQLite') + Noosfero::MultiTenancy.stubs(:on?).returns(false) end def reload_for_ferret diff --git a/vendor/plugins/acts_as_ferret/lib/acts_as_ferret.rb b/vendor/plugins/acts_as_ferret/lib/acts_as_ferret.rb index 444dda7..b2b48ac 100644 --- a/vendor/plugins/acts_as_ferret/lib/acts_as_ferret.rb +++ b/vendor/plugins/acts_as_ferret/lib/acts_as_ferret.rb @@ -204,7 +204,7 @@ module ActsAsFerret # these properties are somewhat vital to the plugin and shouldn't # be overwritten by the user: index_definition[:ferret].update( - :key => (ActiveRecord::Base.connection.adapter_name == 'PostgreSQL' ? [:id, :class_name, :schema_name] : [:id, :class_name]), + :key => ((Noosfero::MultiTenancy.on? and ActiveRecord::Base.postgresql?) ? [:id, :class_name, :schema_name] : [:id, :class_name]), :path => index_definition[:index_dir], :auto_flush => true, # slower but more secure in terms of locking problems TODO disable when running in drb mode? :create_if_missing => true -- libgit2 0.21.2