vagrant-mongodb 0.0.3 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +45 -19
- data/lib/vagrant-mongodb.rb +3 -1
- data/lib/vagrant-mongodb/actions/initiate.rb +134 -0
- data/lib/vagrant-mongodb/commands.rb +21 -0
- data/lib/vagrant-mongodb/commands/initiate.rb +42 -0
- data/lib/vagrant-mongodb/config.rb +34 -9
- data/lib/vagrant-mongodb/errors.rb +1 -1
- data/lib/vagrant-mongodb/plugin.rb +11 -43
- data/lib/vagrant-mongodb/version.rb +1 -1
- data/locales/en.yml +5 -4
- data/test/test.sh +0 -2
- data/vagrant-mongodb.gemspec +4 -1
- metadata +10 -6
- data/lib/vagrant-mongodb/actions/replset_initiate.rb +0 -112
- data/lib/vagrant-mongodb/helpers/translator.rb +0 -20
data/README.md
CHANGED
@@ -1,29 +1,33 @@
|
|
1
1
|
Vagrant MongoDb
|
2
2
|
===============
|
3
|
-
`vagrant-mongodb` is a Vagrant 1.1
|
3
|
+
`vagrant-mongodb` is a Vagrant 1.1 plugin that supports the configuration
|
4
4
|
and initiation of a MongoDb replica set. The longer-term goal is to support
|
5
5
|
various MongoDb administrative tasks.
|
6
6
|
|
7
|
-
Status
|
8
|
-
------
|
9
7
|
The current implementation is a proof-of-concept supporting the larger
|
10
8
|
objective of using Vagrant as a cloud management interface for development
|
11
9
|
and production environments.
|
12
10
|
|
13
|
-
The plugin
|
11
|
+
The plugin communicates with the replica set members over SSH using the
|
12
|
+
`mongo` command.
|
14
13
|
|
15
|
-
|
16
|
-
|
14
|
+
The plugin has been tested with Vagrant 1.1.5 and a Ubuntu 12.04 guest.
|
15
|
+
|
16
|
+
Install
|
17
|
+
-------
|
17
18
|
Install the plugin following the typical Vagrant 1.1 procedure:
|
18
19
|
|
19
|
-
vagrant plugin install vagrant-mongodb
|
20
|
+
$ vagrant plugin install vagrant-mongodb
|
20
21
|
|
21
|
-
|
22
|
-
|
22
|
+
Configure
|
23
|
+
---------
|
23
24
|
The MongoDb replica set must be configured within the project's `Vagrantfile`:
|
24
25
|
|
25
26
|
```ruby
|
27
|
+
config.mongodb.auto_initiate = false
|
28
|
+
|
26
29
|
config.mongodb.replset :rs0 do |rs|
|
30
|
+
rs.ignore_private_ip = false
|
27
31
|
rs.member :server1, :priority => 1
|
28
32
|
rs.member :server2, :priority => 2
|
29
33
|
rs.member :server3, :priority => 1
|
@@ -31,21 +35,43 @@ end
|
|
31
35
|
```
|
32
36
|
|
33
37
|
The first argument to `rs.member` is the machine name defined within the
|
34
|
-
configuration. The second argument is optional
|
38
|
+
configuration. The second argument is optional accepting a hash of options
|
35
39
|
for the replica set member. These options are defined within MongoDb's
|
36
40
|
[replica set configuration reference][1].
|
37
41
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
+
By default, the plugin will lookup and use a static IP address for a
|
43
|
+
member machine if a private network is specified. To disable this, set
|
44
|
+
the replica set attribute, `ignore_private_ip`, to false.
|
45
|
+
|
46
|
+
To disable the plugin hooks and initiate a replica set manually, set the
|
47
|
+
`auto_initiate` attribute to false.
|
48
|
+
|
49
|
+
*NOTE*: The plugin does not support configuration defined within a
|
50
|
+
multi-machine `define` block.
|
51
|
+
|
52
|
+
Run
|
53
|
+
---
|
54
|
+
By default, the plugin hooks into the `vagrant up` and `vagrant provision`
|
55
|
+
commands. It will detect when a replica set's members are available and
|
56
|
+
and call initiate.
|
57
|
+
|
58
|
+
To manually initiate a replica set, invoke the following sub-command:
|
59
|
+
|
60
|
+
$ vagrant mongodb initiate db0 --provider <provider>
|
61
|
+
|
62
|
+
`db0` is a machine defined within the `Vagrantfile` belonging to a
|
63
|
+
replica set that will be initiated. The provider may be specified to
|
64
|
+
initiate a replica set not backed by VirtualBox.
|
42
65
|
|
43
66
|
Contribute
|
44
67
|
----------
|
45
68
|
Contributions are welcome.
|
46
69
|
|
47
|
-
1. Fork
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
70
|
+
1. Fork the project
|
71
|
+
1. Clone the forked repository
|
72
|
+
1. Install project dependencies (`bundle install`)
|
73
|
+
1. Confirm tests pass (`bundle exec rake test`)
|
74
|
+
1. Create your feature branch (`git checkout -b my-new-feature`)
|
75
|
+
1. Commit your changes (`git commit -am 'Add some feature'`)
|
76
|
+
1. Push to the branch (`git push origin my-new-feature`)
|
77
|
+
1. Create new Pull Request
|
data/lib/vagrant-mongodb.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
require 'vagrant'
|
2
1
|
require 'vagrant-mongodb/version'
|
3
2
|
require 'vagrant-mongodb/plugin'
|
4
3
|
require 'vagrant-mongodb/errors'
|
@@ -8,5 +7,8 @@ module VagrantPlugins
|
|
8
7
|
def self.source_root
|
9
8
|
@source_root ||= Pathname.new(File.expand_path('../../', __FILE__))
|
10
9
|
end
|
10
|
+
|
11
|
+
I18n.load_path << File.expand_path('locales/en.yml', source_root)
|
12
|
+
I18n.reload!
|
11
13
|
end
|
12
14
|
end
|
@@ -0,0 +1,134 @@
|
|
1
|
+
module VagrantPlugins
|
2
|
+
module MongoDb
|
3
|
+
module Actions
|
4
|
+
class Initiate
|
5
|
+
include Vagrant::Util::Retryable
|
6
|
+
|
7
|
+
def initialize(app, env)
|
8
|
+
@app = app
|
9
|
+
@machine = env[:machine]
|
10
|
+
@rs = replica_set
|
11
|
+
@logger = Log4r::Logger.new('vagrant::mongodb::initiate')
|
12
|
+
end
|
13
|
+
|
14
|
+
def call(env)
|
15
|
+
@app.call(env)
|
16
|
+
|
17
|
+
# check if machine belongs to a configured replica set
|
18
|
+
return unless @rs
|
19
|
+
|
20
|
+
# check if auto initiate is enabled
|
21
|
+
return unless @machine.config.mongodb.auto_initiate
|
22
|
+
|
23
|
+
# check if the replica set is already initiated
|
24
|
+
if initiated?
|
25
|
+
env[:ui].info I18n.t('vagrant_mongodb.info.initiated', {
|
26
|
+
:name => @rs.name
|
27
|
+
})
|
28
|
+
return
|
29
|
+
end
|
30
|
+
|
31
|
+
env[:ui].info I18n.t('vagrant_mongodb.info.checking', {
|
32
|
+
:name => @rs.name
|
33
|
+
})
|
34
|
+
|
35
|
+
if all_members_available?
|
36
|
+
env[:ui].info I18n.t('vagrant_mongodb.info.initiating', {
|
37
|
+
:name => @rs.name
|
38
|
+
})
|
39
|
+
|
40
|
+
# execute rs.initiate() on first replica set member
|
41
|
+
command = "mongo --eval 'printjson(rs.initiate(#{generate_json}))'"
|
42
|
+
@machine.communicate.execute(command) do |type, data|
|
43
|
+
raise Errors::InitiateError if data =~ /"ok" : 0/
|
44
|
+
end
|
45
|
+
|
46
|
+
# wait until the replica set is initiated
|
47
|
+
retryable(:tries => 6, :sleep => 30) do
|
48
|
+
raise 'not ready' if !initiated?
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
# return the replset the machine is a member of
|
56
|
+
def replica_set
|
57
|
+
return nil if @machine.config.mongodb.nil?
|
58
|
+
|
59
|
+
@machine.config.mongodb.replsets.find do |rs|
|
60
|
+
rs.members.find do |member|
|
61
|
+
member[:host] == @machine.name
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
# check if the replica set has already been initiated
|
67
|
+
def initiated?
|
68
|
+
@logger.info "Checking if '#{@rs.name}' has already been initiated"
|
69
|
+
command = "mongo --eval 'printjson(rs.status())'"
|
70
|
+
@machine.communicate.execute(command) do |type, data|
|
71
|
+
return true if data =~ /"ok" : 1/
|
72
|
+
end
|
73
|
+
|
74
|
+
false
|
75
|
+
rescue Vagrant::Errors::VagrantError
|
76
|
+
false
|
77
|
+
end
|
78
|
+
|
79
|
+
# check if the given machine has mongod running
|
80
|
+
def member_available?(machine)
|
81
|
+
@logger.info "Checking if '#{machine.name}' mongod is available"
|
82
|
+
return false if !machine.communicate.ready?
|
83
|
+
|
84
|
+
# try executing the mongo command on the machine several times
|
85
|
+
# to allow for a process to start after provisioning
|
86
|
+
command = 'mongo --eval "db.runCommand({ ping: 1 })"'
|
87
|
+
retryable(:tries => 3, :sleep => 10) do
|
88
|
+
machine.communicate.execute(command)
|
89
|
+
@logger.info "'#{machine.name}' mongod is available"
|
90
|
+
end
|
91
|
+
true
|
92
|
+
rescue
|
93
|
+
false
|
94
|
+
end
|
95
|
+
|
96
|
+
# check if all members of the replica set have mongod running
|
97
|
+
def all_members_available?
|
98
|
+
@rs.members.each do |member|
|
99
|
+
machine = @machine.env.machine(member[:host], @machine.provider_name)
|
100
|
+
return false if !member_available?(machine)
|
101
|
+
end
|
102
|
+
true
|
103
|
+
end
|
104
|
+
|
105
|
+
# generate replica set JSON document replacing host name with ip
|
106
|
+
def generate_json
|
107
|
+
members = []
|
108
|
+
@rs.members.each do |member|
|
109
|
+
machine = @machine.env.machine(member[:host], @machine.provider_name)
|
110
|
+
copy = member.dup
|
111
|
+
copy[:host] = get_ip_address(machine)
|
112
|
+
members << copy
|
113
|
+
end
|
114
|
+
|
115
|
+
{ :_id => @rs.name, :members => members }.to_json
|
116
|
+
end
|
117
|
+
|
118
|
+
# return the ip address of the given machine
|
119
|
+
def get_ip_address(machine)
|
120
|
+
ip = nil
|
121
|
+
unless @rs.ignore_private_ip
|
122
|
+
machine.config.vm.networks.each do |network|
|
123
|
+
key, options = network[0], network[1]
|
124
|
+
ip = options[:ip] if key == :private_network
|
125
|
+
next if ip
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
ip || machine.ssh_info[:host]
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module VagrantPlugins
|
2
|
+
module MongoDb
|
3
|
+
module Commands
|
4
|
+
class Commands < Vagrant.plugin('2', :command)
|
5
|
+
def initialize(argv, env)
|
6
|
+
super
|
7
|
+
@main_args, @sub_command, @sub_args = split_main_and_subcommand(argv)
|
8
|
+
end
|
9
|
+
|
10
|
+
# TODO refactor to lookup generic commands
|
11
|
+
# TODO display help if no sub command is provided
|
12
|
+
def execute
|
13
|
+
return if @sub_command.downcase != 'initiate'
|
14
|
+
|
15
|
+
require_relative 'commands/initiate'
|
16
|
+
Initiate.new(@sub_args, @env).execute
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module VagrantPlugins
|
2
|
+
module MongoDb
|
3
|
+
module Commands
|
4
|
+
class Initiate < Vagrant.plugin('2', :command)
|
5
|
+
|
6
|
+
def execute
|
7
|
+
options = {}
|
8
|
+
opts = OptionParser.new do |o|
|
9
|
+
o.banner = 'Usage: vagrant mongodb initiate [vm-name]'
|
10
|
+
o.separator ''
|
11
|
+
|
12
|
+
o.on('--provider provider', String,
|
13
|
+
'Initiates replica set with the specific provider.') do |provider|
|
14
|
+
options[:provider] = provider
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
argv = parse_options(opts)
|
19
|
+
options[:provider] ||= @env.default_provider
|
20
|
+
options[:single_target] = true
|
21
|
+
|
22
|
+
with_target_vms(argv, options) do |machine|
|
23
|
+
|
24
|
+
if machine.config.mongodb
|
25
|
+
machine.config.mongodb.auto_initiate = true
|
26
|
+
|
27
|
+
env = { :machine => machine, :ui => @env.ui }
|
28
|
+
callable = Vagrant::Action::Builder.new.tap do |b|
|
29
|
+
b.use Vagrant::Action::Builtin::ConfigValidate
|
30
|
+
b.use Actions::Initiate
|
31
|
+
end
|
32
|
+
|
33
|
+
@env.action_runner.run(callable, env)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
0
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -2,27 +2,46 @@ module VagrantPlugins
|
|
2
2
|
module MongoDb
|
3
3
|
class Config < Vagrant.plugin('2', :config)
|
4
4
|
attr_reader :replsets
|
5
|
+
attr_accessor :auto_initiate
|
5
6
|
|
6
7
|
def initialize
|
7
8
|
@replsets = []
|
8
|
-
@
|
9
|
+
@auto_initiate = UNSET_VALUE
|
9
10
|
end
|
10
11
|
|
11
|
-
#
|
12
|
-
# TODO look into merge strategy
|
12
|
+
# TODO look into appropriate merge strategy
|
13
13
|
def merge(other)
|
14
|
-
|
14
|
+
# other.replsets.each do |o|
|
15
|
+
# rs = @replsets.find { |r| r.name == o.name }
|
16
|
+
# if rs
|
17
|
+
# o.members.each do |member|
|
18
|
+
# rs.member member[:host], member
|
19
|
+
# end
|
20
|
+
# else
|
21
|
+
# @replsets << other
|
22
|
+
# end
|
23
|
+
# end
|
24
|
+
|
25
|
+
# self
|
26
|
+
end
|
27
|
+
|
28
|
+
def finalize!
|
29
|
+
@auto_initiate = true if @auto_initiate == UNSET_VALUE
|
15
30
|
end
|
16
31
|
|
17
32
|
def validate(machine)
|
18
33
|
errors = []
|
19
34
|
@replsets.each do |rs|
|
20
35
|
if rs.members.size < 3
|
21
|
-
errors <<
|
36
|
+
errors << I18n.t('vagrant_mongodb.config.replica_set_size', {
|
37
|
+
:name => rs.name
|
38
|
+
})
|
22
39
|
end
|
23
40
|
rs.members.each do |m|
|
24
41
|
if !machine.env.machine_names.find { |name| name == m[:host] }
|
25
|
-
errors <<
|
42
|
+
errors << I18n.t('vagrant_mongodb.config.unknown_member', {
|
43
|
+
:member => m[:host]
|
44
|
+
})
|
26
45
|
end
|
27
46
|
end
|
28
47
|
end
|
@@ -33,27 +52,33 @@ module VagrantPlugins
|
|
33
52
|
def replset(name, &block)
|
34
53
|
rs = @replsets.find { |r| r.name == name.to_sym }
|
35
54
|
if !rs
|
36
|
-
rs =
|
55
|
+
rs = ReplicaSet.new(name)
|
37
56
|
@replsets << rs
|
38
57
|
end
|
39
58
|
block.call(rs)
|
40
59
|
end
|
41
60
|
|
42
|
-
class
|
61
|
+
class ReplicaSet
|
43
62
|
attr_reader :name
|
44
63
|
attr_reader :members
|
64
|
+
attr_accessor :ignore_private_ip
|
45
65
|
|
46
66
|
def initialize(name)
|
47
67
|
@name = name.to_sym
|
48
68
|
@members = []
|
69
|
+
@ignore_private_ip = false
|
49
70
|
end
|
50
71
|
|
51
72
|
def member(name, options = {})
|
52
73
|
member = @members.find { |m| m[:host] == name.to_sym }
|
53
74
|
if member
|
75
|
+
options.delete(:_id)
|
54
76
|
member.merge!(options)
|
55
77
|
else
|
56
|
-
@members << options.merge({
|
78
|
+
@members << options.merge({
|
79
|
+
:_id => @members.size,
|
80
|
+
:host => name.to_sym
|
81
|
+
})
|
57
82
|
end
|
58
83
|
end
|
59
84
|
end
|
@@ -1,18 +1,16 @@
|
|
1
|
-
require 'vagrant-mongodb/
|
2
|
-
require 'vagrant-mongodb/actions/replset_initiate'
|
1
|
+
require 'vagrant-mongodb/actions/initiate'
|
3
2
|
|
4
3
|
module VagrantPlugins
|
5
4
|
module MongoDb
|
6
5
|
class Plugin < Vagrant.plugin('2')
|
7
6
|
name 'MongoDb'
|
8
7
|
description <<-DESC
|
9
|
-
|
8
|
+
A Vagrant plugin that supports the configuration and initation
|
9
|
+
of a MongoDb replica set.
|
10
10
|
DESC
|
11
11
|
|
12
|
-
def self.
|
13
|
-
|
14
|
-
setup_i18n
|
15
|
-
hook.before(Vagrant::Action::Builtin::Provision, Actions::ReplSetInitiate)
|
12
|
+
def self.initiate(hook)
|
13
|
+
hook.prepend(Actions::Initiate)
|
16
14
|
end
|
17
15
|
|
18
16
|
config(:mongodb) do
|
@@ -20,44 +18,14 @@ module VagrantPlugins
|
|
20
18
|
Config
|
21
19
|
end
|
22
20
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
def self.setup_i18n
|
28
|
-
I18n.load_path << File.expand_path(
|
29
|
-
'locales/en.yml',
|
30
|
-
MongoDb.source_root)
|
31
|
-
I18n.reload!
|
32
|
-
|
33
|
-
Helpers::Translator.plugin_namespace = 'vagrant_mongodb'
|
21
|
+
command(:mongodb) do
|
22
|
+
require_relative 'commands'
|
23
|
+
Commands::Commands
|
34
24
|
end
|
35
25
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
level = Log4r.const_get(ENV['VAGRANT_LOG'].upcase)
|
40
|
-
rescue NameError
|
41
|
-
# This means that the logging constant wasn't found,
|
42
|
-
# which is fine. We just keep `level` as `nil`. But
|
43
|
-
# we tell the user.
|
44
|
-
level = nil
|
45
|
-
end
|
46
|
-
|
47
|
-
# Some constants, such as "true" resolve to booleans, so the
|
48
|
-
# above error checking doesn't catch it. This will check to make
|
49
|
-
# sure that the log level is an integer, as Log4r requires.
|
50
|
-
level = nil if !level.is_a?(Integer)
|
51
|
-
|
52
|
-
# Set the logging level on all "vagrant" namespaced
|
53
|
-
# logs as long as we have a valid level.
|
54
|
-
if level
|
55
|
-
logger = Log4r::Logger.new('vagrant_mongodb')
|
56
|
-
logger.outputters = Log4r::Outputter.stderr
|
57
|
-
logger.level = level
|
58
|
-
logger = nil
|
59
|
-
end
|
60
|
-
end
|
26
|
+
# initiate replica set after machine provisioning
|
27
|
+
action_hook(:mongodb, :machine_action_provision, &method(:initiate))
|
28
|
+
action_hook(:mongodb, :machine_action_up, &method(:initiate))
|
61
29
|
end
|
62
30
|
end
|
63
31
|
end
|
data/locales/en.yml
CHANGED
@@ -3,8 +3,9 @@ en:
|
|
3
3
|
errors:
|
4
4
|
initiate: "Failed to initiate replica set"
|
5
5
|
config:
|
6
|
-
|
6
|
+
replica_set_size: "'%{name}' replica set requires a minimum of 3 members"
|
7
7
|
unknown_member: "'%{member}' member is not defined"
|
8
|
-
|
9
|
-
|
10
|
-
|
8
|
+
info:
|
9
|
+
checking: "Checking if replica set '%{name}' is ready..."
|
10
|
+
initiating: "Initiating replica set '%{name}'..."
|
11
|
+
initiated: "Replica set '%{name}' already initiated."
|
data/test/test.sh
CHANGED
data/vagrant-mongodb.gemspec
CHANGED
@@ -8,7 +8,10 @@ Gem::Specification.new do |gem|
|
|
8
8
|
gem.version = VagrantPlugins::MongoDb::VERSION
|
9
9
|
gem.authors = ['Shawn Dahlen']
|
10
10
|
gem.email = ['shawn@dahlen.me']
|
11
|
-
gem.description =
|
11
|
+
gem.description = <<-DESC
|
12
|
+
A Vagrant plugin that supports the configuration
|
13
|
+
and initation of a MongoDb replica set.
|
14
|
+
DESC
|
12
15
|
gem.homepage = 'https://github.com/smdahlen/vagrant-mongodb'
|
13
16
|
gem.summary = gem.description
|
14
17
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vagrant-mongodb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,9 +9,10 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-04-
|
12
|
+
date: 2013-04-12 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
|
-
description: A Vagrant plugin that
|
14
|
+
description: ! " A Vagrant plugin that supports the configuration\n
|
15
|
+
\ and initation of a MongoDb replica set.\n"
|
15
16
|
email:
|
16
17
|
- shawn@dahlen.me
|
17
18
|
executables: []
|
@@ -24,10 +25,11 @@ files:
|
|
24
25
|
- README.md
|
25
26
|
- Rakefile
|
26
27
|
- lib/vagrant-mongodb.rb
|
27
|
-
- lib/vagrant-mongodb/actions/
|
28
|
+
- lib/vagrant-mongodb/actions/initiate.rb
|
29
|
+
- lib/vagrant-mongodb/commands.rb
|
30
|
+
- lib/vagrant-mongodb/commands/initiate.rb
|
28
31
|
- lib/vagrant-mongodb/config.rb
|
29
32
|
- lib/vagrant-mongodb/errors.rb
|
30
|
-
- lib/vagrant-mongodb/helpers/translator.rb
|
31
33
|
- lib/vagrant-mongodb/plugin.rb
|
32
34
|
- lib/vagrant-mongodb/version.rb
|
33
35
|
- locales/en.yml
|
@@ -57,7 +59,9 @@ rubyforge_project:
|
|
57
59
|
rubygems_version: 1.8.23
|
58
60
|
signing_key:
|
59
61
|
specification_version: 3
|
60
|
-
summary: A Vagrant plugin that
|
62
|
+
summary: A Vagrant plugin that supports the configuration and initation of a MongoDb
|
63
|
+
replica set.
|
61
64
|
test_files:
|
62
65
|
- test/Vagrantfile
|
63
66
|
- test/test.sh
|
67
|
+
has_rdoc:
|
@@ -1,112 +0,0 @@
|
|
1
|
-
module VagrantPlugins
|
2
|
-
module MongoDb
|
3
|
-
module Actions
|
4
|
-
class ReplSetInitiate
|
5
|
-
include Vagrant::Util::Retryable
|
6
|
-
|
7
|
-
def initialize(app, env)
|
8
|
-
@app = app
|
9
|
-
@config = env[:global_config].mongodb
|
10
|
-
@machine = env[:machine]
|
11
|
-
@translator = Helpers::Translator.new('actions.replset_initiate')
|
12
|
-
@logger = Log4r::Logger.new('vagrant_mongodb::actions::replset_initiate')
|
13
|
-
end
|
14
|
-
|
15
|
-
def call(env)
|
16
|
-
@app.call(env)
|
17
|
-
|
18
|
-
# check if the current machine is a member of a replica set and the
|
19
|
-
# replica set has not already been initiated
|
20
|
-
@logger.info "Checking if '#{@machine.name}' is part of a replica set..."
|
21
|
-
rs = get_replset(@machine.name) if @config
|
22
|
-
return if !rs or already_initiated?(rs)
|
23
|
-
|
24
|
-
# ensure all members are available before initiating replica set
|
25
|
-
if all_members_available?(rs)
|
26
|
-
env[:ui].info @translator.t('initiate', { :name => rs.name })
|
27
|
-
command = "mongo --eval 'printjson(rs.initiate(#{generate_json(rs)}))'"
|
28
|
-
@machine.communicate.execute(command) do |type, data|
|
29
|
-
raise Errors::ReplSetInitiateError if data =~ /"ok" : 0/
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
private
|
35
|
-
|
36
|
-
# return the replset containing the machine name
|
37
|
-
def get_replset(name)
|
38
|
-
@config.replsets.find do |rs|
|
39
|
-
rs.members.find do |member|
|
40
|
-
member[:host] == name
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
# check if the given machine has mongod running
|
46
|
-
def member_available?(machine)
|
47
|
-
@logger.info "Checking if '#{machine.name}' mongod is available..."
|
48
|
-
return false if !machine.communicate.ready?
|
49
|
-
|
50
|
-
# try executing the mongo command on the machine several times
|
51
|
-
# to allow for a process to start after provisioning
|
52
|
-
command = 'mongo --eval "db.runCommand({ ping: 1 })"'
|
53
|
-
retryable(:tries => 3, :sleep => 10) do
|
54
|
-
machine.communicate.execute(command)
|
55
|
-
@logger.info "'#{machine.name}' mongod is available..."
|
56
|
-
end
|
57
|
-
true
|
58
|
-
rescue
|
59
|
-
false
|
60
|
-
end
|
61
|
-
|
62
|
-
# check if all members of the replica set have mongod running
|
63
|
-
def all_members_available?(rs)
|
64
|
-
global_env = @machine.env
|
65
|
-
rs.members.each do |member|
|
66
|
-
machine = global_env.machine(member[:host], @machine.provider_name)
|
67
|
-
return false if !member_available?(machine)
|
68
|
-
end
|
69
|
-
true
|
70
|
-
end
|
71
|
-
|
72
|
-
# generate replica set JSON document replacing host name with ip
|
73
|
-
def generate_json(rs)
|
74
|
-
global_env = @machine.env
|
75
|
-
members = rs.members.dup
|
76
|
-
members.each do |member|
|
77
|
-
machine = global_env.machine(member[:host], @machine.provider_name)
|
78
|
-
member[:host] = get_ip_address(machine)
|
79
|
-
@logger.info "Using ip address '#{member[:host]}' for '#{@machine.name}'..."
|
80
|
-
end
|
81
|
-
|
82
|
-
{ :_id => rs.name, :members => members }.to_json
|
83
|
-
end
|
84
|
-
|
85
|
-
# return the ip address of the given machine
|
86
|
-
def get_ip_address(machine)
|
87
|
-
ip = nil
|
88
|
-
machine.config.vm.networks.each do |network|
|
89
|
-
key, options = network[0], network[1]
|
90
|
-
ip = options[:ip] if key == :private_network
|
91
|
-
next if ip
|
92
|
-
end
|
93
|
-
|
94
|
-
ip || machine.ssh_info[:host]
|
95
|
-
end
|
96
|
-
|
97
|
-
# check if the replica set has already been initiated
|
98
|
-
def already_initiated?(rs)
|
99
|
-
@logger.info "Checking if '#{rs.name}' has already been initiated..."
|
100
|
-
command = "mongo --eval 'printjson(rs.status())'"
|
101
|
-
begin
|
102
|
-
@machine.communicate.execute(command) do |type, data|
|
103
|
-
return true if data =~ /"ok" : 1/
|
104
|
-
end
|
105
|
-
rescue Vagrant::Errors::VagrantError
|
106
|
-
end
|
107
|
-
false
|
108
|
-
end
|
109
|
-
end
|
110
|
-
end
|
111
|
-
end
|
112
|
-
end
|
@@ -1,20 +0,0 @@
|
|
1
|
-
module VagrantPlugins
|
2
|
-
module MongoDb
|
3
|
-
module Helpers
|
4
|
-
class Translator
|
5
|
-
def self.plugin_namespace=(val)
|
6
|
-
@@plugin_namespace = val
|
7
|
-
end
|
8
|
-
|
9
|
-
def initialize(namespace)
|
10
|
-
@namespace = namespace
|
11
|
-
end
|
12
|
-
|
13
|
-
def t(keys, opts = {})
|
14
|
-
value = I18n.t("#{@@plugin_namespace}.#{@namespace}.#{keys}", opts)
|
15
|
-
opts[:progress] == false ? value : value + "..."
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|