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,151 @@
1
+ module Machines
2
+ module Installation
3
+ APTGET_QUIET = 'apt-get -q -y'
4
+
5
+ # Adds a PPA source and updates apt
6
+ # @param [String] name Name of the PPA
7
+ # @param [String] key_name What to check in apt-key list to ensure it installed
8
+ # add_ppa 'mozillateam/firefox-stable', 'mozilla'
9
+ def add_ppa name, key_name
10
+ [
11
+ Command.new("add-apt-repository ppa:#{name}", "apt-key list | grep -i #{key_name} #{echo_result}"),
12
+ update
13
+ ]
14
+ end
15
+
16
+ # Adds a DEB source
17
+ # @param [String] source URL of the package. If YOUR_UBUNTU_VERSION_HERE is included then it
18
+ # is replaced by the Ubuntu version name
19
+ # @param [Hash] options
20
+ # @option options [String] :key URL of key
21
+ # @option options [String] :name Used to check `apt-key list` to ensure it installed
22
+ # sudo deb 'http://dl.google.com/linux/deb/ stable main',
23
+ # :key => 'https://dl-ssl.google.com/linux/linux_signing_key.pub',
24
+ # :name => 'Google'
25
+ def deb source, options
26
+ command = "echo deb #{source} >> /etc/apt/sources.list"
27
+ if source =~ /YOUR_UBUNTU_VERSION_HERE/
28
+ command = "expr substr `cat /etc/lsb-release | grep DISTRIB_CODENAME` 18 20 | xargs -I YOUR_UBUNTU_VERSION_HERE #{command}"
29
+ end
30
+ [
31
+ Command.new(command, check_string(source.gsub(/ .*$/, ''), '/etc/apt/sources.list')),
32
+ Command.new("wget -q #{options[:key]} -O - | apt-key add -", "apt-key list | grep -i #{options[:name]} #{echo_result}"),
33
+ update
34
+ ]
35
+ end
36
+
37
+ # Preseed debconf to allow silent installs
38
+ # @param [String] app Name of application to configure
39
+ # @param [String] setting The setting to set
40
+ # @param [String] type Data type of the value
41
+ # @param value The value to set (Ruby types supported)
42
+ def debconf app, setting, type, value
43
+ command = "echo #{app} #{setting} #{type} #{value} | debconf-set-selections"
44
+ check = "debconf-get-selections | grep #{app} #{echo_result}"
45
+ Command.new(command, check)
46
+ end
47
+
48
+ # Download, extract, and remove an archive. Currently supports `zip` or `tar.gz`.
49
+ # @param [String] package Package name to extract
50
+ # @param [Hash] options
51
+ # @option options [Optional String] :to folder to clone or extract to (defaults to /usr/local/src)
52
+ def extract package, options = {}
53
+ name = File.basename(package)
54
+ cmd = package[/.zip/] ? 'unzip -qq' : 'tar -zxf'
55
+ dir = cmd =~ /unzip/ ? File.basename(name, '.zip') : File.basename(name).gsub(/\.tar.*/, '')
56
+ dest = options[:to] || '/usr/local/src'
57
+ Command.new("cd #{dest} && wget #{package} && #{cmd} #{name} && rm #{name} && cd -", check_dir("#{File.join(dest, dir)}"))
58
+ end
59
+
60
+ # Install a gem
61
+ # @param [String] package Name of the gem
62
+ # @param [Hash] options
63
+ # @option options [String] :version Optional version number
64
+ def gem package, options = {}
65
+ version = " -v \"#{options[:version]}\"" if options[:version]
66
+ Command.new("gem install #{package}#{version}", check_gem(package, options[:version]))
67
+ end
68
+
69
+ # Update gems
70
+ # @example Update Rubygems
71
+ # gem_update '--system'
72
+ def gem_update options = ''
73
+ Command.new("gem update #{options}", nil)
74
+ end
75
+
76
+ # Clone a project from a Git repository
77
+ # @param [String] url URL to clone
78
+ # @param [Hash] options
79
+ # @option options [Optional String] :to Folder to clone to
80
+ # @option options [Optional String] :tag Checkout this tag after cloning (requires :to)
81
+ # @option options [Optional String] :branch Switch this branch when cloning
82
+ def git_clone url, options = {}
83
+ raise ArgumentError.new('git_clone Must include a url and folder') if url.nil? || url.empty?
84
+ raise ArgumentError.new('specifying :tag also requires :to') if options[:tag] && options[:to].nil?
85
+ branch = "--branch #{options[:branch]} " if options[:branch]
86
+ command = "git clone --quiet #{branch}#{url}"
87
+ command << " #{options[:to]}" if options[:to]
88
+ command = Command.new(command, check_dir(options[:to]))
89
+ command = [command, Command.new("cd #{options[:to]} && git checkout #{options[:tag]}", "git name-rev --name-only HEAD | grep #{options[:tag]}")] if options[:tag]
90
+ command
91
+ end
92
+
93
+ # Installs one or more packages using apt, deb or git clone and install.sh (Ignores architecture differences)
94
+ # (See `extract` to just uncompress tar.gz or zip files)
95
+ # @param [Symbol, String, Array] packages can be:
96
+ # URL::
97
+ # Download from the specified URL and run `dpkg`
98
+ # Array or string (with no URL)::
99
+ # Run `apt` to install specified packages in the array or string
100
+ # Packages are installed separately to aid progress feedback
101
+ # Ensure this is the main package as dpkg get-selections is used to validate installation
102
+ # install %w(build-essential libssl-dev mysql-server) #=> Installs apt packages
103
+ # install 'http://example.com/my_package.deb', :cleanup => true #=> Installs a deb using dpkg then removes the deb
104
+ def install packages, options = {}
105
+ if packages.is_a?(String)
106
+ if packages =~ /^http:\/\//
107
+ commands = []
108
+ if packages =~ /\.deb$/i
109
+ name = File.basename(packages)
110
+ commands << Command.new("cd /tmp && wget #{packages} && dpkg -i --force-architecture #{name} && rm #{name} && cd -", nil)
111
+ else
112
+ commands << extract(packages, :to => '/tmp')
113
+ name = File.basename(packages).gsub(/\.(tar|zip).*/, '')
114
+ commands << Command.new("cd /tmp/#{name} && dpkg -i --force-architecture *.deb && cd - && rm -rf /tmp/#{name}", nil)
115
+ end
116
+ return commands
117
+ else
118
+ packages = [packages]
119
+ end
120
+ end
121
+
122
+ if packages.is_a?(Array)
123
+ commands = packages.map do |package|
124
+ Command.new("#{APTGET_QUIET} install #{package}", check_package(package))
125
+ end
126
+ end
127
+ commands
128
+ end
129
+
130
+ # Remove one or more packages
131
+ # @param [Array] packages Packages to remove
132
+ def uninstall packages
133
+ packages.map do |package|
134
+ Command.new("#{APTGET_QUIET} purge #{package}", check_package(package, false))
135
+ end
136
+ end
137
+
138
+ def update
139
+ Command.new("#{APTGET_QUIET} update > /tmp/apt-update.log", check_string('Reading package lists', '/tmp/apt-update.log'))
140
+ end
141
+
142
+ # Update, upgrade, autoremove, autoclean apt packages
143
+ # TODO: Check that check_command really checks the correct command with 'echo $?'
144
+ def upgrade
145
+ %w(update upgrade autoremove autoclean).map do |command|
146
+ Command.new("#{APTGET_QUIET} #{command}", check_command('echo $?', '0'))
147
+ end
148
+ end
149
+ end
150
+ end
151
+
@@ -0,0 +1,22 @@
1
+ module Machines
2
+ class LogCommand < Command
3
+ attr_reader :name, :description
4
+
5
+ def initialize name, description
6
+ @name = name
7
+ @description = description
8
+ end
9
+
10
+ def run
11
+ Command.console.log ''
12
+ Command.console.log ' ' + info, :color => :info, :progress => progress
13
+ Command.file.log ''
14
+ Command.file.log info, :color => :info
15
+ end
16
+
17
+ def info
18
+ "TASK #{@name} - #{@description}"
19
+ end
20
+ end
21
+ end
22
+
@@ -0,0 +1,65 @@
1
+ require 'date'
2
+
3
+ module Machines
4
+ class Logger
5
+ HighLine.color_scheme = HighLine::ColorScheme.new do |cs|
6
+ cs[:highlight] = [:bold, :blue]
7
+ cs[:warning] = [:yellow]
8
+ cs[:failure] = [:red]
9
+ cs[:success] = [:green]
10
+ cs[:info] = [:blue]
11
+ end
12
+
13
+ def initialize to, options = {}
14
+ @to = to
15
+ @truncate = options[:truncate]
16
+ end
17
+
18
+ # Logs a message
19
+ # @param [String] message Message to display
20
+ # @param [Hash] options
21
+ # @option options [String] :progress Prepends number of commands completed
22
+ # @option options [String] :color Color the text (overrides :success)
23
+ # @option options [Bool] :newline Set to false to print on same line and return to start of it (:color not supported)
24
+ def log message, options = {}
25
+ message = format_message(message, options)
26
+ @to.print message
27
+ end
28
+
29
+ def flush
30
+ @to.flush
31
+ end
32
+
33
+ private
34
+ def format_message message, options
35
+ message ||= '(no message)'
36
+ message = merge_multiple_lines_of message if @truncate
37
+ message = blank_out_passwords message
38
+ message = truncate message if @truncate
39
+ color = options[:color]
40
+ message = $terminal.color(message, color) if color
41
+ options[:newline] = true if options[:newline].nil?
42
+ message += newline_or_return options[:newline]
43
+ message
44
+ end
45
+
46
+ def truncate message
47
+ width = $terminal.output_cols
48
+ message.size >= width ? message[0..(width - 5)] + '...' : message
49
+ end
50
+
51
+ def merge_multiple_lines_of message
52
+ message.gsub(/(".*?)\n.*(".*)/m, '\1...\2')
53
+ end
54
+
55
+ def newline_or_return newline
56
+ newline ? "\n" : "\r"
57
+ end
58
+
59
+ def blank_out_passwords message
60
+ $conf.passwords && $conf.passwords.any? ? message.gsub(/(#{($conf.passwords).join('|')})/, "*****") : message
61
+ end
62
+
63
+ end
64
+ end
65
+
@@ -0,0 +1,25 @@
1
+ module Machines
2
+ module Machinesfile
3
+ def package name
4
+ if name == 'Machinesfile'
5
+ error = 'Cannot find Machinesfile. Use `machines generate` to create a template.'
6
+ else
7
+ error = "Cannot find custom or built-in package #{name}."
8
+ end
9
+ package = load_and_eval File.join('packages', "#{name}.rb")
10
+ package ||= load_and_eval File.join($conf.application_dir, 'packages', "#{name}.rb")
11
+ package || raise(LoadError, error, caller)
12
+ end
13
+
14
+ private
15
+ def load_and_eval package_name
16
+ if File.exists?(package_name)
17
+ eval(File.read(package_name), nil, "eval: #{package_name}")
18
+ true
19
+ else
20
+ false
21
+ end
22
+ end
23
+ end
24
+ end
25
+
@@ -0,0 +1,9 @@
1
+ class NamedBuffer < StringIO
2
+ attr_reader :name
3
+
4
+ def initialize name, string
5
+ super string
6
+ @name = name
7
+ end
8
+ end
9
+
@@ -0,0 +1,15 @@
1
+ module Machines
2
+ module Questions
3
+ def enter_password(type, confirm = true)
4
+ begin
5
+ password = ask("Enter #{type} password: ") { |question| question.echo = false }
6
+ break unless confirm
7
+ password_confirmation = ask('Confirm the password: ') { |question| question.echo = false }
8
+ say "Passwords do not match, please re-enter" unless password == password_confirmation
9
+ end while password != password_confirmation
10
+ $conf.passwords << password if $conf.passwords && password.size > 4 && password != 'password'
11
+ password
12
+ end
13
+ end
14
+ end
15
+
@@ -0,0 +1,24 @@
1
+ module Machines
2
+ module Services
3
+ # Stop a daemon
4
+ def stop daemon
5
+ Command.new("service #{daemon} stop", check_daemon(daemon, false))
6
+ end
7
+
8
+ # Start a daemon
9
+ # @param [String] daemon Name of the service to start
10
+ # @param [Hash] options
11
+ # @option options [Boolean] :check Set to false to disable the check (e.g. start hostname, :check => false)
12
+ def start daemon, options = {}
13
+ check = options[:check] || check_daemon(daemon)
14
+ Command.new("service #{daemon} start", check)
15
+ end
16
+
17
+ # Restart a daemon
18
+ # @param [String] daemon Name of the service to restart
19
+ def restart daemon
20
+ Command.new("service #{daemon} restart", check_daemon(daemon))
21
+ end
22
+ end
23
+ end
24
+
@@ -0,0 +1,29 @@
1
+ module Machines
2
+ class Upload < Command
3
+ attr_accessor :local, :remote
4
+
5
+ def initialize(local, remote, check)
6
+ super(nil, check)
7
+ @local, @remote = local, remote
8
+ end
9
+
10
+ def run
11
+ process do
12
+ @@scp.upload!(local, remote, {:recursive => local.is_a?(String) && File.directory?(local)})
13
+ end
14
+ end
15
+
16
+ def info
17
+ name = local
18
+ if local.is_a?(NamedBuffer)
19
+ if local.name
20
+ name = "buffer from #{local.name}"
21
+ else
22
+ name = "unnamed buffer"
23
+ end
24
+ end
25
+ "UPLOAD #{name} to #{remote}"
26
+ end
27
+ end
28
+ end
29
+
@@ -0,0 +1,4 @@
1
+ module Machines
2
+ VERSION = '0.5.1'
3
+ end
4
+
data/lib/machines.rb ADDED
@@ -0,0 +1,19 @@
1
+ # Machines allows simple configuration of development, staging and production computers or images for ec2
2
+ require 'active_support'
3
+ require 'app_conf'
4
+ require 'erb'
5
+ require 'fileutils'
6
+ require 'highline/import'
7
+ require 'net/ssh'
8
+ require 'net/scp'
9
+ require 'ostruct'
10
+ require 'json'
11
+ require 'tempfile'
12
+ require 'webrick/utils'
13
+ require 'yaml'
14
+
15
+ $conf = AppConf.new
16
+ $conf.application_dir = File.dirname(__FILE__)
17
+
18
+ require 'machines/base'
19
+
@@ -0,0 +1,11 @@
1
+ task :abiword, 'Install a lightweight word processor' do
2
+ sudo install ['abiword']
3
+ end
4
+
5
+ task :abiword_associations, 'Setup file associations for Abiword' do
6
+ mimetypes = 'application/x-abiword;application/msword;application/rtf;'
7
+ mimetypes.split(';').each do |mimetype|
8
+ run append "#{mimetype}=abiword.desktop", :to => '.local/share/applications/mimeapps.list'
9
+ end
10
+ end
11
+
@@ -0,0 +1,4 @@
1
+ task :amazon_mp3, 'Download and install MP3 downloader from Amazon' do
2
+ sudo install 'http://www.hilltopyodeler.com/packages/AmazonMP3-InstallerForUbuntuNewerThan-9.04.tar.gz'
3
+ end
4
+
@@ -0,0 +1,16 @@
1
+ task :awstats, 'Install AWStats' do
2
+ sudo install 'awstats'
3
+ remote_file = 'https://raw.github.com/PhilT/bin/master/awstats_render'
4
+ local_file = '/usr/local/bin/awstats_render'
5
+ sudo "wget #{remote_file} -O #{local_file}", check_file(local_file)
6
+ sudo chmod '+x', local_file
7
+
8
+ $conf.webapps.each do |app_name, app|
9
+ stats_path = "/etc/awstats/awstats.#{app.server_name}.conf"
10
+ sudo create_from 'misc/awstats.conf.erb', settings: app, to: stats_path
11
+ app_stats = "#{$conf.approots}/#{app_name}_stats"
12
+ run mkdir "#{app_stats}/data"
13
+ run mkdir "#{app_stats}/public"
14
+ end
15
+ end
16
+
@@ -0,0 +1,14 @@
1
+ task :base, 'Install base packages for compiling Ruby and libraries' do
2
+ sudo install [
3
+ 'build-essential', # Needed to build most libraries for Ruby
4
+ 'zlib1g-dev', # Compression library
5
+ 'libpcre3-dev', # Needed by Nginx
6
+ 'ruby1.9.1-dev', # Needed by Ruby
7
+ 'libreadline-dev', # Needed by IRB
8
+ 'libxml2-dev', # Needed by Nokogiri
9
+ 'libxslt1-dev', # Needed by Nokogiri
10
+ 'libssl-dev', # Needed by OpenSSL in Nginx
11
+ 'libncurses5-dev', # Needed by Curses in Stdlib
12
+ ]
13
+ end
14
+
@@ -0,0 +1,12 @@
1
+ task :chrome, 'Add chrome stable repo and installs (set use_opensource to use chromium)' do
2
+ if $conf.use_opensource
3
+ sudo add_ppa 'chromium-daily/stable', 'chromium'
4
+ sudo install 'chromium-browser'
5
+ else
6
+ sudo deb 'http://dl.google.com/linux/deb/ stable main',
7
+ :key => 'https://dl-ssl.google.com/linux/linux_signing_key.pub',
8
+ :name => 'Google'
9
+ sudo install 'google-chrome-stable'
10
+ end
11
+ end
12
+
@@ -0,0 +1,22 @@
1
+ task :cruisecontrol, 'Install, configure and set to start on boot' do
2
+ run git_clone 'https://github.com/thoughtworks/cruisecontrol.rb.git'
3
+ #HACK: PATHS are added to .profile which is not run on a non-login shell. NET::Ssh creates non-login shells
4
+ if $conf.ruby.gems_path =~ /^.rbenv/
5
+ bin = '~/.rbenv/bin/rbenv exec'
6
+ else
7
+ bin = ''
8
+ end
9
+
10
+ run "cd cruisecontrol.rb && #{bin} bundle"
11
+ $conf.webapps.each do |name, webapp|
12
+ run "cd cruisecontrol.rb && #{bin} ruby ./cruise add #{webapp.title} -r #{webapp.scm}"
13
+ end
14
+
15
+ sudo copy 'cruisecontrol.rb/daemon/cruise', '/etc/init.d/cruise'
16
+ sudo "update-rc.d cruise defaults"
17
+ sudo replace "CRUISE_USER = .*", with: "CRUISE_USER = '#{$conf.user}'", in: '/etc/init.d/cruise'
18
+ sudo replace "CRUISE_HOME = .*", with: "CRUISE_HOME = '#{$conf.user_home}/cruisecontrol.rb'", in: '/etc/init.d/cruise'
19
+
20
+ run append "ActionMailer::Base.smtp_settings = {address: '#{$conf.mail.address}', domain: '#{$conf.mail.domain}'}", to: ".cruise/site_config.rb"
21
+ end
22
+
@@ -0,0 +1,10 @@
1
+ task :dependencies, 'Dependencies required for various commands to run' do
2
+ sudo update
3
+
4
+ sudo install [ # Needed by
5
+ 'debconf-utils', # debconf
6
+ 'python-software-properties', # add_ppa
7
+ 'gconf2', # configure
8
+ ]
9
+ end
10
+
@@ -0,0 +1,36 @@
1
+ task :docky, 'Install and configure Docky a dock and app launcher' do
2
+ sudo install 'docky' # Panel/Dock launcher
3
+ sudo install 'gnome-system-monitor' # System info, processes, resources, file system usage
4
+
5
+ # Ensure Docky does not try to reset preferences
6
+ run configure '/apps/docky-2/Docky/Interface/DockPreferences/FirstRun' => false
7
+
8
+ root = '/apps/docky-2/Docky/Interface/DockPreferences/Dock1'
9
+
10
+ # Preferences
11
+ run configure "#{root}/ZoomPercent" => 1.5
12
+ run configure "#{root}/Autohide" => 'Intellihide'
13
+ run configure "#{root}/FadeOnHide" => true
14
+ run configure "#{root}/FadeOpacity" => 50
15
+
16
+ # Launchers
17
+ apps = %w(pcmanfm google-chrome firefox terminator gedit abiword gnumeric gimp inkscape audacious2)
18
+ run configure "#{root}/Launchers" => apps.map {|app| "file:///usr/share/applications/#{app}.desktop"}
19
+ run configure "#{root}/SortList" => apps.map {|app| "/usr/share/applications/#{app}.desktop"}
20
+
21
+ run configure "#{root}/Plugins" => %w(Trash Clock GMail Weather)
22
+
23
+ # Clock
24
+ run configure '/apps/docky-2/Clock/ClockDockItem/ShowDate' => true
25
+ run configure '/apps/docky-2/Clock/ClockDockItem/ShowDigital' => true
26
+ run configure '/apps/docky-2/Clock/ClockDockItem/ShowMilitary' => true
27
+
28
+ # GMail
29
+ run configure '/apps/docky-2/GMail/GMailPreferences/RefreshRate' => 10
30
+ run configure '/apps/docky-2/GMail/GMailPreferences/User' => "phil@"
31
+
32
+ # Weather
33
+ run configure '/apps/docky-2/WeatherDocklet/WeatherPreferences/Location' => ['London\\, United Kingdom']
34
+ run configure '/apps/docky-2/WeatherDocklet/WeatherPreferences/Metric' => true
35
+ end
36
+
@@ -0,0 +1,26 @@
1
+ username = $conf.machine.user
2
+
3
+ task :dotfiles, "Upload files in users/#{username}/dotfiles, prepend a dot and substitute some bashrc vars" do
4
+ Dir["users/#{username}/dotfiles/*"].each do |source|
5
+ run upload source, ".#{File.basename(source)}" if File.exists?(source)
6
+ end
7
+ run chmod 600, '$HOME/.ssh/id_rsa' if File.exists?("users/#{username}/dotfiles/ssh/id_rsa")
8
+
9
+ run mkdir '$HOME/.ssh'
10
+ run chmod 700, '$HOME/.ssh'
11
+ $conf.hosts.to_hash.each do |host, address|
12
+ run "ssh-keyscan -H #{host} >> $HOME/.ssh/known_hosts"
13
+ end if $conf.hosts
14
+
15
+ if $conf.set_rails_env_for.nil? || $conf.set_rails_env_for.include?($conf.environment)
16
+ run append "export RAILS_ENV=#{$conf.environment}", to: '.profile'
17
+ end
18
+ run append "export CDPATH=#{$conf.appsroot}", to: '.profile'
19
+
20
+ authorized_key_file = "users/#{username}/authorized_keys"
21
+ if File.exists?(authorized_key_file)
22
+ run upload authorized_key_file, '.ssh/authorized_keys'
23
+ run chmod 600, '.ssh/authorized_keys'
24
+ end
25
+ end
26
+
@@ -0,0 +1,12 @@
1
+ task :file_roller, 'Install file-roller archive manager' do
2
+ sudo install ['file-roller']
3
+ end
4
+
5
+ # Mimetypes can be discovered by looking in /usr/share/applications/*.desktop
6
+ task :file_roller_associations, 'Setup file associations for file-roller' do
7
+ mimetypes = 'application/x-7z-compressed;application/x-7z-compressed-tar;application/x-ace;application/x-alz;application/x-ar;application/x-arj;application/x-bzip;application/x-bzip-compressed-tar;application/x-bzip1;application/x-bzip1-compressed-tar;application/x-cabinet;application/x-cbr;application/x-cbz;application/x-cd-image;application/x-compress;application/x-compressed-tar;application/x-cpio;application/x-deb;application/x-ear;application/x-ms-dos-executable;application/x-gtar;application/x-gzip;application/x-gzpostscript;application/x-java-archive;application/x-lha;application/x-lhz;application/x-lrzip;application/x-lrzip-compressed-tar;application/x-lzip;application/x-lzip-compressed-tar;application/x-lzma;application/x-lzma-compressed-tar;application/x-lzop;application/x-lzop-compressed-tar;application/x-rar;application/x-rar-compressed;application/x-rpm;application/x-rzip;application/x-tar;application/x-tarz;application/x-stuffit;application/x-war;application/x-xz;application/x-xz-compressed-tar;application/x-zip;application/x-zip-compressed;application/x-zoo;application/zip;'
8
+ mimetypes.split(';').each do |mimetype|
9
+ run append "#{mimetype}=file-roller.desktop", :to => '.local/share/applications/mimeapps.list'
10
+ end
11
+ end
12
+
@@ -0,0 +1,4 @@
1
+ task :finalise, 'Make sure all libraries are up to date and clean' do
2
+ sudo upgrade
3
+ end
4
+
@@ -0,0 +1,4 @@
1
+ task :firefox, 'install firefox' do
2
+ sudo install %w(firefox)
3
+ end
4
+
@@ -0,0 +1,11 @@
1
+ task :gedit, 'Install basic programmers editor and set associations' do
2
+ sudo install [
3
+ 'python-gi-cairo', # gedit throws exceptions when closing files without this
4
+ 'gedit',
5
+ ]
6
+
7
+ run append 'text/plain=gedit.desktop', :to => '.local/share/applications/mimeapps.list'
8
+ run append 'application/x-ruby=gedit.desktop', :to => '.local/share/applications/mimeapps.list'
9
+ run append 'application/x-shellscript=gedit.desktop', :to => '.local/share/applications/mimeapps.list'
10
+ end
11
+
@@ -0,0 +1,4 @@
1
+ task :git, 'Install Git' do
2
+ sudo install %w(git-core)
3
+ end
4
+
@@ -0,0 +1,33 @@
1
+ task :gmate, 'Clone and install gmate for gEdit from Github and set some preferences and plugins' do
2
+ dir = File.join $conf.appsroot, 'gmate'
3
+
4
+ sudo install ['python-pyinotify'] # Required for gEdit Open
5
+ sudo install ['ack-grep'] # Find in project
6
+ run git_clone 'git://github.com/gmate/gmate.git', :to => dir
7
+ run "cd #{dir} && echo \\n | ./install.sh"
8
+
9
+ run configure '/apps/gedit-2/plugins/active-plugins' => %w(text_tools smart_indent align rails_hotkeys trailsave gemini rubyonrailsloader gedit_openfiles quickhighlightmode completion time docinfo filebrowser snippets spell indent tabswitch)
10
+
11
+ indent = '/apps/gedit-2/plugins/smart_indent'
12
+ run configure "#{indent}/haml_tab_size" => 2,
13
+ "#{indent}/js_tab_size" => 2,
14
+ "#{indent}/markdown_tab_size" => 2,
15
+ "#{indent}/plain_text_tab_size" => 2,
16
+ "#{indent}/sass_tab_size" => 2,
17
+ "#{indent}/yaml_tab_size" => 2
18
+
19
+ editor = '/apps/gedit-2/preferences/editor/'
20
+ run configure "#{editor}bracket_matching/bracket_matching" => true,
21
+ "#{editor}current_line/highlight_current_line" => true,
22
+ "#{editor}cursor_position/restore_cursor_position" => true,
23
+ "#{editor}line_numbers/display_line_numbers" => true,
24
+ "#{editor}right_margin/display_right_margin" => true,
25
+ "#{editor}right_margin/right_margin_position" => 120,
26
+ "#{editor}colors/scheme" => 'railscasts',
27
+ "#{editor}tabs/insert_spaces" => true,
28
+ "#{editor}tabs/tabs_size" => 2,
29
+ "#{editor}wrap_mode/wrap_mode" => 'GTK_WRAP_NONE',
30
+ "#{editor}save/create_backup_copy" => false
31
+ run configure '/apps/gedit-2/preferences/ui/toolbar/toolbar_visible' => false
32
+ end
33
+
@@ -0,0 +1,10 @@
1
+ task :gnome, 'Set Gnome display preferences' do
2
+ run configure '/apps/metacity/general/titlebar_font' => 'Arial Bold 10',
3
+ '/apps/metacity/general/num_workspaces' => 1,
4
+ '/apps/nautilus/preferences/desktop_font' => 'Sans 9',
5
+ '/apps/nautilus/preferences/default_folder_viewer' => 'compact_view',
6
+ '/desktop/gnome/interface/font_name' => 'Sans 9',
7
+ '/desktop/gnome/interface/document_font_name' => 'Sans 9',
8
+ '/desktop/gnome/interface/monospace_font_name' => 'Monospace 10'
9
+ end
10
+
@@ -0,0 +1,11 @@
1
+ task :gnumeric, 'Install gnumeric lightweight spreadsheet' do
2
+ sudo install ['gnumeric']
3
+ end
4
+
5
+ task :gnumeric_associations, 'Setup file associations for Gnumeric' do
6
+ mimetypes = 'application/x-gnumeric;application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;text/csv;application/msexcel'
7
+ mimetypes.split(';').each do |mimetype|
8
+ run append "#{mimetype}=gnumeric.desktop", :to => '.local/share/applications/mimeapps.list'
9
+ end
10
+ end
11
+
@@ -0,0 +1,13 @@
1
+ task :hosts, 'Setup /etc/hosts' do
2
+ # Sets hostname according to the following: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=316099
3
+ fqdn = $conf.machine.hostname
4
+ hostname = $conf.machine.hostname.split('.').first
5
+ sudo write "127.0.0.1 #{fqdn} localhost.localdomain localhost\n127.0.1.1 #{hostname}\n", :to => '/etc/hosts'
6
+ sudo write $conf.machine.hostname, :to => '/etc/hostname'
7
+ sudo start 'hostname', :check => check_command('hostname', $conf.machine.hostname)
8
+
9
+ $conf.hosts.to_hash.each do |host, address|
10
+ sudo append "#{address} #{host}", :to => '/etc/hosts' if host && address
11
+ end if $conf.hosts
12
+ end
13
+