Commit b1b3e471f1143b0b8aab231005c896c571ea7de2
Committed by
Daniela Feitosa
1 parent
f2a648b7
Exists in
master
and in
23 other branches
Multitenancy documentation and separation
(ActionItem1845)
Showing
6 changed files
with
43 additions
and
11 deletions
Show diff stats
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 | ... | ... |