Commit b1b3e471f1143b0b8aab231005c896c571ea7de2

Authored by Caio SBA
Committed by Daniela Feitosa
1 parent f2a648b7

Multitenancy documentation and separation

(ActionItem1845)
INSTALL.multitenancy
... ... @@ -11,7 +11,7 @@ organization works with a customized virtual application instance.
11 11  
12 12 Today this feature is available only for PostgreSQL databases.
13 13  
14   -This document assumes that you have a fully PostgresSQL default Noosfero
  14 +This document assumes that you have a new fully PostgresSQL default Noosfero
15 15 installation as explained at the INSTALL file.
16 16  
17 17 == Separated data
... ... @@ -121,11 +121,6 @@ Run Noosfero init file as root:
121 121 It's necessary to run only one instance of ferret_server. Don't worry
122 122 about this, Noosfero initializer had already done this for you.
123 123  
124   -Build or rebuild the Ferret index by running the following task just
125   -for your hosting environment, do this as noosfero user:
126   -
127   -$ RAILS_ENV=production rake multitenancy:reindex
128   -
129 124 == Feed updater & Delayed job
130 125  
131 126 Just for your information, a daemon of feed-updater and delayed_job
... ... @@ -137,3 +132,32 @@ relax.
137 132 When running with PostgreSQL, Noosfero uploads stuff to a folder named
138 133 the same way as the running schema. Inside the upload folder root, for
139 134 example, will be public/image_uploads/env2 and public/image_uploads/env3.
  135 +
  136 +== Adding multitenancy support to an existing Noosfero environment
  137 +
  138 +If you already have a Noosfero environment, you can turn it multitenant
  139 +by following the steps below in addition to the previous steps:
  140 +
  141 +1. Reindex your database
  142 +
  143 +Rebuild the Ferret index by running the following task just
  144 +for your hosting environment, do this as noosfero user:
  145 +
  146 +$ RAILS_ENV=production rake multitenancy:reindex
  147 +
  148 +2. Move the uploaded files to the right place
  149 +
  150 +Add a directory with the same name as your schema name (by default this
  151 +name is 'public') in the root of each upload directory, for example,
  152 +public/articles/0000 will be moved to public/articles/public/0000. Do this
  153 +with the directories public/image_uploads, public/articles and public/thumbnails.
  154 +
  155 +3. Fix paths on activities
  156 +
  157 +The profile activities store static paths to the images, so it's necessary to fix
  158 +these paths. You can do this easily by setting an alias on your webserver.
  159 +On Apache you can add the three rules below, where 'public' is the schema name:
  160 +
  161 + RewriteRule ^/articles(.+) /articles/public$1
  162 + RewriteRule ^/image_uploads(.+) /image_uploads/public$1
  163 + RewriteRule ^/thumbnails(.+) /thumbnails/public$1
... ...
lib/acts_as_searchable.rb
... ... @@ -2,7 +2,7 @@ module ActsAsSearchable
2 2  
3 3 module ClassMethods
4 4 def acts_as_searchable(options = {})
5   - if ActiveRecord::Base.connection.adapter_name == 'PostgreSQL'
  5 + if Noosfero::MultiTenancy.on? and ActiveRecord::Base.postgresql?
6 6 options[:additional_fields] ||= {}
7 7 options[:additional_fields] = Hash[*options[:additional_fields].collect{ |v| [v, {}] }.flatten] if options[:additional_fields].is_a?(Array)
8 8 options[:additional_fields].merge!(:schema_name => { :index => :untokenized })
... ... @@ -35,7 +35,7 @@ module ActsAsSearchable
35 35  
36 36 ferret_options[:limit] = :all
37 37  
38   - ferret_query = ActiveRecord::Base.connection.adapter_name == 'PostgreSQL' ? "+schema_name:\"#{schema_name}\" AND #{query}" : query
  38 + ferret_query = (Noosfero::MultiTenancy.on? and ActiveRecord::Base.postgresql?) ? "+schema_name:\"#{schema_name}\" AND #{query}" : query
39 39 # FIXME this is a HORRIBLE HACK
40 40 ids = find_ids_with_ferret(ferret_query, ferret_options)[1][0..8000].map{|r|r[:id].to_i}
41 41  
... ...
lib/noosfero/multi_tenancy.rb
... ... @@ -6,7 +6,7 @@ module Noosfero
6 6 end
7 7  
8 8 def self.on?
9   - !self.mapping.blank?
  9 + !self.mapping.blank? || self.is_hosted_environment?
10 10 end
11 11  
12 12 def self.db_by_host=(host)
... ... @@ -26,5 +26,11 @@ module Noosfero
26 26 map
27 27 end
28 28  
  29 + def self.is_hosted_environment?
  30 + db_file = File.join(RAILS_ROOT, 'config', 'database.yml')
  31 + db_config = YAML.load_file(db_file)
  32 + db_config.select{ |env, attr| RAILS_ENV.to_s.match(/_#{env}$/) }.any?
  33 + end
  34 +
29 35 end
30 36 end
... ...
lib/postgresql_attachment_fu.rb
... ... @@ -9,7 +9,7 @@ module PostgresqlAttachmentFu
9 9 module InstanceMethods
10 10 def full_filename(thumbnail = nil)
11 11 file_system_path = (thumbnail ? thumbnail_class : self).attachment_options[:path_prefix].to_s
12   - file_system_path = File.join(file_system_path, ActiveRecord::Base.connection.schema_search_path) if ActiveRecord::Base.postgresql?
  12 + file_system_path = File.join(file_system_path, ActiveRecord::Base.connection.schema_search_path) if ActiveRecord::Base.postgresql? and Noosfero::MultiTenancy.on?
13 13 File.join(RAILS_ROOT, file_system_path, *partitioned_path(thumbnail_name_for(thumbnail)))
14 14 end
15 15 end
... ...
test/test_helper.rb
... ... @@ -189,12 +189,14 @@ class Test::Unit::TestCase
189 189 adapter = ActiveRecord::Base.connection.class
190 190 adapter.any_instance.stubs(:adapter_name).returns('PostgreSQL')
191 191 adapter.any_instance.stubs(:schema_search_path).returns(schema_name)
  192 + Noosfero::MultiTenancy.stubs(:on?).returns(true)
192 193 reload_for_ferret
193 194 end
194 195  
195 196 def uses_sqlite
196 197 adapter = ActiveRecord::Base.connection.class
197 198 adapter.any_instance.stubs(:adapter_name).returns('SQLite')
  199 + Noosfero::MultiTenancy.stubs(:on?).returns(false)
198 200 end
199 201  
200 202 def reload_for_ferret
... ...
vendor/plugins/acts_as_ferret/lib/acts_as_ferret.rb
... ... @@ -204,7 +204,7 @@ module ActsAsFerret
204 204 # these properties are somewhat vital to the plugin and shouldn't
205 205 # be overwritten by the user:
206 206 index_definition[:ferret].update(
207   - :key => (ActiveRecord::Base.connection.adapter_name == 'PostgreSQL' ? [:id, :class_name, :schema_name] : [:id, :class_name]),
  207 + :key => ((Noosfero::MultiTenancy.on? and ActiveRecord::Base.postgresql?) ? [:id, :class_name, :schema_name] : [:id, :class_name]),
208 208 :path => index_definition[:index_dir],
209 209 :auto_flush => true, # slower but more secure in terms of locking problems TODO disable when running in drb mode?
210 210 :create_if_missing => true
... ...