machines 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (180) hide show
  1. data/.gitignore +11 -0
  2. data/EXAMPLES.md +18 -0
  3. data/Gemfile +4 -0
  4. data/Guardfile +14 -0
  5. data/INSTALL.md +25 -0
  6. data/LICENSE +23 -0
  7. data/README.md +271 -0
  8. data/Rakefile +60 -0
  9. data/TODO.md +92 -0
  10. data/bin/machines +6 -0
  11. data/lib/machines/app_settings.rb +54 -0
  12. data/lib/machines/base.rb +13 -0
  13. data/lib/machines/checks.rb +63 -0
  14. data/lib/machines/cloud_machine.rb +33 -0
  15. data/lib/machines/command.rb +86 -0
  16. data/lib/machines/commandline.rb +148 -0
  17. data/lib/machines/configuration.rb +49 -0
  18. data/lib/machines/core.rb +117 -0
  19. data/lib/machines/database.rb +17 -0
  20. data/lib/machines/file_operations.rb +104 -0
  21. data/lib/machines/help.rb +30 -0
  22. data/lib/machines/installation.rb +151 -0
  23. data/lib/machines/log_command.rb +22 -0
  24. data/lib/machines/logger.rb +65 -0
  25. data/lib/machines/machinesfile.rb +25 -0
  26. data/lib/machines/named_buffer.rb +9 -0
  27. data/lib/machines/questions.rb +15 -0
  28. data/lib/machines/services.rb +24 -0
  29. data/lib/machines/upload.rb +29 -0
  30. data/lib/machines/version.rb +4 -0
  31. data/lib/machines.rb +19 -0
  32. data/lib/packages/abiword.rb +11 -0
  33. data/lib/packages/amazon_mp3.rb +4 -0
  34. data/lib/packages/awstats.rb +16 -0
  35. data/lib/packages/base.rb +14 -0
  36. data/lib/packages/chrome.rb +12 -0
  37. data/lib/packages/cruisecontrol.rb +22 -0
  38. data/lib/packages/dependencies.rb +10 -0
  39. data/lib/packages/docky.rb +36 -0
  40. data/lib/packages/dotfiles.rb +26 -0
  41. data/lib/packages/file_roller.rb +12 -0
  42. data/lib/packages/finalise.rb +4 -0
  43. data/lib/packages/firefox.rb +4 -0
  44. data/lib/packages/gedit.rb +11 -0
  45. data/lib/packages/git.rb +4 -0
  46. data/lib/packages/gmate.rb +33 -0
  47. data/lib/packages/gnome.rb +10 -0
  48. data/lib/packages/gnumeric.rb +11 -0
  49. data/lib/packages/hosts.rb +13 -0
  50. data/lib/packages/load_machines.rb +38 -0
  51. data/lib/packages/monit.rb +10 -0
  52. data/lib/packages/mysql.rb +46 -0
  53. data/lib/packages/nginx.rb +22 -0
  54. data/lib/packages/nginx_logrotate.rb +26 -0
  55. data/lib/packages/openbox.rb +35 -0
  56. data/lib/packages/passenger.rb +14 -0
  57. data/lib/packages/passenger_nginx.rb +8 -0
  58. data/lib/packages/postfix.rb +10 -0
  59. data/lib/packages/questions.rb +5 -0
  60. data/lib/packages/rbenv.rb +27 -0
  61. data/lib/packages/rvm.rb +20 -0
  62. data/lib/packages/save_machines.rb +4 -0
  63. data/lib/packages/slim.rb +6 -0
  64. data/lib/packages/sqlserver.rb +5 -0
  65. data/lib/packages/subtle.rb +29 -0
  66. data/lib/packages/sudo_mods.rb +6 -0
  67. data/lib/packages/time.rb +6 -0
  68. data/lib/packages/time_daily.rb +5 -0
  69. data/lib/packages/timezone.rb +10 -0
  70. data/lib/packages/unison.rb +5 -0
  71. data/lib/packages/virtualbox.rb +11 -0
  72. data/lib/packages/virtualbox_guest.rb +7 -0
  73. data/lib/packages/webapps.rb +36 -0
  74. data/lib/template/Machinesfile +48 -0
  75. data/lib/template/certificates/example.com.crt +0 -0
  76. data/lib/template/certificates/example.com.key +0 -0
  77. data/lib/template/certificates/selfsigned.crt +14 -0
  78. data/lib/template/certificates/selfsigned.key +16 -0
  79. data/lib/template/config.yml +98 -0
  80. data/lib/template/logrotate/app.erb +10 -0
  81. data/lib/template/logrotate/nginx.erb +12 -0
  82. data/lib/template/machines.yml +179 -0
  83. data/lib/template/misc/awstats.conf.erb +7 -0
  84. data/lib/template/misc/ntp.conf +7 -0
  85. data/lib/template/monit/conf.d/delayed_job.erb +11 -0
  86. data/lib/template/monit/conf.d/mysql.erb +7 -0
  87. data/lib/template/monit/conf.d/nginx +5 -0
  88. data/lib/template/monit/conf.d/postfix +7 -0
  89. data/lib/template/monit/conf.d/ssh +6 -0
  90. data/lib/template/monit/conf.d/system.erb +14 -0
  91. data/lib/template/monit/monitrc.erb +10 -0
  92. data/lib/template/monit/upstart.conf +16 -0
  93. data/lib/template/mysql/dbmaster.cnf +7 -0
  94. data/lib/template/mysql/dbslave.cnf +3 -0
  95. data/lib/template/nginx/app_server.conf.erb +87 -0
  96. data/lib/template/nginx/nginx.conf.erb +46 -0
  97. data/lib/template/nginx/upstart.conf.erb +21 -0
  98. data/lib/template/packages/custom.rb +17 -0
  99. data/lib/template/packages/productivity.rb +18 -0
  100. data/lib/template/slim/themes/dark/background.jpg +0 -0
  101. data/lib/template/slim/themes/dark/panel.png +0 -0
  102. data/lib/template/slim/themes/dark/slim.theme +39 -0
  103. data/lib/template/users/phil/dotfiles/bash_aliases +45 -0
  104. data/lib/template/users/phil/dotfiles/config/Trolltech.conf +4 -0
  105. data/lib/template/users/phil/dotfiles/config/gtk-3.0/settings.ini +9 -0
  106. data/lib/template/users/phil/dotfiles/config/openbox/autostart.sh +14 -0
  107. data/lib/template/users/phil/dotfiles/config/openbox/rc.xml +482 -0
  108. data/lib/template/users/phil/dotfiles/config/terminator/config +10 -0
  109. data/lib/template/users/phil/dotfiles/fonts.conf +15 -0
  110. data/lib/template/users/phil/dotfiles/gitconfig +27 -0
  111. data/lib/template/users/phil/dotfiles/gtkrc-2.0 +16 -0
  112. data/lib/template/users/phil/dotfiles/local/share/applications/mimeapps.list +4 -0
  113. data/lib/template/users/phil/dotfiles/unison/default.prf +33 -0
  114. data/lib/template/users/www/authorized_keys +0 -0
  115. data/lib/template/users/www/dotfiles/bash_aliases +40 -0
  116. data/lib/template/webapps.yml +75 -0
  117. data/machines.gemspec +44 -0
  118. data/spec/acceptance/dev_machine_spec.rb +22 -0
  119. data/spec/lib/machines/app_settings_spec.rb +106 -0
  120. data/spec/lib/machines/checks_spec.rb +105 -0
  121. data/spec/lib/machines/cloud_machine_spec.rb +36 -0
  122. data/spec/lib/machines/command_spec.rb +184 -0
  123. data/spec/lib/machines/commandline_spec.rb +299 -0
  124. data/spec/lib/machines/configuration_spec.rb +61 -0
  125. data/spec/lib/machines/core_spec.rb +299 -0
  126. data/spec/lib/machines/database_spec.rb +51 -0
  127. data/spec/lib/machines/file_operations_spec.rb +124 -0
  128. data/spec/lib/machines/help_spec.rb +22 -0
  129. data/spec/lib/machines/installation_spec.rb +176 -0
  130. data/spec/lib/machines/log_command_spec.rb +16 -0
  131. data/spec/lib/machines/logger_spec.rb +70 -0
  132. data/spec/lib/machines/machinesfile_spec.rb +34 -0
  133. data/spec/lib/machines/questions_spec.rb +73 -0
  134. data/spec/lib/machines/services_spec.rb +26 -0
  135. data/spec/lib/machines/upload_spec.rb +86 -0
  136. data/spec/lib/packages/abiword_spec.rb +20 -0
  137. data/spec/lib/packages/amazon_mp3_spec.rb +17 -0
  138. data/spec/lib/packages/awstats_spec.rb +26 -0
  139. data/spec/lib/packages/base_spec.rb +21 -0
  140. data/spec/lib/packages/chrome_spec.rb +30 -0
  141. data/spec/lib/packages/cruisecontrol_spec.rb +33 -0
  142. data/spec/lib/packages/dependencies_spec.rb +20 -0
  143. data/spec/lib/packages/docky_spec.rb +32 -0
  144. data/spec/lib/packages/dotfiles_spec.rb +44 -0
  145. data/spec/lib/packages/file_roller_spec.rb +69 -0
  146. data/spec/lib/packages/firefox_spec.rb +16 -0
  147. data/spec/lib/packages/gedit_spec.rb +20 -0
  148. data/spec/lib/packages/git_spec.rb +16 -0
  149. data/spec/lib/packages/gmate_spec.rb +39 -0
  150. data/spec/lib/packages/gnome_spec.rb +22 -0
  151. data/spec/lib/packages/gnumeric_spec.rb +21 -0
  152. data/spec/lib/packages/hosts_spec.rb +41 -0
  153. data/spec/lib/packages/load_machines_spec.rb +118 -0
  154. data/spec/lib/packages/monit_spec.rb +34 -0
  155. data/spec/lib/packages/mysql_spec.rb +69 -0
  156. data/spec/lib/packages/nginx_logrotate_spec.rb +80 -0
  157. data/spec/lib/packages/nginx_spec.rb +46 -0
  158. data/spec/lib/packages/openbox_spec.rb +41 -0
  159. data/spec/lib/packages/passenger_nginx_spec.rb +20 -0
  160. data/spec/lib/packages/passenger_spec.rb +26 -0
  161. data/spec/lib/packages/postfix_spec.rb +19 -0
  162. data/spec/lib/packages/questions_spec.rb +29 -0
  163. data/spec/lib/packages/rbenv_spec.rb +32 -0
  164. data/spec/lib/packages/rvm_spec.rb +31 -0
  165. data/spec/lib/packages/save_machines_spec.rb +51 -0
  166. data/spec/lib/packages/slim_spec.rb +22 -0
  167. data/spec/lib/packages/sqlserver_spec.rb +17 -0
  168. data/spec/lib/packages/timezone_spec.rb +27 -0
  169. data/spec/lib/packages/unison_spec.rb +17 -0
  170. data/spec/lib/packages/virtualbox_guest_spec.rb +25 -0
  171. data/spec/lib/packages/virtualbox_spec.rb +23 -0
  172. data/spec/lib/packages/webapps_spec.rb +70 -0
  173. data/spec/spec_helper.rb +103 -0
  174. data/spec/support/coverage.rb +8 -0
  175. data/spec/support/fake_out.rb +22 -0
  176. data/spec/support/fakefs_additions.rb +10 -0
  177. data/spec/support/minitest.rb +69 -0
  178. data/spec/support/vm_control.rb +54 -0
  179. data/tmp/.gitkeep +0 -0
  180. metadata +581 -0
@@ -0,0 +1,70 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'packages/webapps' do
4
+ before(:each) do
5
+ load_package('webapps')
6
+
7
+ $conf.from_hash(:user => {:name => 'username', :home => 'home_dir'}, :ruby => {:version => 'ruby_version'})
8
+ $conf.webapps = {'application' =>
9
+ AppBuilder.new(
10
+ 'scm' => 'github.com/project',
11
+ 'branch' => 'master',
12
+ 'name' => 'application',
13
+ 'url' => 'github url',
14
+ 'path' => '/home/users/application',
15
+ 'db_password' => 'pa55',
16
+ 'server_name' => 'app.dev'
17
+ )
18
+ }
19
+ $conf.from_hash(:awstats => {:path => 'stats_path'})
20
+ $conf.from_hash(:webserver => {:name => 'nginx', :path => 'nginx_path', :servers_dir => 'servers'})
21
+ $conf.from_hash(:db_server => {:address => 'db_master'})
22
+ FileUtils.mkdir_p 'nginx'
23
+ File.open('nginx/app_server.conf.erb', 'w') {|f| f.puts 'the template' }
24
+ end
25
+
26
+ it 'adds the following commands' do
27
+ $conf.environment = 'production'
28
+ eval_package
29
+ $conf.commands.map(&:info).join("\n").must_equal [
30
+ "TASK webapps - Sets up Web apps in config/webapps.yml using app_server.conf.erb. Copies SSL certs.",
31
+ "SUDO mkdir -p nginx_path/servers",
32
+ "RUN mkdir -p /home/users/application/releases",
33
+ "RUN mkdir -p /home/users/application/shared/config",
34
+ "RUN mkdir -p /home/users/application/shared/system",
35
+ "RUN mkdir -p /home/users/application/shared/log",
36
+ "UPLOAD buffer from nginx/app_server.conf.erb to /tmp/application.conf",
37
+ "SUDO cp -rf /tmp/application.conf nginx_path/servers/application.conf",
38
+ "RUN rm -rf /tmp/application.conf",
39
+ "SUDO mkdir -p /var/log/nginx",
40
+ 'SUDO grep "127.0.0.1 app.dev" /etc/hosts || echo "127.0.0.1 app.dev" >> /etc/hosts'
41
+ ].join("\n")
42
+ end
43
+
44
+ it 'creates a database.yml when requested' do
45
+ $conf.environment = 'production'
46
+ $conf.webapps['application'].write_yml = true
47
+ eval_package
48
+ $conf.commands.map(&:info).join("\n").must_match 'UPLOAD buffer from database.yml to /home/users/application/shared/config/database.yml'
49
+ end
50
+
51
+ it "doesn't make app structure when target is a development machine" do
52
+ $conf.from_hash(:ruby => {:gems_path => '.rbenv'})
53
+ $conf.environment = 'development'
54
+ eval_package
55
+ commandline = $conf.commands.map(&:info).join("\n")
56
+ commandline.must_equal [
57
+ "TASK webapps - Sets up Web apps in config/webapps.yml using app_server.conf.erb. Copies SSL certs.",
58
+ "SUDO mkdir -p nginx_path/servers",
59
+ "RUN git clone --quiet --branch master github.com/project /home/users/application",
60
+ "RUN cd /home/users/application && $HOME/.rbenv/bin/rbenv exec bundle",
61
+ "RUN cd /home/users/application && $HOME/.rbenv/bin/rbenv exec bundle --binstubs=.bin",
62
+ "UPLOAD buffer from nginx/app_server.conf.erb to /tmp/application.conf",
63
+ "SUDO cp -rf /tmp/application.conf nginx_path/servers/application.conf",
64
+ "RUN rm -rf /tmp/application.conf",
65
+ "SUDO mkdir -p /var/log/nginx",
66
+ 'SUDO grep "127.0.0.1 app.dev" /etc/hosts || echo "127.0.0.1 app.dev" >> /etc/hosts'
67
+ ].join("\n")
68
+ end
69
+ end
70
+
@@ -0,0 +1,103 @@
1
+ $LOAD_PATH << 'lib'
2
+
3
+ require 'bundler/setup'
4
+ require 'minitest/spec'
5
+ require 'mocha'
6
+ require 'stringio'
7
+ require 'fakefs/safe'
8
+
9
+ Dir['spec/support/*.rb'].each {|file| require File.join('./spec', 'support', File.basename(file)) }
10
+ require 'machines'
11
+ application_dir = $conf.application_dir
12
+
13
+ include Machines::AppSettings
14
+
15
+ # This is done so that Machines::Core.run doesn't collide with MiniTest::Unit::TestCase.run when included
16
+ module Machines::Core
17
+ alias :run_command :run
18
+ remove_method :run
19
+ end
20
+ MiniTest::Spec.add_setup_hook do |klass|
21
+ klass.instance_eval do
22
+ alias :run :run_command if respond_to?(:run_command)
23
+ end
24
+ end
25
+
26
+ MiniTest::Spec.add_setup_hook do
27
+ include Machines::Checks
28
+
29
+ $conf.clear
30
+ $conf.passwords = []
31
+ $conf.commands = []
32
+ $conf.tasks = {}
33
+ $conf.application_dir = application_dir
34
+
35
+ $input = StringIO.new
36
+ $output = StringIO.new
37
+ $terminal = HighLine.new($input, $output)
38
+
39
+ $debug = FakeOut.new
40
+ $file = FakeOut.new
41
+ $console = FakeOut.new
42
+ Machines::Command.debug = Machines::Logger.new $debug
43
+ Machines::Command.file = Machines::Logger.new $file
44
+ Machines::Command.console = Machines::Logger.new $console, :truncate => true
45
+
46
+ FakeFS.activate!
47
+ FileUtils.mkdir_p 'tmp'
48
+ end
49
+
50
+ MiniTest::Spec.add_teardown_hook do
51
+ FakeFS.deactivate!
52
+ FakeFS::FileSystem.clear
53
+ end
54
+
55
+ module MiniTest
56
+ module Assertions
57
+ def capture_io
58
+ yield
59
+ return $output.string
60
+ end
61
+ end
62
+ end
63
+
64
+ class MiniTest::Spec::Package < MiniTest::Spec
65
+ include Machines
66
+ include AppSettings, CloudMachine, Commandline, Configuration, Core, Database
67
+ include FileOperations, Installation, Machinesfile, Questions, Services
68
+ end
69
+
70
+ MiniTest::Spec.register_spec_type(/packages\//, MiniTest::Spec::Package)
71
+
72
+ def RealFS &block
73
+ FakeFS.deactivate!
74
+ yield block
75
+ ensure
76
+ FakeFS.activate!
77
+ end
78
+
79
+ def load_package name
80
+ RealFS do
81
+ @package_path = File.join($conf.application_dir, File.join('packages', "#{name}.rb"))
82
+ @package = File.read(@package_path)
83
+ end
84
+ end
85
+
86
+ def eval_package
87
+ eval @package, nil, @package_path
88
+ end
89
+
90
+ def save_yaml contents, path
91
+ File.open(path, 'w') do |f|
92
+ YAML.dump(contents, f)
93
+ end
94
+ end
95
+
96
+ def colored string, color
97
+ ending = string.scan(/(\n|\r)$/).flatten.first
98
+ string.sub!(/(\n|\r)$/, '')
99
+ $terminal.color(string, color.to_sym) + ending.to_s
100
+ end
101
+
102
+ require 'minitest/autorun'
103
+
@@ -0,0 +1,8 @@
1
+ if ENV['COVERAGE']
2
+ require 'simplecov'
3
+ SimpleCov.start do
4
+ add_filter '/spec/'
5
+ add_filter '/bin/'
6
+ end
7
+ end
8
+
@@ -0,0 +1,22 @@
1
+ class FakeOut
2
+ def initialize
3
+ @buffer = []
4
+ end
5
+
6
+ def inspect
7
+ @buffer.join("\n")
8
+ end
9
+
10
+ def print message
11
+ @buffer << message
12
+ end
13
+
14
+ def next
15
+ @buffer.delete_at(0)
16
+ end
17
+
18
+
19
+ def flush
20
+ end
21
+ end
22
+
@@ -0,0 +1,10 @@
1
+ module FakeFS
2
+ class File
3
+ class Stat
4
+ def mode
5
+ File.directory?(@file) ? 0755 : 0644
6
+ end
7
+ end
8
+ end
9
+ end
10
+
@@ -0,0 +1,69 @@
1
+ # Standard minitest diff calls the OS's diff command. FakeFS breaks diff because
2
+ # diff is looking for the files on disk but the files are written by Tempfile
3
+ # while FakeFS is still active. The following modules provide a pure ruby diff
4
+ # and override MiniTest::Assertions::diff to utilitize it.
5
+
6
+ module Diff
7
+ attr_accessor :diffs, :sequences
8
+
9
+ def self.diffs(old, new)
10
+ new, old, @diffs = new.lines.to_a, old.lines.to_a, []
11
+ build_sequences(old, new)
12
+ find_diffs(old, new, old.size, new.size)
13
+ end
14
+
15
+ private
16
+
17
+ def self.find_diffs(old, new, row, col)
18
+ if row > 0 && col > 0 && old[row-1] == new[col-1]
19
+ find_diffs(old, new, row-1, col-1)
20
+ @diffs << { :line => row, :change => :same, :string => old[row-1].strip }
21
+ elsif col > 0 && (row == 0 || @sequences[row][col-1] >= @sequences[row-1][col])
22
+ find_diffs(old, new, row, col-1)
23
+ @diffs << { :line => col, :change => :add, :string => new[col-1].strip }
24
+ elsif row > 0 && (col == 0 || @sequences[row][col-1] < @sequences[row-1][col])
25
+ find_diffs(old, new, row-1, col)
26
+ @diffs << { :line => row, :change => :delete, :string => old[row-1].strip }
27
+ end
28
+ end
29
+
30
+ def self.build_sequences(old, new)
31
+ rows, cols = old.size+1, new.size+1
32
+ @sequences = rows.times.map{|x|[0]*(x+1)}
33
+ rows.times.each do |row|
34
+ cols.times.each do |col|
35
+ @sequences[row][col] = if old[row-1] == new[col-1]
36
+ @sequences[row-1][col-1] + 1
37
+ else
38
+ [@sequences[row][col-1].to_i, @sequences[row-1][col].to_i].max
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+
45
+ module MiniTest
46
+ module Assertions
47
+ SYMBOLS = {:add => '+', :delete => '-', :same => ' '}
48
+
49
+ def diff exp, act
50
+ expect = mu_pp_for_diff exp
51
+ butwas = mu_pp_for_diff act
52
+ result = nil
53
+
54
+ need_to_diff =
55
+ (expect.include?("\n") ||
56
+ butwas.include?("\n") ||
57
+ expect.size > 30 ||
58
+ butwas.size > 30 ||
59
+ expect == butwas)
60
+
61
+ return "Expected: #{mu_pp exp}\n Actual: #{mu_pp act}" unless need_to_diff
62
+
63
+ Diff.diffs(expect, butwas).map do |diff|
64
+ SYMBOLS[diff[:change]] + diff[:string]
65
+ end.join("\n")
66
+ end
67
+ end
68
+ end
69
+
@@ -0,0 +1,54 @@
1
+ require 'net/ssh'
2
+
3
+ class VmControl
4
+ def initialize
5
+ @name = 'machinesvm'
6
+ end
7
+
8
+ def start
9
+ vboxmanage "startvm #{@name} --type headless"
10
+ end
11
+
12
+ def stop
13
+ vboxmanage "controlvm #{@name} savestate"
14
+ end
15
+
16
+ def kill
17
+ return unless state =~ /running/
18
+ vboxmanage "controlvm #{@name} poweroff"
19
+ end
20
+
21
+ def restore
22
+ vboxmanage "snapshot #{@name} restorecurrent"
23
+ end
24
+
25
+ def state
26
+ string = "showvminfo #{@name}"
27
+ output = vboxmanage string
28
+ output.scan(/State:\s+(.*)/).first.first
29
+ end
30
+
31
+ def vboxmanage command
32
+ send File.read('.vmcontrol').gsub("\n", ''), command
33
+ rescue Errno::ENOENT
34
+ raise '.vmcontrol does not exist. Add `local` to test using VMs on a Linux host or add `remote` to test on a VM running on Windows.'
35
+ end
36
+
37
+ private
38
+ def local command
39
+ output = `VBoxManage #{command}`
40
+ end
41
+
42
+ def remote command
43
+ output = ''
44
+ begin
45
+ Net::SSH.start('winhost', 'vbuser', :timeout => 10) do |ssh|
46
+ output = ssh.exec!("C:\\Program Files\\Oracle\\VirtualBox\\VBoxManage #{command}")
47
+ end
48
+ rescue Timeout::Error => e
49
+ raise 'Connection timed out. Did you start your SSH server on the host?'
50
+ end
51
+ output
52
+ end
53
+ end
54
+
data/tmp/.gitkeep ADDED
File without changes