├── .gitignore ├── README.md ├── Vagrantfile ├── puppet ├── manifests │ └── mongo.pp └── modules │ ├── hosts │ └── manifests │ │ └── .directory │ └── mongodb │ ├── manifests │ ├── configure.pp │ └── init.pp │ └── templates │ ├── mongodb.conf.erb │ ├── mongodb.key.erb │ ├── mongodb.upstart.conf.erb │ └── mongodb.upstart.default.erb └── vagrant-mongo └── lib ├── vagrant-mongo.rb ├── vagrant-mongo ├── command.rb ├── config.rb ├── configure.rb ├── facter.rb ├── middleware.rb └── version.rb └── vagrant_init.rb /.gitignore: -------------------------------------------------------------------------------- 1 | .vagrant 2 | puppet/modules/hosts/manifests/generated.pp 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Vagrant plugin and puppet manifests for MongoDB 2 | =============================================== 3 | 4 | Creates (by default) 8 virtual machines based on Ubuntu Lucid (64bits). 5 | 6 | * 1x ReplicaSet (primary, secondary, arbiter) without authentication. 7 | * 1x ReplicaSet (primary, secondary, arbiter) with authentication. 8 | * 1x Standalone server without authentication. 9 | * 1x Standalone server with authentication. 10 | 11 | The ReplicaSet servers will have their _/etc/hosts_ synchronized among them. 12 | 13 | All servers will retrieve and install the latest MongoDB from the official 10gen repository. 14 | 15 | Several new Vagrant configurations are available in the _Vagrantfile_ 16 | to configure a MongoDB replicaset, such as the servers priority to become primaries. 17 | 18 | A new Vagrant comand is availalbe to initialize the replicaset based on 19 | the configuration in the _Vagrantfile_, and to create users for authenticated setup. 20 | 21 | 22 | Usage 23 | ----- 24 | $ git clone https://github.com/bjori/vagrant-mongodb.git 25 | $ cd vagrant-mongodb 26 | 27 | Boot up *all* servers 28 | 29 | $ vagrant up # Will bootup *all 8 servers* 30 | 31 | Or only bootup a normal ReplicaSet 32 | 33 | $ vagrant up primary secondary tertiary # Will bootup only one ReplicaSet 34 | 35 | To bootup ReplicaSet with authentication enabled 36 | 37 | $ vagrant up primaryauth secondaryauth tertiaryauth # RS with auth 38 | 39 | Don't want ReplicaSets? This will create a standalone MongoDB server 40 | 41 | $ vagrant up standalone # Will bootup the standalone server 42 | 43 | And this will create a standalone MongoDB server with authentication enabled 44 | 45 | $ vagrant up standaloneauth # Standalone with auth 46 | 47 | 48 | Initializing ReplicaSets 49 | ------------------------ 50 | To initialize the ReplicaSet for the first time, type 51 | 52 | $ vagrant mongo primary --init-replicaset 53 | 54 | and/or 55 | 56 | $ vagrant mongo primaryauth --init-replicaset 57 | 58 | To initialize the ReplicaSet for the authenticated environment. 59 | 60 | 61 | Creating users 62 | -------------- 63 | 64 | To create a first time admin user on a standalone server run 65 | 66 | $ vagrant mongo standaloneauth -c -u adm -p pass --db admin 67 | 68 | or for ReplicaSet environment 69 | 70 | $ vagrant mongo primaryauth -c -u adm -p pass --db admin 71 | 72 | To create more users you have to authenticate using that admin user 73 | 74 | $ vagrant mongo standaloneauth -c -u user -p mypass --db mydb --authuser adm --authpass pass --authdb admin 75 | 76 | 77 | /etc/hosts 78 | ---------- 79 | 80 | The ReplicaSets are configured using the hostnames defined in the _Vagrantfile_. 81 | I recommend you add all these hosts to your local _/etc/hosts_ (the servers themselves already have). 82 | 83 | By default the following hostnames and IPs are used 84 | 85 | 172.16.1.10 primaryauth.rs.local primaryauth 86 | 172.16.1.11 secondaryauth.rs.local secondaryauth 87 | 172.16.1.12 tertiaryauth.rs.local tertiaryauth 88 | 172.16.2.10 standaloneauth.local standaloneauth 89 | 90 | 172.16.3.10 primary.rs.local primary 91 | 172.16.3.11 secondary.rs.local secondary 92 | 172.16.3.12 tertiary.rs.local tertiary 93 | 172.16.4.10 standalone.local standalone 94 | 95 | 96 | Thats it folks! 97 | --------------- 98 | And there we go! 99 | Now you have a full MongoDB replicaset running in its own virtualized network, 100 | and all of the servers are running on the default ports. 101 | To connect to MongoDB, just fire up your favorite driver and connect :) 102 | 103 | 104 | Fixing my mess? 105 | --------------- 106 | This is the first time I have ever created a puppet module, puppet manifest, vagrant plugin 107 | or written Ruby code at all. 108 | There is very likely something could have been done better or prettier. 109 | I would love it if you forked this repo and applied your skillz cleaning things up. 110 | 111 | Everything should work out of the box though :) 112 | 113 | TODO 114 | ---- 115 | * MongoDB Sharded environment 116 | * mongobride support 117 | * _vagrant mongo_ command to tune mongobridge 118 | * Configuration settings 119 | * Split the _vagrant mongo_ command to simplify creating users 120 | * Automatically initialize ReplicaSets when all RS vms have booted up 121 | 122 | 123 | -------------------------------------------------------------------------------- /Vagrantfile: -------------------------------------------------------------------------------- 1 | # -*- mode: ruby -*- 2 | # vi: set ft=ruby sw=2 : 3 | 4 | require './vagrant-mongo/lib/vagrant_init.rb' 5 | 6 | Vagrant::Config.run do |config| 7 | 8 | ### World wide configure 9 | 10 | # Which base box to use, or fetch if not present 11 | config.vm.box = "replicaset" 12 | config.vm.box_url = "http://files.vagrantup.com/lucid64.box" 13 | 14 | # Use puppet, and the replicaset.pp manifest 15 | config.vm.provision :puppet do |puppet| 16 | puppet.manifests_path = "puppet/manifests" 17 | puppet.manifest_file = "mongo.pp" 18 | puppet.module_path = "puppet/modules" 19 | end 20 | 21 | 22 | ### Per-server configuration 23 | config.vm.define :primaryauth do |primaryauth| 24 | # Configure the hostname and IP 25 | # You should probably update your local /etc/hosts with this info 26 | primaryauth.vm.network :hostonly, "172.16.1.10" 27 | primaryauth.vm.host_name = "primaryauth.rs.local" 28 | 29 | # The ReplicaSet name, and content of the keyfile if we want auth 30 | primaryauth.mongo.rs = "RSAuth" 31 | primaryauth.mongo.auth = "random string" 32 | 33 | # ReplicaSet config entry ID 34 | primaryauth.mongo.id = 0 35 | # The priority of this member to become primaryauth 36 | primaryauth.mongo.priority = 20 37 | 38 | end 39 | 40 | config.vm.define :secondaryauth do |secondaryauth| 41 | secondaryauth.vm.network :hostonly, "172.16.1.11" 42 | secondaryauth.vm.host_name = "secondaryauth.rs.local" 43 | 44 | secondaryauth.mongo.rs = "RSAuth" 45 | secondaryauth.mongo.auth = "random string" 46 | 47 | secondaryauth.mongo.id = 1 48 | secondaryauth.mongo.priority = 10 49 | end 50 | 51 | config.vm.define :tertiaryauth do |tertiaryauth| 52 | tertiaryauth.vm.network :hostonly, "172.16.1.12" 53 | tertiaryauth.vm.host_name = "tertiaryauth.rs.local" 54 | 55 | tertiaryauth.mongo.rs = "RSAuth" 56 | tertiaryauth.mongo.auth = "random string" 57 | 58 | tertiaryauth.mongo.id = 2 59 | # Make this one arbiter 60 | tertiaryauth.mongo.arbiter = true 61 | end 62 | 63 | 64 | config.vm.define :standaloneauth do |standaloneauth| 65 | standaloneauth.vm.network :hostonly, "172.16.2.10" 66 | standaloneauth.vm.host_name = "standaloneauth.local" 67 | 68 | standaloneauth.mongo.auth = "true" 69 | standaloneauth.mongo.id = 42 70 | end 71 | 72 | 73 | ### And now without authentication 74 | config.vm.define :primary do |primary| 75 | primary.vm.network :hostonly, "172.16.3.10" 76 | primary.vm.host_name = "primary.rs.local" 77 | 78 | primary.mongo.rs = "RS" 79 | 80 | primary.mongo.id = 0 81 | primary.mongo.priority = 20 82 | 83 | end 84 | 85 | config.vm.define :secondary do |secondary| 86 | secondary.vm.network :hostonly, "172.16.3.11" 87 | secondary.vm.host_name = "secondary.rs.local" 88 | 89 | secondary.mongo.rs = "RS" 90 | 91 | secondary.mongo.id = 1 92 | secondary.mongo.priority = 10 93 | end 94 | 95 | config.vm.define :tertiary do |tertiary| 96 | tertiary.vm.network :hostonly, "172.16.3.12" 97 | tertiary.vm.host_name = "tertiary.rs.local" 98 | 99 | tertiary.mongo.rs = "RS" 100 | 101 | tertiary.mongo.id = 2 102 | tertiary.mongo.arbiter = true 103 | end 104 | 105 | 106 | config.vm.define :standalone do |standalone| 107 | standalone.vm.network :hostonly, "172.16.4.10" 108 | standalone.vm.host_name = "standalone.local" 109 | 110 | standalone.mongo.id = 42 111 | end 112 | 113 | 114 | end 115 | 116 | -------------------------------------------------------------------------------- /puppet/manifests/mongo.pp: -------------------------------------------------------------------------------- 1 | include mongodb 2 | exec { "apt-update": 3 | command => "apt-get update", 4 | path => "/usr/bin" 5 | } 6 | mongodb::configure { $::rs_name: 7 | arbiter => $::rs_arbiter, 8 | useauth => $::mongo_auth, 9 | #rest => true 10 | } 11 | 12 | include hosts::generated 13 | 14 | -------------------------------------------------------------------------------- /puppet/modules/hosts/manifests/.directory: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bjori/vagrant-mongodb/330e8fb27a913c1a047a2b6b8d4b90c7b2c97b55/puppet/modules/hosts/manifests/.directory -------------------------------------------------------------------------------- /puppet/modules/mongodb/manifests/configure.pp: -------------------------------------------------------------------------------- 1 | define mongodb::configure ( 2 | $replicaset = $title, 3 | $arbiter = 'false', 4 | $useauth = 'false', 5 | $rest = '', 6 | $prealloc = '', 7 | $journal = '', 8 | $port = '27017', 9 | $rest = false, 10 | ) { 11 | 12 | include mongodb 13 | 14 | if ($arbiter == 'true') { 15 | if ($journal == '') { 16 | $nojournal = 'true' 17 | } 18 | if ($noprealloc == '') { 19 | $noprealloc = 'true' 20 | } 21 | } else { 22 | if ($journal == '') { 23 | $nojournal = 'false' 24 | } 25 | if ($prealloc == '') { 26 | $noprealloc = 'false' 27 | } 28 | } 29 | 30 | if ($useauth == 'false'){ 31 | $auth = 'false' 32 | if ($replicaset) { 33 | $replSet = $replicaset 34 | } else { 35 | $replSet = false 36 | } 37 | } else { 38 | $auth = 'true' 39 | if ($replicaset) { 40 | $replSet = $replicaset 41 | $keyFile = "/etc/mongodb.key" 42 | } else { 43 | $replSet = false 44 | } 45 | } 46 | 47 | file { '/etc/mongodb.key': 48 | content => template('mongodb/mongodb.key.erb'), 49 | mode => '0600', 50 | owner => 'mongodb', 51 | notify => Service['mongodb'], 52 | require => File['/etc/mongodb.conf'], 53 | } 54 | file { '/etc/mongodb.conf': 55 | content => template('mongodb/mongodb.conf.erb'), 56 | mode => '0644', 57 | notify => Service['mongodb'], 58 | require => File['/etc/default/mongodb'], 59 | } 60 | file { '/etc/default/mongodb': 61 | content => template('mongodb/mongodb.upstart.default.erb'), 62 | mode => '0644', 63 | notify => Service['mongodb'], 64 | require => File['/etc/init/mongodb.conf'], 65 | } 66 | file { '/etc/init/mongodb.conf': 67 | content => template('mongodb/mongodb.upstart.conf.erb'), 68 | mode => '0644', 69 | notify => Service['mongodb'], 70 | require => Package['mongodb-10gen'], 71 | } 72 | } 73 | 74 | -------------------------------------------------------------------------------- /puppet/modules/mongodb/manifests/init.pp: -------------------------------------------------------------------------------- 1 | class mongodb { 2 | package { "python-software-properties": 3 | ensure => installed, 4 | } 5 | 6 | exec { "apt-repo-10gen": 7 | path => "/bin:/usr/bin", 8 | command => "echo 'deb http://downloads-distro.mongodb.org/repo/ubuntu-upstart dist 10gen' >> /etc/apt/sources.list", 9 | unless => "cat /etc/apt/sources.list | grep 10gen", 10 | require => Package["python-software-properties"], 11 | } 12 | 13 | exec { "apt-key-10gen": 14 | path => "/bin:/usr/bin", 15 | command => "apt-key adv --keyserver keyserver.ubuntu.com --recv 7F0CEB10", 16 | unless => "apt-key list | grep 10gen", 17 | require => Exec["apt-repo-10gen"], 18 | } 19 | 20 | exec { "update-apt": 21 | path => "/bin:/usr/bin", 22 | command => "apt-get update", 23 | require => Exec["apt-key-10gen"], 24 | } 25 | 26 | package { "mongodb-10gen": 27 | ensure => installed, 28 | require => Exec["update-apt"], 29 | } 30 | 31 | service { "mongodb": 32 | enable => true, 33 | ensure => running, 34 | require => File['/etc/mongodb.key'], 35 | } 36 | 37 | } 38 | 39 | -------------------------------------------------------------------------------- /puppet/modules/mongodb/templates/mongodb.conf.erb: -------------------------------------------------------------------------------- 1 | # mongodb.conf 2 | 3 | # Where to store the data. 4 | 5 | # Note: if you run mongodb as a non-root user (recommended) you may 6 | # need to create and set permissions for this directory manually, 7 | # e.g., if the parent directory isn't mutable by the mongodb user. 8 | dbpath=/var/lib/mongodb 9 | 10 | #where to log 11 | logpath=/var/log/mongodb/mongodb.log 12 | 13 | logappend=true 14 | 15 | port = <%= port %> 16 | 17 | # Disables write-ahead journaling 18 | nojournal = <%= nojournal %> 19 | 20 | # Enables periodic logging of CPU utilization and I/O wait 21 | #cpu = true 22 | 23 | # Turn on/off security. Off is currently the default 24 | #noauth = true 25 | auth = <%= auth %> 26 | 27 | # Verbose logging output. 28 | #verbose = true 29 | 30 | # Inspect all client data for validity on receipt (useful for 31 | # developing drivers) 32 | #objcheck = true 33 | 34 | # Enable db quota management 35 | #quota = true 36 | 37 | # Set oplogging level where n is 38 | # 0=off (default) 39 | # 1=W 40 | # 2=R 41 | # 3=both 42 | # 7=W+some reads 43 | #diaglog = 0 44 | 45 | # Ignore query hints 46 | #nohints = true 47 | 48 | # Disable the HTTP interface (Defaults to localhost:27018). 49 | #nohttpinterface = true 50 | 51 | # Turns off server-side scripting. This will result in greatly limited 52 | # functionality 53 | #noscripting = true 54 | 55 | # Turns off table scans. Any query that would do a table scan fails. 56 | #notablescan = true 57 | 58 | # Disable data file preallocation. 59 | noprealloc = <%= noprealloc %> 60 | 61 | # Specify .ns file size for new databases. 62 | # nssize = 63 | 64 | # Accout token for Mongo monitoring server. 65 | #mms-token = 66 | 67 | # Server name for Mongo monitoring server. 68 | #mms-name = 69 | 70 | # Ping interval for Mongo monitoring server. 71 | #mms-interval = 72 | 73 | # Replication Options 74 | 75 | # in master/slave replicated mongo databases, specify here whether 76 | # this is a slave or master 77 | #slave = true 78 | #source = master.example.com 79 | # Slave only: specify a single database to replicate 80 | #only = master.example.com 81 | # or 82 | #master = true 83 | #source = slave.example.com 84 | 85 | # in replica set configuration, specify the name of the replica set 86 | # replSet = setname 87 | <% if replSet -%> 88 | replSet = <%=replSet%> 89 | <% if auth != 'false' -%> 90 | keyFile = /etc/mongodb.key 91 | <% end -%> 92 | 93 | <% end -%> 94 | 95 | -------------------------------------------------------------------------------- /puppet/modules/mongodb/templates/mongodb.key.erb: -------------------------------------------------------------------------------- 1 | very secret mongodb key file <%=useauth%> that noone knows the content of 2 | -------------------------------------------------------------------------------- /puppet/modules/mongodb/templates/mongodb.upstart.conf.erb: -------------------------------------------------------------------------------- 1 | # Ubuntu upstart file at /etc/init/mongodb.conf 2 | 3 | limit nofile 20000 20000 4 | 5 | kill timeout 300 # wait 300s between SIGTERM and SIGKILL. 6 | 7 | pre-start script 8 | mkdir -p /var/lib/mongodb/ 9 | mkdir -p /var/log/mongodb/ 10 | end script 11 | 12 | start on runlevel [2345] 13 | stop on runlevel [06] 14 | 15 | script 16 | ENABLE_MONGODB="yes" 17 | if [ -f /etc/default/mongodb ]; then . /etc/default/mongodb; fi 18 | if [ "x$ENABLE_MONGODB" = "xyes" ]; then exec start-stop-daemon --start --quiet --chuid mongodb --exec /usr/bin/mongod -- --config /etc/mongodb.conf $MONGODB_OPTIONS; fi 19 | end script 20 | -------------------------------------------------------------------------------- /puppet/modules/mongodb/templates/mongodb.upstart.default.erb: -------------------------------------------------------------------------------- 1 | 2 | MONGODB_OPTIONS="" 3 | 4 | <% if rest == true -%> 5 | MONGODB_OPTIONS+="--rest " 6 | <% end -%> 7 | 8 | -------------------------------------------------------------------------------- /vagrant-mongo/lib/vagrant-mongo.rb: -------------------------------------------------------------------------------- 1 | require 'vagrant' 2 | require File.dirname(__FILE__) + '/vagrant-mongo/middleware' 3 | require File.dirname(__FILE__) + '/vagrant-mongo/facter' 4 | require File.dirname(__FILE__) + '/vagrant-mongo/config' 5 | require File.dirname(__FILE__) + '/vagrant-mongo/configure' 6 | require File.dirname(__FILE__) + '/vagrant-mongo/command' 7 | 8 | 9 | Vagrant.config_keys.register(:mongo) { VagrantMongo::Config } 10 | 11 | # We need this to be executed after the entire environment is up and running 12 | #Vagrant.actions[:start].insert_before Vagrant::Action::VM::Provision, VagrantMongo::Middleware::ReplicaSet 13 | 14 | # This will inject a 'fact' with the ReplicaSet name so we can pass the apropriate arguments to mongod 15 | Vagrant.actions[:provision].insert_before Vagrant::Action::VM::Provision, VagrantMongo::Middleware::Facter 16 | Vagrant.actions[:provision].insert_before Vagrant::Action::VM::Provision, VagrantMongo::Middleware::Hosts 17 | Vagrant.actions[:start].insert_after Vagrant::Action::VM::Provision, VagrantMongo::Middleware::Facter 18 | Vagrant.actions[:start].insert_after Vagrant::Action::VM::Provision, VagrantMongo::Middleware::Hosts 19 | 20 | Vagrant.commands.register(:mongo) { VagrantMongo::Command::Mongo } 21 | 22 | #I18n.load_path << File.expand_path("../../locales/en.yml", __FILE__) 23 | -------------------------------------------------------------------------------- /vagrant-mongo/lib/vagrant-mongo/command.rb: -------------------------------------------------------------------------------- 1 | require 'optparse' 2 | 3 | module VagrantMongo 4 | 5 | module Command 6 | class Mongo < Vagrant::Command::Base 7 | 8 | def execute 9 | options = {} 10 | 11 | opts = OptionParser.new do |opts| 12 | opts.banner = "Usage: vagrant mongo vm-name --init-replicaset" 13 | 14 | opts.separator "" 15 | 16 | opts.on("", "--init-replicaset", "Initialize or reconfigure replicaset") do |c| 17 | options[:replicaset] = c 18 | end 19 | 20 | opts.on("-c", "--create-user", "Create a user") do |c| 21 | options[:create] = true 22 | end 23 | opts.on("-u", "--username username", "The username of the new user") do |c| 24 | options[:username] = c 25 | end 26 | opts.on("-p", "--password password", "The password of the new user") do |c| 27 | options[:password] = c 28 | end 29 | opts.on("-d", "--db dbname", "The database the user should be created on") do |c| 30 | options[:database] = c 31 | end 32 | 33 | opts.on("", "--authuser username", "The username to authenticate with") do |c| 34 | options[:authuser] = c 35 | end 36 | opts.on("", "--authpass password", "The password to authenticate with") do |c| 37 | options[:authpass] = c 38 | end 39 | opts.on("", "--authdb dbname", "The database to authenticate against") do |c| 40 | options[:authdb] = c 41 | end 42 | end 43 | 44 | argv = parse_options(opts) 45 | return if !argv 46 | 47 | 48 | raise Vagrant::Errors::CLIInvalidOptions, :help => opts.help.chomp if argv.empty? 49 | #with_target_vms(nil) { |vm| execute_on_primary_vm(vm) } 50 | #else 51 | argv.each do |vm_name| 52 | with_target_vms(vm_name) do |vm| 53 | if options[:replicaset] 54 | init_replicaset_on_vm(vm) 55 | end 56 | if options[:create] 57 | create_user_on_vm(vm, options) 58 | end 59 | end 60 | end 61 | #end 62 | end 63 | 64 | def create_user_on_vm(vm, options) 65 | opts = vm.config.mongo.to_hash 66 | VagrantMongo::Configure.new(@env, vm, opts).createUser(options) 67 | end 68 | 69 | def init_replicaset_on_vm(vm) 70 | opts = vm.config.mongo.to_hash 71 | VagrantMongo::Configure.new(@env, vm, opts).initReplicaset 72 | end 73 | 74 | def execute_on_primary_vm(vm) 75 | return if vm.config.mongo.arbiter 76 | primary = vm.config.vm.host_name; 77 | pr = 0 78 | 79 | @env.vms.each do |name, subvm| 80 | if subvm.config.mongo.arbiter != true 81 | if subvm.config.mongo.priority > pr 82 | pr = subvm.config.mongo.priority 83 | primary = subvm.config.vm.host_name 84 | end 85 | end 86 | end 87 | 88 | # In case two or more have the same priority 89 | init_replicaset_on_vm(vm) if vm.config.vm.host_name == primary 90 | end 91 | 92 | end 93 | end 94 | end 95 | -------------------------------------------------------------------------------- /vagrant-mongo/lib/vagrant-mongo/config.rb: -------------------------------------------------------------------------------- 1 | module VagrantMongo 2 | 3 | class Config < Vagrant::Config::Base 4 | attr_accessor :id 5 | attr_accessor :priority 6 | attr_accessor :arbiter 7 | attr_accessor :rs 8 | attr_accessor :auth 9 | 10 | 11 | def to_hash 12 | { 13 | :rs => { 14 | :id => id, 15 | :priority => priority, 16 | :name => rs, 17 | :arbiter => arbiter 18 | }, 19 | :auth => auth 20 | } 21 | end 22 | 23 | 24 | def validate(env, errors) 25 | end 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /vagrant-mongo/lib/vagrant-mongo/configure.rb: -------------------------------------------------------------------------------- 1 | require 'json' 2 | module VagrantMongo 3 | 4 | class Configure 5 | 6 | def initialize(env, vm, options = {}) 7 | @env = env 8 | @vm = vm 9 | @options = options 10 | end 11 | 12 | def createUser(options) 13 | return unless is_master? 14 | 15 | puts options 16 | db = options[:database] || "admin" 17 | 18 | command = 'db.getSiblingDB("' + db + '").addUser("' + options[:username]+ '", "' + options[:password] +'")' 19 | 20 | if options[:authuser] 21 | options[:authdb] = options[:authdb] || "admin" 22 | auth = ' --username ' + options[:authuser] + ' --password ' + options[:authpass] + ' localhost/' + options[:authdb] + ' ' 23 | else 24 | auth = "" 25 | end 26 | 27 | 28 | cmd = "mongo " + auth + " --eval '" + command + "'" 29 | @vm.channel.execute(cmd) do |type, data| 30 | @vm.ui.info(data, :prefix => false, :new_line => false) 31 | end 32 | 33 | end 34 | 35 | def initReplicaset 36 | raise Vagrant::Errors::VMNotCreatedError if !@vm.created? 37 | raise Vagrant::Errors::VMInaccessible if !@vm.state == :inaccessible 38 | raise Vagrant::Errors::VMNotRunningError if @vm.state != :running 39 | 40 | 41 | return unless @vm.config.mongo.rs 42 | 43 | cfg = make_cfg(@vm, @options) 44 | 45 | reconfig_rs(cfg) if replicaset_initialized? 46 | init_replicaset(cfg) unless replicaset_initialized? 47 | end 48 | 49 | def make_cfg(vm, options) 50 | members = [] 51 | @env.vms.each do |name, subvm| 52 | next if subvm.config.mongo == nil 53 | next if subvm.config.mongo.rs != vm.config.mongo.rs 54 | 55 | member = {} 56 | c = subvm.config.mongo.to_hash 57 | member[:_id] = c[:rs][:id] 58 | member[:host] = subvm.config.vm.host_name 59 | 60 | if subvm.config.mongo.priority 61 | member[:priority] = subvm.config.mongo.priority 62 | end 63 | if subvm.config.mongo.arbiter 64 | member[:arbiterOnly] = true 65 | end 66 | 67 | members.push(member) 68 | end 69 | retval = { :_id => vm.config.mongo.rs, :members => members } 70 | 71 | retval 72 | end 73 | 74 | def reconfig_rs(cfg) 75 | return unless is_master? 76 | json = cfg.to_json 77 | 78 | @vm.channel.execute("mongo --eval 'rs.reconfig(#{json}).errmsg'") do |type, data| 79 | @vm.ui.info(data, :prefix => false, :new_line => false) 80 | end 81 | 82 | end 83 | 84 | def replicaset_initialized? 85 | @vm.channel.execute("mongo --eval 'rs.status().ok' | tail -n1", :error_check => false) do | type, data | 86 | return data.chomp == "1" 87 | end 88 | end 89 | 90 | def init_replicaset(cfg) 91 | json = cfg.to_json 92 | 93 | @vm.channel.execute("mongo --eval 'rs.initiate(#{json}).errmsg'") do |type, data| 94 | @vm.ui.info(data, :prefix => false, :new_line => false) 95 | end 96 | 97 | end 98 | 99 | def is_master? 100 | @vm.channel.execute("mongo --eval 'rs.isMaster().ismaster' | tail -n1") do |type, data| 101 | return data.chomp == "true" 102 | end 103 | end 104 | 105 | end 106 | 107 | end 108 | -------------------------------------------------------------------------------- /vagrant-mongo/lib/vagrant-mongo/facter.rb: -------------------------------------------------------------------------------- 1 | module VagrantMongo 2 | module Middleware 3 | 4 | class Facter 5 | def initialize(app, env) 6 | @app = app 7 | @env = env 8 | @vm = env[:vm] 9 | end 10 | 11 | def call(env) 12 | 13 | options = @vm.config.mongo.to_hash 14 | 15 | @env[:vm].config.vm.provisioners.each do |provisioner| 16 | if provisioner.shortcut.to_s == "puppet" 17 | 18 | provisioner.config.facter[:rs_name] = "" 19 | provisioner.config.facter[:mongo_auth] = options[:auth] 20 | 21 | if options[:rs][:name] 22 | provisioner.config.facter[:rs_name] = options[:rs][:name] 23 | provisioner.config.facter[:rs_arbiter] = options[:rs][:arbiter] ? "true" : "false" 24 | end 25 | 26 | end 27 | end 28 | 29 | @app.call(env) 30 | 31 | end 32 | 33 | end 34 | 35 | class Hosts 36 | def initialize(app, env) 37 | @app = app 38 | @env = env 39 | @vm = env[:vm] 40 | end 41 | 42 | def call(env) 43 | hosts = get_hosts_for_replicaset(@vm) 44 | content = make_file_content(hosts) 45 | 46 | base = get_base_path(@vm) 47 | filename = write_temp_hostfile(base, content) 48 | 49 | @app.call(env) 50 | 51 | #remove_temp_hostfile(filename) 52 | end 53 | 54 | def get_hosts_for_replicaset(vm) 55 | entries = [] 56 | vm.env.vms.each do |name, subvm| 57 | next if subvm.config.mongo == nil 58 | next if subvm.config.mongo.rs != vm.config.mongo.rs 59 | 60 | entry = get_host_for(name, subvm) 61 | 62 | entries.push(entry) 63 | end 64 | 65 | entries 66 | end 67 | 68 | def get_host_for(name, vm) 69 | member = {} 70 | member[:hosts] = vm.config.vm.host_name, name 71 | vm.config.vm.networks.each do |type, args| 72 | raise Vagrant::Errors::ConfigValidationFailed unless type == :hostonly 73 | member[:ip] = args[0] 74 | end 75 | 76 | member 77 | end 78 | 79 | def get_base_path(vm) 80 | vm.config.vm.provisioners.each do |provisioner| 81 | raise Vagrant::Errors::ConfigValidationFailed unless provisioner.shortcut.to_s == "puppet" 82 | return provisioner.config.module_path + "/" 83 | end 84 | end 85 | 86 | def write_temp_hostfile(base, data) 87 | f = File.new(base + "hosts/manifests/generated.pp", "w+") 88 | f.write(data) 89 | f.path 90 | end 91 | 92 | def make_file_content(hosts) 93 | content = "# THIS FILE WAS GENERATED BY MONGO VAGRANT AND WILL BE OVERWRITTEN\n" 94 | content += "class hosts::generated {\n" 95 | 96 | hosts.each do | entry | 97 | content += < 'present', 100 | ip => '#{entry[:ip]}', 101 | host_aliases => ['#{entry[:hosts][0]}', '#{entry[:hosts][1]}'] 102 | } 103 | EOS 104 | 105 | end 106 | content += "}\n" 107 | 108 | content 109 | end 110 | 111 | end 112 | end 113 | end 114 | -------------------------------------------------------------------------------- /vagrant-mongo/lib/vagrant-mongo/middleware.rb: -------------------------------------------------------------------------------- 1 | module VagrantMongo 2 | module Middleware 3 | 4 | class ReplicaSet 5 | def initialize(app, env) 6 | @app = app 7 | @env = env 8 | @vm = env[:vm] 9 | end 10 | 11 | def call(env) 12 | @app.call(env) 13 | 14 | options = @vm.config.mongo.to_hash 15 | VagrantMongo::Configure.new(@vm.env, @vm, options).initReplicaset 16 | end 17 | 18 | end 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /vagrant-mongo/lib/vagrant-mongo/version.rb: -------------------------------------------------------------------------------- 1 | module VagrantMongo 2 | VERSION = "0.0.1" 3 | end 4 | -------------------------------------------------------------------------------- /vagrant-mongo/lib/vagrant_init.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/vagrant-mongo' 2 | --------------------------------------------------------------------------------