Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Per environment master shard #538

Open
wants to merge 45 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
74145f1
Setup a docker development environment
calh Jun 21, 2019
48090f0
Start on setting up sample_app -- not working
calh Jun 25, 2019
8e2671d
Ooops, revert a couple files.
calh Jun 25, 2019
c3ac7ca
Add DB2 server
calh Jun 26, 2019
ce42246
Trying to add ibm_db gem to gemspec
calh Jun 26, 2019
75a1ef5
Adding ibm_db versions for each rails version
calh Jun 26, 2019
77a3155
Install the DB2 ODBC driver
calh Jun 26, 2019
faaca64
Add a DB2 shard
calh Jun 26, 2019
28e9190
Appriasal run for ibm_db
calh Jun 26, 2019
3e9f50b
Check that @config exists. Fixes #413
calh Jun 26, 2019
4fd1129
Check that @config exists. Fixes #413
calh Jun 26, 2019
5f3bc57
Monkey patch IBM_DBAdapter to add @config
calh Jun 26, 2019
fa21f02
Ooof, typo in filename
calh Jun 28, 2019
9da3a89
Adding db2
calh Jun 28, 2019
08ad9e0
Adding DB2
calh Jun 28, 2019
ee8c9d2
Setting up DB2 server image
calh Jun 28, 2019
4a488a9
Add conditional check to allow the ibm_db gem to be optional
calh Jul 1, 2019
66c61c6
Optionally load the ibm_db gem
calh Jul 1, 2019
a70aad5
ibm_db support only works in rails 4.2 and 5.0
calh Jul 1, 2019
5ef3e27
Remove ibm_db gem, this is optional now
calh Jul 1, 2019
82205de
Remove ibm_db from rails 5.1
calh Jul 1, 2019
1c658c1
First DB2 test is working
calh Jul 1, 2019
7f48d85
Note on DB2
calh Jul 2, 2019
c6e267f
We don't need this with Appraisal
calh Jul 2, 2019
3495359
Tests for DB2
calh Jul 2, 2019
1c5b373
Add db2 port/db
calh Jul 3, 2019
67dc844
Adding expect, in case I change up the entrypoint/cmd
calh Jul 3, 2019
a96f523
Create 4 total dbs for shard/replication testing
calh Jul 3, 2019
3dcd867
db:prepare on rails5, run tests against all Appraisals
calh Jul 3, 2019
ea41105
Skip migrations with DB2. Random bug in ibm_db.
calh Jul 18, 2019
091f9ef
DB2 doesn't have boolean types
calh Jul 18, 2019
65d981d
Adding Appriasals just for DB2.
calh Jul 18, 2019
c63e2a0
Ooops, wrong names
calh Jul 18, 2019
86058e1
Boolean coersion works in rails 4.2 with DB2
calh Jul 18, 2019
fc18f35
Merge pull request #1 from calh/docker-dev-system
calh Jul 18, 2019
cc72467
Merge pull request #2 from calh/nil_shard_config
calh Jul 18, 2019
2cbfd9e
Merge pull request #3 from calh/ibm_db
calh Jul 18, 2019
f241079
Issue with stock ibm_db 4.0.0 gem
calh Jul 18, 2019
9a8b293
Fix for DB2 hanging indefinitely on disconnect with Passenger
calh Jul 31, 2019
8b59e83
Better condition for skipping disconnects on DB2
calh Jul 31, 2019
98de909
Better cross-adapter method of checking the db type
calh Jul 31, 2019
92b4caf
Skip the connected? test with DB2
calh Aug 5, 2019
d5431c2
Merge branch 'ibm_db'
calh Aug 5, 2019
a4d2a06
Add a per-environment master_shard option
calh Aug 28, 2019
1d07220
Better fix for per-environment master shards
calh Aug 28, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
*.gem
*.sqlite3
.bundle
.rvmrc
.ruby-version
Gemfile.lock
gemfiles/*.lock
pkg/*
*.rbc
tmp/*
.*.sw[a-z]
database.log
24 changes: 23 additions & 1 deletion Appraisals
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,29 @@ appraise "rails42" do
gem "activerecord", "~> 4.2.0"
end

appraise "rails5" do
appraise "rails42_db2" do
gem "activerecord", "~> 4.2.0"
#Causes issue https://github.com/ibmdb/ruby-ibmdb/issues/31
# Wait for this PR to be accepted or pull in a local gem for yourself:
# https://github.com/ibmdb/ruby-ibmdb/pull/38/files
gem "ibm_db", "~> 3.0.5"
end

appraise "rails50_db2" do
gem "activerecord", "~> 5.0.0"
# For now, ibm_db only works on rails 5.0
#gem "ibm_db", "~> 4.0.0"
# 4.0.0 breaks on empty_insert_statement_value issue:
# https://github.com/ibmdb/ruby-ibmdb/pull/89
# I've merged this into my own branch for testing until
# IBM fixes this issue officially
gem "ibm_db",
git: "https://github.com/calh/ruby-ibmdb.git",
branch: "v4.0.1",
glob: "IBM_DB_Adapter/ibm_db/IBM_DB.gemspec"
end

appraise "rails50" do
gem "activerecord", "~> 5.0.0"
end

Expand Down
42 changes: 42 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
FROM ruby:2.5

RUN apt-get update && apt-get install -y \
mysql-client \
postgresql \
vim

# Install the IBM DB2 CLI driver. The ibm_db gem install
# will also do this, but it has no status output and takes
# several minutes.
ENV IBM_DB_HOME=/opt/ibm/clidriver
RUN wget http://public.dhe.ibm.com/ibmdl/export/pub/software/data/db2/drivers/odbc_cli/linuxx64_odbc_cli.tar.gz -O /tmp/linuxx64_odbc_cli.tar.gz \
&& mkdir -p /opt/ibm \
&& tar -C /opt/ibm -xzvf /tmp/linuxx64_odbc_cli.tar.gz

# Set up DB2 libraries and catalogs
COPY docker/db2-ld.conf /etc/ld.so.conf.d/
COPY docker/db2dsdriver.cfg /opt/ibm/clidriver/cfg/
RUN ldconfig

WORKDIR /usr/src/app

# Pull in a full profile for gem/bundler
SHELL ["/bin/bash", "-l", "-c"]

RUN gem install --no-document bundler -v 1.16.6

# Uncomment if you don't want to use Appraisal
# Copy only what's needed for bundler
#COPY Gemfile ar-octopus.gemspec /usr/src/app/
#COPY lib/octopus/version.rb /usr/src/app/lib/octopus/version.rb
#RUN bundle install --path=.bundle

# Uncomment if you want to copy the octopus repo
# into the Docker image itself. docker-compose is
# set up to use a bind mount of your local directory
# from the host
#COPY . /usr/src/app

# This just keeps the container running. Replace
# this with a rails server if you want
CMD ["/bin/sleep", "infinity"]
41 changes: 41 additions & 0 deletions README.mkdn
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,47 @@ bundle install
cucumber
```

### Using Docker Compose

For a more consistent build/test/development environment, use [Docker Compose](https://docs.docker.com/compose/install/).

```bash
[me@host octopus]$ docker-compose -f docker-compose.yml up
Creating network "octopus_default" with the default driver
Creating octopus_postgres_1 ...
Creating octopus_mysql_1 ...
Creating octopus_postgres_1
. . .
octopus_1 | mysqld is alive
octopus_1 | MySQL is ready
octopus_1 | + bundle exec rake db:prepare
. . .
octopus_1 | + bundle exec rake spec
. . .
octopus_1 | Finished in 7 minutes 44 seconds (files took 0.71416 seconds to load)
octopus_1 | 359 examples, 0 failures, 2 pending

(Ctrl+C to shut down the stack)
```

Your workstation's octopus clone is mounted inside the docker container, so
you may still use your favorite development tools. The `octopus_1` container
is available for re-running the test suite. To start a new shell in another
terminal, run:

```bash
[me@host octopus]$ docker-compose exec octopus /bin/bash
root@f6ae68df6fc8:/usr/src/app#
# run bundle exec rake spec again
```

To completely destory the stack and start over:

```bash
[me@host octopus]$ docker-compose -f docker-compose.yml down
[me@host octopus]$ docker-compose -f docker-compose.yml up
```

If you are having issues running the octopus spec suite, verify your database users and passwords match those inside the config files and your permissions are correct.

## Contributors:
Expand Down
28 changes: 26 additions & 2 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ require 'rspec/core/rake_task'
require 'rubocop/rake_task'
require 'appraisal'

$stdout.sync = true
RSpec::Core::RakeTask.new
RuboCop::RakeTask.new

Expand All @@ -13,15 +14,17 @@ namespace :db do
task :build_databases do
pg_spec = {
:adapter => 'postgresql',
:host => 'localhost',
:host => (ENV['POSTGRES_HOST'] || ''),
:username => (ENV['POSTGRES_USER'] || 'postgres'),
:password => (ENV['POSTGRES_PASSWORD'] || ''),
:encoding => 'utf8',
}

mysql_spec = {
:adapter => 'mysql2',
:host => 'localhost',
:host => (ENV['MYSQL_HOST'] || ''),
:username => (ENV['MYSQL_USER'] || 'root'),
:password => (ENV['MYSQL_PASSWORD'] || ''),
:encoding => 'utf8',
}

Expand All @@ -30,6 +33,7 @@ namespace :db do
require 'active_record'

# Connects to PostgreSQL
puts "Connecting to PostgreSQL"
ActiveRecord::Base.establish_connection(pg_spec.merge('database' => 'postgres', 'schema_search_path' => 'public'))
(1..2).map do |i|
# drop the old database (if it exists)
Expand All @@ -39,13 +43,15 @@ namespace :db do
end

# Connect to MYSQL
puts "Connecting to MySQL"
ActiveRecord::Base.establish_connection(mysql_spec)
(1..5).map do |i|
# drop the old database (if it exists)
ActiveRecord::Base.connection.drop_database("octopus_shard_#{i}")
# create new database
ActiveRecord::Base.connection.create_database("octopus_shard_#{i}")
end

end

desc 'Create tables on tests databases'
Expand All @@ -58,15 +64,33 @@ namespace :db do
require "#{File.dirname(__FILE__)}/spec/support/database_connection"

shard_symbols = [:master, :brazil, :canada, :russia, :alone_shard, :postgresql_shard, :sqlite_shard]
if Octopus.ibm_db_support?
shard_symbols += [:db2_1, :db2_2, :db2_3, :db2_4]
end

shard_symbols << :protocol_shard
shard_symbols.each do |shard_symbol|
# Rails 3.1 needs to do some introspection around the base class, which requires
# the model be a descendent of ActiveRecord::Base.
class BlankModel < ActiveRecord::Base; end

puts "Preparing shard #{shard_symbol}"
BlankModel.using(shard_symbol).connection.initialize_schema_migrations_table
BlankModel.using(shard_symbol).connection.initialize_metadata_table if Octopus.atleast_rails50?

# Since it's too slow to drop/create DB2 databases,
# drop all the tables instead
if BlankModel.using(shard_symbol).connection.adapter_name == "IBM_DB"
[:users,:clients,:cats,:items,:computers,:keyboards, :roles,
:permissions, :permissions_roles, :assignments, :programmers,
:projects, :comments, :parts, :yummy, :adverts, :custom].each do |table|
begin
BlankModel.using(shard_symbol).connection.drop_table(table)
rescue ActiveRecord::StatementInvalid
end
end
end

BlankModel.using(shard_symbol).connection.create_table(:users) do |u|
u.string :name
u.integer :number
Expand Down
54 changes: 54 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
version: '3'

services:
octopus:
build: .
# Your local clone binds to /usr/src/app
volumes:
- .:/usr/src/app
environment:
POSTGRES_HOST: postgres # image name below
POSTGRES_USER: postgres
POSTGRES_PASSWORD: testpassword # password below
MYSQL_HOST: mysql
MYSQL_USER: root
MYSQL_PASSWORD: testpassword
DB2_HOST: db2
DB2_USER: db2inst1
DB2_PASSWORD: testpassword
DB2_PORT: 50000
DB2_DATABASE: octopus6
depends_on:
- mysql
- postgres
- db2
# Wait for databases to start up, run test suite
command: ./docker/startup.sh
mysql:
image: mysql:8
command: --default-authentication-plugin=mysql_native_password
restart: always
environment:
MYSQL_ROOT_PASSWORD: testpassword
healthcheck:
test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost"]
interval: 10s
timeout: 20s
retries: 5
postgres:
image: postgres:11
restart: always
environment:
POSTGRES_PASSWORD: testpassword
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
timeout: 5s
retries: 5
db2:
build: docker/db2
restart: always
environment:
DB2INST1_PASSWORD: testpassword
LICENSE: accept
command: db2start && sleep infinity
1 change: 1 addition & 0 deletions docker/db2-ld.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/opt/ibm/clidriver/lib
14 changes: 14 additions & 0 deletions docker/db2/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
FROM ibmcom/db2express-c:latest

RUN yum makecache fast && yum install -y expect

SHELL ["/bin/bash", "-l", "-c"]
COPY create_databases.sh /
# Bake the Octopus databases into the DB2 image,
# since they take a very long time to create.
# NOTE: this is the only way to properly source
# the db2 profile environment to use the
# DB2 CLI command line.
RUN su - db2inst1 -c /create_databases.sh

CMD db2start && sleep infinity
9 changes: 9 additions & 0 deletions docker/db2/create_databases.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/bin/bash
set -e
source /home/db2inst1/sqllib/db2profile
db2start
echo "Creating databases, this may take around 6 - 8 minutes per database..."
for db in octopus6 octopus7 octopus8 octopus9; do
echo "create databse $db"
time db2 create database $db
done
9 changes: 9 additions & 0 deletions docker/db2dsdriver.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<configuration>
<databases>
<database host="db2" name="OCTOPUS6" port="50000"/>
</databases>
<dsncollection>
<dsn alias="OCTOPUS6" host="db2" name="OCTOPUS6" port="50000"/>
</dsncollection>
</configuration>
45 changes: 45 additions & 0 deletions docker/startup.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#!/bin/bash

set -e

# Wait for our two databases to startup
# (docker-compose v3 removes the health check stuff)
until PGPASSWORD=$POSTGRES_PASSWORD psql -h "$POSTGRES_HOST" -U "$POSTGRES_USER" -c '\q'; do
>&2 echo "Postgres is unavailable - sleeping"
sleep 10
done

>&2 echo "Postgres is ready"

until mysqladmin -u$MYSQL_USER -h $MYSQL_HOST -p$MYSQL_PASSWORD ping; do
>&2 echo "MySQL is unavailable - sleeping"
sleep 10
done

>&2 echo "MySQL is ready"

echo /opt/ibm/clidriver/bin/db2cli validate -database $DB2_DATABASE:$DB2_HOST:$DB2_PORT -connect -user $DB2_USER -passwd $DB2_PASSWORD

until ! /opt/ibm/clidriver/bin/db2cli validate -database $DB2_DATABASE:$DB2_HOST:$DB2_PORT -connect -user $DB2_USER -passwd $DB2_PASSWORD | grep -q FAILED ; do
>&2 echo "DB2 is unavailable - sleeping"
sleep 10
done

>&2 echo "DB2 is ready"

set -x
cd /usr/src/app
bundle install --path=.bundle
bundle exec appraisal install

# The db migration only works on rails 5.0.
# See bug https://github.com/ibmdb/ruby-ibmdb/issues/31
bundle exec appraisal rails50_db2 rake db:prepare

# Run the full spec across all rails versions.
# (This takes a while)
bundle exec rake appraisal spec

set +x
echo Octopus is ready for you. Run \"docker-compose exec octopus /bin/bash\"
/bin/sleep infinity
2 changes: 1 addition & 1 deletion gemfiles/rails42.gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@
source "https://rubygems.org"

gem "activerecord", "~> 4.2.0"
gem "mysql2", "0.4.10"

gemspec path: "../"
8 changes: 8 additions & 0 deletions gemfiles/rails42_db2.gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# This file was generated by Appraisal

source "https://rubygems.org"

gem "activerecord", "~> 4.2.0"
gem "ibm_db", "~> 3.0.5"

gemspec path: "../"
1 change: 1 addition & 0 deletions gemfiles/rails5.gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@
source "https://rubygems.org"

gem "activerecord", "~> 5.0.0"
gem "ibm_db", path: "/usr/src/ruby-ibmdb/IBM_DB_Adapter/ibm_db"

gemspec path: "../"
7 changes: 7 additions & 0 deletions gemfiles/rails50.gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# This file was generated by Appraisal

source "https://rubygems.org"

gem "activerecord", "~> 5.0.0"

gemspec path: "../"
8 changes: 8 additions & 0 deletions gemfiles/rails50_db2.gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# This file was generated by Appraisal

source "https://rubygems.org"

gem "activerecord", "~> 5.0.0"
gem "ibm_db", git: "https://github.com/calh/ruby-ibmdb.git", branch: "v4.0.1", glob: "IBM_DB_Adapter/ibm_db/IBM_DB.gemspec"

gemspec path: "../"
Loading