vagrant-mongodb 0.0.3 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|