diff --git a/.travis.yml b/.travis.yml index 87976c4e..eb15af14 100644 --- a/.travis.yml +++ b/.travis.yml @@ -32,7 +32,7 @@ before_install: before_script: - bundle exec rake db:create - - bundle exec chromedriver-update 74.0.3729.6 + - bundle exec chromedriver-update 76.0.3809.68 before_deploy: - git clean -dxf; rm -rf vendor/bundle diff --git a/Dockerfile b/Dockerfile index c628fe64..e437912a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -10,6 +10,6 @@ COPY --chown=app . $APP_HOME RUN /sbin/setuser app bash -l -c "set -x && \ (bundle check || bundle install) && \ bundle exec rake assets:precompile DB_ADAPTER=nulldb && \ - mv ./public/assets ./public/assets.new" + mv ./public/assets ./public/assets-new" CMD ["/sbin/my_init"] diff --git a/Dockerfile.base b/Dockerfile.base index 38683534..b30c3c9f 100644 --- a/Dockerfile.base +++ b/Dockerfile.base @@ -1,7 +1,20 @@ FROM phusion/passenger-ruby25:1.0.2 RUN apt-get update -qq && \ - apt-get install -y build-essential libpq-dev nodejs libreoffice imagemagick unzip ghostscript libsasl2-dev libpq-dev postgresql-client tzdata && \ + apt-get install -y \ + build-essential \ + ghostscript \ + imagemagick \ + libpq-dev \ + libpq-dev nodejs \ + libreoffice \ + libsasl2-dev \ + netcat \ + postgresql-client \ + rsync \ + tzdata \ + unzip \ + && \ apt-get clean && \ rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* diff --git a/README.md b/README.md index 91244437..3c0af2b9 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,7 @@ Jump In: [![Slack Status](http://slack.samvera.org/badge.svg)](http://slack.samv * [On AWS](#on-aws) * [With Docker](#with-docker) * [With Vagrant](#with-vagrant) + * [Single Tenant Mode](#single-tenancy) * [Switching accounts](#switching-accounts) * [Development dependencies](#development-dependencies) * [Postgres](#postgres) @@ -63,7 +64,8 @@ The full spec suite can be run in docker locally. There are several ways to do t docker-compose exec web rake ``` -### For development +### With out Docker +#### For development ```bash solr_wrapper @@ -74,7 +76,7 @@ bin/setup DISABLE_REDIS_CLUSTER=true bundle exec sidekiq DISABLE_REDIS_CLUSTER=true bundle exec rails server -b 0.0.0.0 ``` -### For testing +#### For testing See the [Hyku Development Guide](https://github.com/samvera/hyku/wiki/Hyku-Development-Guide) for how to run tests. @@ -104,6 +106,12 @@ docker-compose up -d The [samvera-vagrant project](https://github.com/samvera-labs/samvera-vagrant) provides another simple way to get started "kicking the tires" of Hyku (and [Hyrax](http://hyr.ax/)), making it easy and quick to spin up Hyku. (Note that this is not for production or production-like installations.) It requires [VirtualBox](https://www.virtualbox.org/) and [Vagrant](https://www.vagrantup.com/). +## Single Tenant Mode + +Much of the default configuration in Hyku is set up to use multi-tenant mode. This default mode allows Hyku users to run the equivielent of multiple Hyrax installs on a single set of resources. However, sometimes the subdomain splitting mutli-headed complexity is simply not needed. If this is the case, then single tenant mode is for you. Single tenant mode will not show the tenant sign up page, or any of the tenant management screens. Instead it shows a single Samvera instance at what ever domain is pointed at the application. + +To enable single tenant, in your settings.yml file change multitenancy/enabled to `false` or set `SETTINGS__MULTITENANCY__ENABLED=false` in your `docker-compose.yml` and `docker-compose.production.yml` configs. After changinig this setting, run the seeds to prepopulate the single tenant. + ## Switching accounts The recommend way to switch your current session from one account to another is by doing: @@ -116,7 +124,7 @@ AccountElevator.switch!('repo.example.com') ### Postgres -Hydra-in-a-Box supports multitenancy using the `apartment` gem. `apartment` works best with a postgres database. +Hyku supports multitenancy using the `apartment` gem. `apartment` works best with a postgres database. ## Importing ### from CSV: diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index f1e2798b..18717c64 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -33,7 +33,6 @@ class ApplicationController < ActionController::Base def require_active_account! return unless Settings.multitenancy.enabled return if devise_controller? - raise Apartment::TenantNotFound, "No tenant for #{request.host}" unless current_account.persisted? end @@ -53,7 +52,15 @@ def admin_host? def current_account @current_account ||= Account.from_request(request) - @current_account ||= Account.single_tenant_default + @current_account ||= if Settings.multitenancy.enabled + Account.new do |a| + a.build_solr_endpoint + a.build_fcrepo_endpoint + a.build_redis_endpoint + end + else + Account.single_tenant_default + end end # Add context information to the lograge entries diff --git a/app/models/account.rb b/app/models/account.rb index 75be5a75..60822c44 100644 --- a/app/models/account.rb +++ b/app/models/account.rb @@ -61,11 +61,13 @@ def self.from_request(request) # @return [Account] a placeholder account using the default connections configured by the application def self.single_tenant_default - Account.new do |a| + @single_tenant_default ||= Account.find_by(cname: 'single.tenant.default') + @single_tenant_default ||= Account.new do |a| a.build_solr_endpoint a.build_fcrepo_endpoint a.build_redis_endpoint end + @single_tenant_default end # @return [Boolean] whether this Account is the global tenant in a multitenant environment diff --git a/db/seeds.rb b/db/seeds.rb index 115fa55d..893dcc1d 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -12,3 +12,8 @@ Hyrax::Workflow::WorkflowImporter.load_workflows errors = Hyrax::Workflow::WorkflowImporter.load_errors abort("Failed to process all workflows:\n #{errors.join('\n ')}") unless errors.empty? + +unless Settings.multitenancy.enabled + single_tenant_default = Account.new(name: 'Single Tenenat', cname: 'single.tenant.default', tenant: 'single') + CreateAccount.new(single_tenant_default).save +end diff --git a/docker-compose.production.yml b/docker-compose.production.yml index acc8291e..4040ab10 100644 --- a/docker-compose.production.yml +++ b/docker-compose.production.yml @@ -13,7 +13,6 @@ volumes: assets: networks: - external: internal: services: @@ -79,7 +78,6 @@ services: expose: - 8983 volumes: - - .:/app - solr:/opt/solr/server/solr networks: internal: @@ -93,6 +91,7 @@ services: volumes: - fcrepo:/data environment: + # - JAVA_OPTS=-Dfcrepo.modeshape.configuration="classpath:/config/jdbc-postgresql-s3/repository.json" -Dfcrepo.postgresql.host="db" -Dfcrepo.postgresql.username="postgres" -Dfcrepo.postgresql.password="DatabaseFTW" -Daws.accessKeyId="REPLACE_WITH_AWS_ID" -Daws.secretKey="REPLACE_WITH_AWS_SECRET_KEY" -Daws.bucket="REPLACE_WITH_BUCKET_NAME" - JAVA_OPTS=${JAVA_OPTS} -Dfcrepo.modeshape.configuration="classpath:/config/file-simple/repository.json" -Dfcrepo.object.directory="/data/objects" -Dfcrepo.binary.directory="/data/binaries" networks: internal: @@ -106,16 +105,7 @@ services: networks: internal: - base: - image: hyku/base:latest - build: - context: . - dockerfile: Dockerfile.base - env_file: - - .env - app: - build: . image: hyku/main:latest env_file: - .env @@ -124,6 +114,7 @@ services: - FEDORA_URL=http://fcrepo:8080/fcrepo/rest - IN_DOCKER=true - LD_LIBRARY_PATH=/opt/fits/tools/mediainfo/linux + - PASSENGER_APP_ENV=production - RAILS_CACHE_STORE_URL=memcache - RAILS_LOG_TO_STDOUT=true - REDIS_HOST=redis @@ -140,16 +131,12 @@ services: volumes: - app:/home/app/webapp/tmp/uploads - assets:/home/app/webapp/public/assets - - .:/home/app/webapp networks: internal: web: extends: service: app - environment: - - VIRTUAL_PORT=80 - - VIRTUAL_HOST=hyku.docker depends_on: - db - solr diff --git a/docker-compose.yml b/docker-compose.yml index 47c057bd..e6cee880 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -11,7 +11,6 @@ volumes: assets: networks: - external: internal: services: @@ -34,7 +33,7 @@ services: - zookeeper_cluster solr: - image: solr:7.1 + image: solr:7.5 command: solr -c -f -z zoo1:2181 depends_on: - zoo1 diff --git a/ops/nginx.sh b/ops/nginx.sh index 964a4156..28f7d8d9 100755 --- a/ops/nginx.sh +++ b/ops/nginx.sh @@ -20,6 +20,8 @@ fi if [[ $PASSENGER_APP_ENV == "production" ]] || [[ $PASSENGER_APP_ENV == "staging" ]] then + /bin/bash -l -c 'chown -R app:app /home/app/webapp/tmp' # mounted volume may have wrong permissions + /bin/bash -l -c 'chown -R app:app /home/app/webapp/public/assets' # mounted volume may have wrong permissions /sbin/setuser app /bin/bash -l -c 'cd /home/app/webapp && rsync -a public/assets-new/ public/assets/' fi diff --git a/spec/features/edit_file_spec.rb b/spec/features/edit_file_spec.rb deleted file mode 100644 index e81f5f1e..00000000 --- a/spec/features/edit_file_spec.rb +++ /dev/null @@ -1,23 +0,0 @@ -RSpec.describe "Editing a file:", type: :feature do - let(:user) { create(:user) } - let(:file_title) { 'Some kind of title' } - let(:work) { build(:work, user: user) } - let(:file_set) { create(:file_set, user: user, title: [file_title]) } - let(:file) { File.open(fixture_path + '/images/world.png') } - - before do - login_as(user, scope: :user) - Hydra::Works::AddFileToFileSet.call(file_set, file, :original_file) - work.ordered_members << file_set - work.save! - end - - context 'when the user tries to update file content, but forgets to select a file:' do - it 'shows the edit page again' do - visit edit_hyrax_file_set_path(file_set) - click_link 'Versions' - click_button 'Upload New Version' - expect(page).to have_content "Edit #{file_title}" - end - end -end diff --git a/spec/models/solr_endpoint_spec.rb b/spec/models/solr_endpoint_spec.rb index eb312eba..9b5afcfb 100644 --- a/spec/models/solr_endpoint_spec.rb +++ b/spec/models/solr_endpoint_spec.rb @@ -25,9 +25,9 @@ allow(ActiveFedora::SolrService.instance).to receive(:conn) .and_return(double(options: af_options)) allow(RSolr).to receive(:connect) - .with("read_timeout" => 120, - "open_timeout" => 120, - "url" => "http://example.com/solr/") + .with(hash_including("read_timeout" => 120, + "open_timeout" => 120, + "url" => "http://example.com/solr/")) .and_return(result) end diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index fb8f89f7..6bfc3683 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -144,13 +144,13 @@ config.before(:suite) do DatabaseCleaner.clean_with(:truncation) + Account.destroy_all CreateSolrCollectionJob.new.without_account('hydra-test') if ENV['IN_DOCKER'] end config.before(:each) do |example| # Pass `:clean' to destroy objects in fedora/solr and start from scratch ActiveFedora::Cleaner.clean! if example.metadata[:clean] - if example.metadata[:type] == :feature && Capybara.current_driver != :rack_test DatabaseCleaner.strategy = :truncation else