kellerkind 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/Gemfile ADDED
@@ -0,0 +1,17 @@
1
+ source "http://rubygems.org"
2
+ # Add dependencies required to use your gem here.
3
+ # Example:
4
+ # gem "activesupport", ">= 2.3.5"
5
+
6
+ gem 'virtus', "~> 0.5.5"
7
+ gem "minitar", "~> 0.5.4"
8
+ gem "trollop"
9
+
10
+ # Add dependencies to develop your gem here.
11
+ # Include everything needed to run rake, tests, features, etc.
12
+ group :development do
13
+ gem "rspec", "~> 2.13.0"
14
+ gem "rdoc", "~> 3.12"
15
+ gem "bundler", "~> 1.3.5"
16
+ gem "jeweler", "~> 1.8.4"
17
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,73 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ addressable (2.3.5)
5
+ backports (3.3.3)
6
+ builder (3.2.2)
7
+ descendants_tracker (0.0.1)
8
+ diff-lcs (1.2.4)
9
+ faraday (0.8.7)
10
+ multipart-post (~> 1.1)
11
+ git (1.2.5)
12
+ github_api (0.10.1)
13
+ addressable
14
+ faraday (~> 0.8.1)
15
+ hashie (>= 1.2)
16
+ multi_json (~> 1.4)
17
+ nokogiri (~> 1.5.2)
18
+ oauth2
19
+ hashie (2.0.5)
20
+ highline (1.6.19)
21
+ httpauth (0.2.0)
22
+ jeweler (1.8.6)
23
+ builder
24
+ bundler (~> 1.0)
25
+ git (>= 1.2.5)
26
+ github_api (= 0.10.1)
27
+ highline (>= 1.6.15)
28
+ nokogiri (= 1.5.10)
29
+ rake
30
+ rdoc
31
+ json (1.8.0)
32
+ jwt (0.1.8)
33
+ multi_json (>= 1.5)
34
+ minitar (0.5.4)
35
+ multi_json (1.7.7)
36
+ multi_xml (0.5.4)
37
+ multipart-post (1.2.0)
38
+ nokogiri (1.5.10)
39
+ oauth2 (0.9.2)
40
+ faraday (~> 0.8)
41
+ httpauth (~> 0.2)
42
+ jwt (~> 0.1.4)
43
+ multi_json (~> 1.0)
44
+ multi_xml (~> 0.5)
45
+ rack (~> 1.2)
46
+ rack (1.5.2)
47
+ rake (10.1.0)
48
+ rdoc (3.12.2)
49
+ json (~> 1.4)
50
+ rspec (2.13.0)
51
+ rspec-core (~> 2.13.0)
52
+ rspec-expectations (~> 2.13.0)
53
+ rspec-mocks (~> 2.13.0)
54
+ rspec-core (2.13.1)
55
+ rspec-expectations (2.13.0)
56
+ diff-lcs (>= 1.1.3, < 2.0)
57
+ rspec-mocks (2.13.1)
58
+ trollop (2.0)
59
+ virtus (0.5.5)
60
+ backports (~> 3.3)
61
+ descendants_tracker (~> 0.0.1)
62
+
63
+ PLATFORMS
64
+ ruby
65
+
66
+ DEPENDENCIES
67
+ bundler (~> 1.3.5)
68
+ jeweler (~> 1.8.4)
69
+ minitar (~> 0.5.4)
70
+ rdoc (~> 3.12)
71
+ rspec (~> 2.13.0)
72
+ trollop
73
+ virtus (~> 0.5.5)
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2013 Daniel Schmidt
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,45 @@
1
+ # kellerkind
2
+
3
+ Kellerkind is just a Ruby script that runs mongodump and tars the resulting dump.
4
+
5
+ It should be used with its cli but it's also possible to use it with its API.
6
+
7
+ ## Usage
8
+
9
+ Install it as gem:
10
+
11
+ ```
12
+ gem install kellerkind
13
+ ```
14
+
15
+ Run from the command line:
16
+
17
+ ```
18
+ kellerkind --help
19
+ ```
20
+
21
+ to the arguments you could specify.
22
+
23
+ **Example**
24
+
25
+ ```
26
+ kellerkind --mongo-db appDatabase --mongo-host linus.mongohq.com --mongo-port 10010 --mongo-username myUser --mongo-password myCrypticPassword --compress true --out $HOME/tmp/mongodump
27
+ ```
28
+
29
+ Dumps a database hosted at MongoHQ to <code>$HOME/tmp/mongodump</code> and create a tar file of this dump.
30
+
31
+ ## Contributing to kellerkind
32
+
33
+ * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
34
+ * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
35
+ * Fork the project.
36
+ * Start a feature/bugfix branch.
37
+ * Commit and push until you are happy with your contribution.
38
+ * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
39
+ * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
40
+
41
+ ## Copyright
42
+
43
+ Copyright (c) 2013 Daniel Schmidt. See LICENSE.txt for
44
+ further details.
45
+
data/Rakefile ADDED
@@ -0,0 +1,49 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ begin
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
12
+ require 'rake'
13
+
14
+ require 'jeweler'
15
+ Jeweler::Tasks.new do |gem|
16
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
17
+ gem.name = "kellerkind"
18
+ gem.homepage = "http://github.com/dsci/kellerkind"
19
+ gem.license = "MIT"
20
+ gem.summary = %Q{Mongodb archiving tool.}
21
+ gem.description = %Q{Dumps mongodb databases and archives them.}
22
+ gem.email = "dsci@code79.net"
23
+ gem.authors = ["Daniel Schmidt"]
24
+ # dependencies defined in Gemfile
25
+ end
26
+ Jeweler::RubygemsDotOrgTasks.new
27
+
28
+ require 'rspec/core'
29
+ require 'rspec/core/rake_task'
30
+ RSpec::Core::RakeTask.new(:spec) do |spec|
31
+ spec.pattern = FileList['spec/**/*_spec.rb']
32
+ end
33
+
34
+ RSpec::Core::RakeTask.new(:rcov) do |spec|
35
+ spec.pattern = 'spec/**/*_spec.rb'
36
+ spec.rcov = true
37
+ end
38
+
39
+ task :default => :spec
40
+
41
+ require 'rdoc/task'
42
+ Rake::RDocTask.new do |rdoc|
43
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
44
+
45
+ rdoc.rdoc_dir = 'rdoc'
46
+ rdoc.title = "kellerkind #{version}"
47
+ rdoc.rdoc_files.include('README*')
48
+ rdoc.rdoc_files.include('lib/**/*.rb')
49
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.1
data/bin/kellerkind ADDED
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env ruby
2
+ lib = File.expand_path(File.dirname(__FILE__) + '/../lib')
3
+ $LOAD_PATH.unshift(lib) if File.directory?(lib) && !$LOAD_PATH.include?(lib)
4
+
5
+ require 'kellerkind'
6
+
7
+ REQUIRED_ARGS = {
8
+ :mongo_db => %Q{You must specify a mongo database! },
9
+ :out => %Q{You must specify a path the dump should saved to! }
10
+ }
11
+
12
+ opts = Trollop::options do
13
+ banner <<-EOS
14
+ Mongodb archiving tool.
15
+
16
+ Dumps mongodb databases and archives them. Nothing more. Neat, isn't it?
17
+ EOS
18
+
19
+ opt :mongo_db, "mongo database to dump", :type => :string
20
+ opt :mongo_host, "mongo host to connect to", :type => :string,
21
+ :default => "localhost"
22
+ opt :mongo_username, "mongo username", :type => :string
23
+ opt :mongo_password, "mongo password", :type => :string
24
+ opt :mongo_port, "mongo server port", :type => :string,
25
+ :default => "27017"
26
+ opt :out, "path to dump to", :type => :string
27
+ opt :compress, "use gzip compression?", :type => :boolean,
28
+ :default => false
29
+ opt :remove_dump, "remove dump after compression?", :type => :boolean,
30
+ :default => true
31
+ end
32
+
33
+ REQUIRED_ARGS.each_pair do |key,value|
34
+ Trollop::die key, value unless opts[key]
35
+ end
36
+
37
+ Kellerkind::Runner.exec(opts)
38
+
@@ -0,0 +1,85 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "kellerkind"
8
+ s.version = "0.1.1"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Daniel Schmidt"]
12
+ s.date = "2013-07-05"
13
+ s.description = "Dumps mongodb databases and archives them."
14
+ s.email = "dsci@code79.net"
15
+ s.executables = ["kellerkind"]
16
+ s.extra_rdoc_files = [
17
+ "LICENSE.txt",
18
+ "README.md"
19
+ ]
20
+ s.files = [
21
+ ".document",
22
+ ".rspec",
23
+ "Gemfile",
24
+ "Gemfile.lock",
25
+ "LICENSE.txt",
26
+ "README.md",
27
+ "Rakefile",
28
+ "VERSION",
29
+ "bin/kellerkind",
30
+ "kellerkind.gemspec",
31
+ "lib/kellerkind.rb",
32
+ "lib/kellerkind/core/configuration.rb",
33
+ "lib/kellerkind/core/ext.rb",
34
+ "lib/kellerkind/core/set.rb",
35
+ "lib/kellerkind/database/mongo.rb",
36
+ "lib/kellerkind/dependencies.rb",
37
+ "lib/kellerkind/system/compress.rb",
38
+ "lib/kellerkind/system/die.rb",
39
+ "lib/kellerkind/system/lock.rb",
40
+ "lib/kellerkind/system/runner.rb",
41
+ "spec/fixtures/mongodb.js",
42
+ "spec/kellerkind/database/mongo_spec.rb",
43
+ "spec/kellerkind/system/compress_spec.rb",
44
+ "spec/kellerkind/system/lock_spec.rb",
45
+ "spec/kellerkind/tmp/.gitkeep",
46
+ "spec/kellerkind_spec.rb",
47
+ "spec/spec_helper.rb"
48
+ ]
49
+ s.homepage = "http://github.com/dsci/kellerkind"
50
+ s.licenses = ["MIT"]
51
+ s.require_paths = ["lib"]
52
+ s.rubygems_version = "1.8.25"
53
+ s.summary = "Mongodb archiving tool."
54
+
55
+ if s.respond_to? :specification_version then
56
+ s.specification_version = 3
57
+
58
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
59
+ s.add_runtime_dependency(%q<virtus>, ["~> 0.5.5"])
60
+ s.add_runtime_dependency(%q<minitar>, ["~> 0.5.4"])
61
+ s.add_runtime_dependency(%q<trollop>, [">= 0"])
62
+ s.add_development_dependency(%q<rspec>, ["~> 2.13.0"])
63
+ s.add_development_dependency(%q<rdoc>, ["~> 3.12"])
64
+ s.add_development_dependency(%q<bundler>, ["~> 1.3.5"])
65
+ s.add_development_dependency(%q<jeweler>, ["~> 1.8.4"])
66
+ else
67
+ s.add_dependency(%q<virtus>, ["~> 0.5.5"])
68
+ s.add_dependency(%q<minitar>, ["~> 0.5.4"])
69
+ s.add_dependency(%q<trollop>, [">= 0"])
70
+ s.add_dependency(%q<rspec>, ["~> 2.13.0"])
71
+ s.add_dependency(%q<rdoc>, ["~> 3.12"])
72
+ s.add_dependency(%q<bundler>, ["~> 1.3.5"])
73
+ s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
74
+ end
75
+ else
76
+ s.add_dependency(%q<virtus>, ["~> 0.5.5"])
77
+ s.add_dependency(%q<minitar>, ["~> 0.5.4"])
78
+ s.add_dependency(%q<trollop>, [">= 0"])
79
+ s.add_dependency(%q<rspec>, ["~> 2.13.0"])
80
+ s.add_dependency(%q<rdoc>, ["~> 3.12"])
81
+ s.add_dependency(%q<bundler>, ["~> 1.3.5"])
82
+ s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
83
+ end
84
+ end
85
+
@@ -0,0 +1,64 @@
1
+ module Kellerkind
2
+
3
+ # Public: Various methods useful for configure Kellerkind.
4
+ module Config
5
+ extend self
6
+
7
+
8
+ # Public: Gets the prefix that is use in the cli for database options.
9
+ #
10
+ # Returns a regular expression.
11
+ def db_prefix
12
+ /mongo_/
13
+ end
14
+
15
+
16
+ # Public: Gets the name of the command line executable to use for
17
+ # dumping.
18
+ #
19
+ # Returns name of executable as String.
20
+ def db_dump_cmd
21
+ "mongodump"
22
+ end
23
+
24
+
25
+ # Public: Gets the path to the lock dir to mark process running.
26
+ # Note that just one kellerkind process is runnable.
27
+ def lock_dir
28
+ File.join(Dir.home, "tmp")
29
+ end
30
+
31
+ # Public: Gets the direct path to kellerkind lock file
32
+ def lock_path
33
+ File.join(lock_dir,"Kellerkind.lock")
34
+ end
35
+
36
+ # Internal: Gets message for action when dumping was started.
37
+ def start_dumping
38
+ %Q{Start dumping ...}
39
+ end
40
+
41
+ # Internal: Gets message for action when a dump is about to remove.
42
+ def remove_dump
43
+ %Q{Remove raw dump. To disable that use --remove-dump false}
44
+ end
45
+
46
+ # Internal: Gets message for action when compressing was started.
47
+ def start_compressing
48
+ %Q{Start compressing of dump ... }
49
+ end
50
+
51
+ # Internal: Gets message for action when compressing is finished.
52
+ def finished_compressing
53
+ %Q{Compressing done ...}
54
+ end
55
+
56
+ # Internal: Gets message for action when all is done.
57
+ #
58
+ # database - Name of the database from which a dump is created.
59
+ def finished_dumping(database)
60
+ %Q{ -- Dumping of #{database} done ...}
61
+ end
62
+
63
+ end
64
+ end
@@ -0,0 +1,8 @@
1
+ Object.class_eval do
2
+
3
+ def in?(list)
4
+ raise ArgumentError unless list.respond_to?(:include?)
5
+ list.include?(self)
6
+ end
7
+
8
+ end
@@ -0,0 +1,16 @@
1
+ module Kellerkind
2
+ class Set
3
+ include Virtus
4
+
5
+ protected
6
+
7
+ def init_instance(options)
8
+ options.each_pair do |key,value|
9
+ instance_attr = key.to_s.split(Kellerkind::Config.db_prefix).last
10
+ if instance_attr.to_sym.in?(attributes.keys)
11
+ self.send("#{instance_attr}=", value)
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,59 @@
1
+ module Kellerkind
2
+
3
+ # Public: Dumps a MongoDb database.
4
+ #
5
+ # For more see mongodump --help
6
+ class Mongo < Set
7
+
8
+ # MongoDb database (required)
9
+ attribute :db, String
10
+ # MongoDb host
11
+ attribute :host, String
12
+ # MongoDb user
13
+ attribute :username, String
14
+ # MongoDb user password
15
+ attribute :password, String
16
+ # MongoDb server host
17
+ attribute :port, String
18
+ # File path location for dump
19
+ attribute :out, String
20
+
21
+ def initialize(options={})
22
+ init_instance(options) unless options.empty?
23
+ end
24
+
25
+
26
+ # Public: Dumps the database by using a stream to the underlying
27
+ # operation system.
28
+ #
29
+ def dump_database
30
+ cmd = %Q{`which #{Kellerkind::Config.db_dump_cmd}` #{dump_argument_list}}
31
+ out = IO.popen(cmd)
32
+ out.readlines.join(" ")
33
+ end
34
+
35
+
36
+ # Public: Builds an argument list for mongodump by taking only values
37
+ # existing in #attributes
38
+ #
39
+ # Returns the argument list string.
40
+ def dump_argument_list
41
+ usable_line_args = attributes.select{|k,v| not v.nil? }
42
+ return "" if usable_line_args.empty?
43
+ return usable_line_args.collect do |key,value|
44
+ "--#{key} #{value}"
45
+ end.join(" ")
46
+ end
47
+
48
+ private
49
+
50
+ def init_instance(options)
51
+ options.each_pair do |key,value|
52
+ instance_attr = key.to_s.split(Kellerkind::Config.db_prefix).last
53
+ if instance_attr.to_sym.in?(attributes.keys)
54
+ self.send("#{instance_attr}=", value)
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,9 @@
1
+ %w{ core/ext.rb
2
+ core/configuration
3
+ core/set
4
+ system/lock
5
+ system/compress
6
+ system/die
7
+ database/mongo
8
+ system/runner
9
+ }.each{ |code| require_relative code }
@@ -0,0 +1,59 @@
1
+ require 'zlib'
2
+ require 'archive/tar/minitar'
3
+
4
+ module Kellerkind
5
+
6
+ # Public: Compresses a mongodb dump directory by using Gzip and tar.
7
+ class Compress < Set
8
+
9
+ include Archive::Tar
10
+
11
+ # Path where dump is located (parent direcotry of the dump)
12
+ attribute :path, String
13
+ # Database name which equals the dumps directory name
14
+ attribute :database_name, String
15
+
16
+
17
+ # Public: Initialises compressing of the dumps directory.
18
+ def gzip
19
+ traverse_and_gzip
20
+ end
21
+
22
+
23
+ # Public: Checks if tar file exists.
24
+ #
25
+ # If tar file exists we assume compressing succeeds
26
+ #
27
+ # Returns true if file exists otherwise false.
28
+ def succeeded?
29
+ File.exists?(File.join(self.path, @actual_tar_name))
30
+ end
31
+
32
+ private
33
+
34
+ def traverse_and_gzip
35
+ Dir.chdir(self.path) do
36
+ Find.find(self.database_name).each do |file|
37
+ if File.directory?(file)
38
+ tgz = Zlib::GzipWriter.new(db_dump_gz_file)
39
+ Minitar.pack(file, tgz)
40
+ end
41
+ end
42
+ end
43
+ end
44
+
45
+ def tarball_name
46
+ "#{self.database_name}_#{Time.now.to_i}.tar.gz"
47
+ end
48
+
49
+ def db_dump_gz_file
50
+ File.open(tar_location, 'wb')
51
+ end
52
+
53
+ def tar_location
54
+ @actual_tar_name = tarball_name
55
+ File.join(self.path, @actual_tar_name)
56
+ end
57
+
58
+ end
59
+ end
@@ -0,0 +1,9 @@
1
+ module Kellerkind
2
+ module Die
3
+
4
+ def die(abort_message, options={})
5
+ abort(abort_message)
6
+ end
7
+
8
+ end
9
+ end
@@ -0,0 +1,19 @@
1
+ module Kellerkind
2
+ module Lock
3
+ extend self
4
+
5
+ def lock_process
6
+ unless File.exists?(Kellerkind::Config.lock_dir)
7
+ FileUtils.mkdir(Kellerkind::Config.lock_dir)
8
+ end
9
+ FileUtils.touch(Kellerkind::Config.lock_path)
10
+ end
11
+
12
+ def unlock_process
13
+ if File.exists?(Kellerkind::Config.lock_path)
14
+ FileUtils.rm(Kellerkind::Config.lock_path)
15
+ end
16
+ end
17
+
18
+ end
19
+ end
@@ -0,0 +1,56 @@
1
+ module Kellerkind
2
+ class Runner
3
+ extend Die
4
+
5
+ PROCESS_LOCKED_WARNING = <<-WARNING
6
+ kellerkind.lock find! Make sure that there isn't another kellerkind process running!
7
+ WARNING
8
+
9
+ DUMP_NOT_SUCCEEDED_WARNING = <<-WARNING
10
+ No dump found. It seems dumping failed.
11
+ WARNING
12
+
13
+ def self.exec(options={})
14
+ process_locked?
15
+ lock_process
16
+ mongo = Mongo.new(options)
17
+ puts Kellerkind::Config.start_dumping
18
+ mongo.dump_database
19
+ if options[:compress]
20
+ compress = Compress.new(:path => options[:out],
21
+ :database_name =>options[:mongo_db])
22
+ if File.exists?(File.join(options[:out], options[:mongo_db]))
23
+ puts Kellerkind::Config.start_compressing
24
+ compress.gzip
25
+ if compress.succeeded?
26
+ puts Kellerkind::Config.finished_compressing
27
+ if options[:remove_dump]
28
+ puts Kellerkind::Config.remove_dump
29
+ FileUtils.rm_rf(File.join(options[:out],mongo.db))
30
+ end
31
+ end
32
+ else
33
+ unlock_process
34
+ die(DUMP_NOT_SUCCEEDED_WARNING)
35
+ end
36
+ end
37
+
38
+ unlock_process
39
+ puts Kellerkind::Config.finished_dumping(mongo.db)
40
+ end
41
+
42
+ def self.process_locked?
43
+ die(PROCESS_LOCKED_WARNING) if File.exists?(Kellerkind::Config.lock_path)
44
+ end
45
+
46
+ private
47
+
48
+ def self.lock_process
49
+ Kellerkind::Lock.lock_process
50
+ end
51
+
52
+ def self.unlock_process
53
+ Kellerkind::Lock.unlock_process
54
+ end
55
+ end
56
+ end
data/lib/kellerkind.rb ADDED
@@ -0,0 +1,12 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+
4
+ Bundler.require
5
+
6
+ require_relative 'kellerkind/dependencies'
7
+
8
+ <<-DOC
9
+ File.open('test.tar', 'wb') { |tar| Minitar.pack(File.join("/Users/Demo/tmp/"), tar) }
10
+ DOC
11
+
12
+ Kellerkind::Mongo.new
@@ -0,0 +1,8 @@
1
+ var databaseName = "kellerkindTest";
2
+ var kellerkindDb = db.getSiblingDB(databaseName);
3
+ var data = {
4
+ "title" : "10 Uhr zwanzig"
5
+ }
6
+
7
+ kellerkindDb.tests.insert(obj);
8
+
@@ -0,0 +1,145 @@
1
+ require 'spec_helper'
2
+
3
+ describe Kellerkind::Mongo do
4
+
5
+ it{ should respond_to(:db) }
6
+ it{ should respond_to(:host) }
7
+ it{ should respond_to(:username) }
8
+ it{ should respond_to(:password) }
9
+ it{ should respond_to(:port) }
10
+ it{ should respond_to(:out) }
11
+
12
+ describe "instance methoods" do
13
+
14
+ let(:attributes) do
15
+ {
16
+ :mongo_db => "test",
17
+ :mongo_host => "localhost",
18
+ :mongo_username => "rspec_user",
19
+ :mongo_password => "no_pwd",
20
+ :mongo_port => "27017"
21
+ }
22
+ end
23
+
24
+ it{ should respond_to(:dump_database) }
25
+ it{ should respond_to(:dump_argument_list)}
26
+
27
+ describe "#initialize" do
28
+
29
+ context "with a hash of attributes" do
30
+
31
+ context "that uses the proper prefix" do
32
+
33
+ subject{ Kellerkind::Mongo.new(attributes) }
34
+
35
+ it "then initializes the instance with the attributes values" do
36
+ subject.db.should eq attributes[:mongo_db]
37
+ subject.host.should eq attributes[:mongo_host]
38
+ subject.username.should eq attributes[:mongo_username]
39
+ subject.password.should eq attributes[:mongo_password]
40
+ subject.port.should eq attributes[:mongo_port]
41
+
42
+ subject.dump_database
43
+ end
44
+
45
+ end
46
+
47
+ context "that uses not the proper prefix" do
48
+ let(:inproper_attributes) do
49
+ attributes.delete(:mongo_db)
50
+ attributes[:super_database] = "testa"
51
+ attributes
52
+ end
53
+
54
+ subject{ Kellerkind::Mongo.new(inproper_attributes) }
55
+
56
+ it "then initializes the instance without these attributes" do
57
+ subject.db.should be nil
58
+ end
59
+
60
+ end
61
+
62
+ end
63
+
64
+ end
65
+
66
+ describe "#dump_argument_list" do
67
+
68
+ context "and arguments given" do
69
+
70
+ let(:mongo){ Kellerkind::Mongo.new(attributes) }
71
+
72
+ subject{ mongo.dump_argument_list }
73
+
74
+ context "then returns a parameter list including the instances attributes" do
75
+
76
+ it{ should match(/--db #{attributes[:mongo_db]}{1,}/) }
77
+ it{ should match(/--password #{attributes[:mongo_password]}{1,}/) }
78
+ it{ should match(/--host #{attributes[:mongo_host]}{1,}/) }
79
+ it{ should match(/--port #{attributes[:mongo_port]}{1,}/)}
80
+ it{ should match(/--username #{attributes[:mongo_username]}{1,}/)}
81
+
82
+ it{ should_not match(/--host #{attributes[:mongo_host]}{2,*}/)}
83
+ it{ should_not match(/--db #{attributes[:mongo_db]}{2,*}/) }
84
+ it{ should_not match(/--password #{attributes[:mongo_password]}{2,*}/) }
85
+ it{ should_not match(/--host #{attributes[:mongo_host]}{2,*}/) }
86
+ it{ should_not match(/--port #{attributes[:mongo_port]}{2,*}/)}
87
+ it{ should_not match(/--user_name #{attributes[:mongo_username]}{2,*}/)}
88
+
89
+ end
90
+
91
+ end
92
+
93
+ context "and no arguments given" do
94
+
95
+ let(:mongo){ Kellerkind::Mongo.new }
96
+
97
+ subject{ mongo.dump_argument_list }
98
+
99
+ it "then returns an empty string" do
100
+ subject.should be_empty
101
+ end
102
+
103
+ end
104
+
105
+ end
106
+
107
+ describe "#dump_database" do
108
+ let(:out_dir) do
109
+ File.expand_path(File.join(File.dirname(__FILE__),"..", "tmp"))
110
+ end
111
+ let(:dump_attributes) do
112
+ {
113
+ :mongo_db => "kellerkindTest",
114
+ :mongo_port => "27017",
115
+ :mongo_host => "localhost",
116
+ :mongo_out => out_dir
117
+ }
118
+ end
119
+
120
+ before do
121
+ js_path = File.expand_path(File.join(__FILE__,'..','..','fixtures'))
122
+ system("`which mongo` #{js_path}/mongodb.js")
123
+ end
124
+
125
+ after do
126
+ if File.exists?(out_dir)
127
+ FileUtils.rm_rf(out_dir)
128
+ end
129
+ end
130
+
131
+ subject{ Kellerkind::Mongo.new(dump_attributes) }
132
+
133
+ it "dumps database content into --out" do
134
+ subject.dump_database
135
+ File.exists?("#{out_dir}/kellerkindTest").should be true
136
+ File.exists?("#{out_dir}/kellerkindTest/tests.bson").should be true
137
+ File.exists?("#{out_dir}/kellerkindTest/tests.metadata.json").should be true
138
+ File.exists?("#{out_dir}/kellerkindTest/system.indexes.bson").should be true
139
+ end
140
+
141
+ end
142
+
143
+ end
144
+
145
+ end
@@ -0,0 +1,58 @@
1
+ require 'spec_helper'
2
+
3
+ describe Kellerkind::Compress do
4
+
5
+ it{ should respond_to(:path) }
6
+ it{ should respond_to(:database_name) }
7
+
8
+ describe "instance methods" do
9
+ let(:out_dir) do
10
+ File.expand_path(File.join(File.dirname(__FILE__),"..", "tmp"))
11
+ end
12
+ let(:attributes) do
13
+ {
14
+ :database_name => "test",
15
+ :path => out_dir
16
+ }
17
+ end
18
+
19
+ it{ should respond_to(:gzip) }
20
+
21
+ context "with a hash of attributes" do
22
+ subject{ Kellerkind::Compress.new(attributes) }
23
+
24
+ it "then initializes the instance with the attributes values" do
25
+ subject.database_name.should eq attributes[:database_name]
26
+ subject.path.should eq attributes[:path]
27
+ end
28
+ end
29
+
30
+ describe "#gzip" do
31
+ let(:test_dump) do
32
+ File.join(out_dir, attributes[:database_name])
33
+ end
34
+
35
+ let(:compress) do
36
+ Kellerkind::Compress.new(:path => out_dir, :database_name => "test")
37
+ end
38
+
39
+ before do
40
+ FileUtils.mkdir_p(test_dump)
41
+ FileUtils.touch(File.join(test_dump, "foo.txt"))
42
+ compress.gzip
43
+ end
44
+
45
+ after do
46
+ Dir["#{out_dir}/*.tar.gz"].each{ |tar| FileUtils.rm(tar) }
47
+ FileUtils.rm_rf(test_dump)
48
+ end
49
+
50
+ it "tars and gzip the given database dump" do
51
+ Dir["#{out_dir}/#{compress.database_name}_*.tar.gz"].should have(1).item
52
+ end
53
+
54
+ end
55
+
56
+ end
57
+
58
+ end
@@ -0,0 +1,39 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Locking and unlocking process" do
4
+ let(:tmp_path) do
5
+ File.expand_path(File.join(File.dirname(__FILE__),"..", "tmp"))
6
+ end
7
+
8
+ let(:lock_file){ File.join(tmp_path,"Kellerkind.lock") }
9
+
10
+ before do
11
+ Kellerkind::Config.stub!(:lock_dir).and_return(tmp_path)
12
+ end
13
+
14
+ describe "#lock_process" do
15
+
16
+ after do
17
+ FileUtils.rm(lock_file)
18
+ end
19
+
20
+ it "creates a file do mark the process as locked" do
21
+ Kellerkind::Lock.lock_process
22
+ File.exists?(lock_file).should be true
23
+ end
24
+
25
+ end
26
+
27
+ describe "#unlock_process" do
28
+
29
+ before do
30
+ FileUtils.touch(lock_file)
31
+ end
32
+
33
+ it "removes the lock file to mark the process as runnable" do
34
+ Kellerkind::Lock.unlock_process
35
+ File.exists?(lock_file).should be false
36
+ end
37
+
38
+ end
39
+ end
File without changes
@@ -0,0 +1,7 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "Kellerkind" do
4
+ it "fails" do
5
+ fail "hey buddy, you should probably rename this file and start specing for real"
6
+ end
7
+ end
@@ -0,0 +1,12 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
3
+ require 'rspec'
4
+ require 'kellerkind'
5
+
6
+ # Requires supporting files with custom matchers and macros, etc,
7
+ # in ./support/ and its subdirectories.
8
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
9
+
10
+ RSpec.configure do |config|
11
+
12
+ end
metadata ADDED
@@ -0,0 +1,190 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: kellerkind
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Daniel Schmidt
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-07-05 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: virtus
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 0.5.5
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: 0.5.5
30
+ - !ruby/object:Gem::Dependency
31
+ name: minitar
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: 0.5.4
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: 0.5.4
46
+ - !ruby/object:Gem::Dependency
47
+ name: trollop
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: rspec
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ~>
68
+ - !ruby/object:Gem::Version
69
+ version: 2.13.0
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: 2.13.0
78
+ - !ruby/object:Gem::Dependency
79
+ name: rdoc
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ~>
84
+ - !ruby/object:Gem::Version
85
+ version: '3.12'
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ~>
92
+ - !ruby/object:Gem::Version
93
+ version: '3.12'
94
+ - !ruby/object:Gem::Dependency
95
+ name: bundler
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ~>
100
+ - !ruby/object:Gem::Version
101
+ version: 1.3.5
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ~>
108
+ - !ruby/object:Gem::Version
109
+ version: 1.3.5
110
+ - !ruby/object:Gem::Dependency
111
+ name: jeweler
112
+ requirement: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ~>
116
+ - !ruby/object:Gem::Version
117
+ version: 1.8.4
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ~>
124
+ - !ruby/object:Gem::Version
125
+ version: 1.8.4
126
+ description: Dumps mongodb databases and archives them.
127
+ email: dsci@code79.net
128
+ executables:
129
+ - kellerkind
130
+ extensions: []
131
+ extra_rdoc_files:
132
+ - LICENSE.txt
133
+ - README.md
134
+ files:
135
+ - .document
136
+ - .rspec
137
+ - Gemfile
138
+ - Gemfile.lock
139
+ - LICENSE.txt
140
+ - README.md
141
+ - Rakefile
142
+ - VERSION
143
+ - bin/kellerkind
144
+ - kellerkind.gemspec
145
+ - lib/kellerkind.rb
146
+ - lib/kellerkind/core/configuration.rb
147
+ - lib/kellerkind/core/ext.rb
148
+ - lib/kellerkind/core/set.rb
149
+ - lib/kellerkind/database/mongo.rb
150
+ - lib/kellerkind/dependencies.rb
151
+ - lib/kellerkind/system/compress.rb
152
+ - lib/kellerkind/system/die.rb
153
+ - lib/kellerkind/system/lock.rb
154
+ - lib/kellerkind/system/runner.rb
155
+ - spec/fixtures/mongodb.js
156
+ - spec/kellerkind/database/mongo_spec.rb
157
+ - spec/kellerkind/system/compress_spec.rb
158
+ - spec/kellerkind/system/lock_spec.rb
159
+ - spec/kellerkind/tmp/.gitkeep
160
+ - spec/kellerkind_spec.rb
161
+ - spec/spec_helper.rb
162
+ homepage: http://github.com/dsci/kellerkind
163
+ licenses:
164
+ - MIT
165
+ post_install_message:
166
+ rdoc_options: []
167
+ require_paths:
168
+ - lib
169
+ required_ruby_version: !ruby/object:Gem::Requirement
170
+ none: false
171
+ requirements:
172
+ - - ! '>='
173
+ - !ruby/object:Gem::Version
174
+ version: '0'
175
+ segments:
176
+ - 0
177
+ hash: 3218703124372926278
178
+ required_rubygems_version: !ruby/object:Gem::Requirement
179
+ none: false
180
+ requirements:
181
+ - - ! '>='
182
+ - !ruby/object:Gem::Version
183
+ version: '0'
184
+ requirements: []
185
+ rubyforge_project:
186
+ rubygems_version: 1.8.25
187
+ signing_key:
188
+ specification_version: 3
189
+ summary: Mongodb archiving tool.
190
+ test_files: []