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
data/.gitignore ADDED
@@ -0,0 +1,11 @@
1
+ *.gem
2
+ .bin
3
+ .bundle
4
+ .yardoc
5
+ doc
6
+ coverage
7
+ log
8
+ tmp
9
+ Gemfile.lock
10
+ .vmcontrol
11
+
data/EXAMPLES.md ADDED
@@ -0,0 +1,18 @@
1
+ It's easy to add new packages if you need something new on your current install.
2
+ I added the following to `packages/printer.rb`:
3
+
4
+ task :printer, 'Install Samsung Unified Linux Drivers' do
5
+ sudo deb 'http://www.bchemnet.com/suldr/ debian extra', :key => 'http://www.bchemnet.com/suldr/suldr.gpg', :name => 'Samsung'
6
+ sudo install 'samsungmfp-data'
7
+ end
8
+
9
+ I added it to my `Machinesfile`:
10
+
11
+ package :printer
12
+
13
+ Then ran it locally:
14
+
15
+ machines build task=printer machine=Desktop host=localhost user=phil hostname=ignored
16
+
17
+ Now the drivers for my printer are installed.
18
+
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://www.rubygems.org"
2
+
3
+ gemspec
4
+
data/Guardfile ADDED
@@ -0,0 +1,14 @@
1
+ guard 'bundler' do
2
+ watch('Gemfile')
3
+ watch('machines.gemspec')
4
+ end
5
+
6
+ guard 'minitest', :test_file_patterns => 'lib/**/*_spec.rb', :cli => '-Ilib' do
7
+ watch(%r{^spec/(.*)_spec\.rb$})
8
+ watch(%r{^lib/(machines|packages)(.+)\.rb$}) { |m| "spec/lib/#{m[1]}#{m[2]}_spec.rb" }
9
+ watch(%r{^spec/support/(.+)\.rb$}) { |m| "spec/support_specs/#{m[1]}_spec.rb" }
10
+
11
+ # String watch patterns are matched with simple '=='
12
+ watch('lib/machines.rb') { "lib/machines_spec.rb" }
13
+ end
14
+
data/INSTALL.md ADDED
@@ -0,0 +1,25 @@
1
+ Install freeSSHd
2
+ ----------------------------------------
3
+
4
+ * Do not install as a service
5
+ * Load FreeSSHd and click on the system tray icon
6
+ * Under "Users" tab "Add" a user
7
+ ** Login: vbuser
8
+ ** Authorization: Public key
9
+ ** User can use: Shell
10
+ * Copy the public rsa key from your Ubuntu VM and save it in `C:\Program Files (x86)\freeSSHd\vbuser` with no extension
11
+
12
+ Install VM
13
+ ----------------------------------------
14
+
15
+ 1. Grab the ISO from http://archive.ubuntu.com/ubuntu/dists/precise/main/installer-amd64/current/images/netboot/mini.iso
16
+ 2. Install with
17
+ * username: user
18
+ * password: password
19
+ * Select software: OpenSSH server
20
+ 3. Set Network Adapter 1 to Bridged Adapter
21
+ 4. Grab the IP address: `ifconfig`
22
+ 5. On your development VM do (replace `IP_ADDRESS` with the IP address you grabbed in the previous step) `sudo sh -c 'echo IP_ADDRESS machinesvm >> /etc/hosts'`
23
+ 6. Take a snapshot of the new VM
24
+ 7. Finally, try `rake vm:win:kill` to close the running VM
25
+
data/LICENSE ADDED
@@ -0,0 +1,23 @@
1
+ (The MIT License)
2
+
3
+ Copyright (c) 2009, 2010, 2011, 2012 Phil Thompson
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+
data/README.md ADDED
@@ -0,0 +1,271 @@
1
+ Machines - A custom Ubuntu system in less than 15 minutes
2
+ ===========================================================
3
+
4
+ Setup Ubuntu development and server **Machines** locally or in the cloud for developing and hosting Ruby, Rails and related environments.
5
+
6
+ Run commands like:
7
+
8
+ sudo install %w(build-essential zlib1g-dev libpcre3-dev)
9
+ sudo write "127.0.1.1\t#{$conf.hostname}", :to => '/etc/hosts'
10
+ sudo append "192.168.1.2\tserver", :to => '/etc/hosts'
11
+ run download $conf.nginx.url
12
+ run create_from 'nginx/nginx.conf.erb', :to => File.join($conf.nginx.path, 'conf', 'nginx.conf')
13
+
14
+ Upgrade passenger:
15
+
16
+ machines build phil_workstation passenger_nginx
17
+
18
+
19
+ Status
20
+ -----------------------------------------------------------
21
+
22
+ September 2012
23
+
24
+ * Released 0.5.1
25
+ * Working development and server builds.
26
+ * Cloud deployments to complete.
27
+
28
+ Features
29
+ -----------------------------------------------------------
30
+
31
+ * An opinionated Ubuntu configuration script with sensible defaults
32
+ * Easily override the defaults with configuration options and custom ruby
33
+ * Supports several cloud services
34
+ * Default template supports Nginx, Passenger, Ruby, Rails, MySQL, Git, Monit, Logrotate
35
+ * Preconfigured Ruby & Rails light development environment (Openbox or Subtle)
36
+ * Bring up new instances fully configured in less than 15 minutes
37
+
38
+ Motivation
39
+ -----------------------------------------------------------
40
+
41
+ Configuration management is a complex topic. I wanted to reduce some of the variables (single target platform, single development environment) to provide a simpler solution.
42
+
43
+
44
+ Overview
45
+ -----------------------------------------------------------
46
+
47
+ The top level script is the `Machinesfile`. This contains the packages to include. Packages contain the commands to run. Default packages are provided by Machines. Default packages can be overridden and new ones created.
48
+
49
+ Commands are added to a queue with `sudo` or `run`. [lib/packages](https://github.com/PhilT/machines/tree/master/lib/packages) contains the packages you can add in the `Machinesfile` in Machines. Once the build starts the commands are run and shown with the current progress.
50
+
51
+ Installation and Configuration
52
+ -----------------------------------------------------------
53
+
54
+ ### Install the gem
55
+
56
+ gem install machines
57
+
58
+ ### Generate an example build script
59
+
60
+ machines new example
61
+
62
+ Creates the `example` folder and copies in an example template.
63
+
64
+ ### Configure your deployment
65
+
66
+ Take a look at the generated project. It contains several folders with templates and
67
+ configuration settings for various programs, your `Machinesfile` and the various `.yml` files.
68
+
69
+ `machines.yml` is your machine architecture. Here you'll add all the computers in your environment.
70
+
71
+ `webapps.yml` lists the web applications you develop and maintain.
72
+
73
+ `config.yml` contains settings for various packages. Version numbers, Cloud configuration, paths, etc.
74
+
75
+ `users/` contains user specific preferences, dotfiles, etc
76
+
77
+ * Create your architecture in `machines.yml`
78
+ * Add you webapps in `webapps.yml`
79
+ * Edit the build script (`Machinesfile`)
80
+ * Add your websites certificates and amazon private key (if required)
81
+ * Edit settings in `config.yml`
82
+ * Run `machines override <package>` to copy a default package to your project for alteration (Use `machines packages` to see a list)
83
+ * Setup your `users/` folders
84
+ * Add `~/.ssh/id_rsa.pub` public key from all users machines that need access, to the `users/www/authorized_keys` file
85
+
86
+ ### Prepare the target machine
87
+
88
+ * Download the latest minimal Ubuntu 12.04 image or ISO (Precise Pangolin)
89
+ * [64bit image](http://archive.ubuntu.com/ubuntu/dists/precise/main/installer-amd64/current/images/netboot/boot.img.gz)
90
+ * [64bit ISO](http://archive.ubuntu.com/ubuntu/dists/precise/main/installer-amd64/current/images/netboot/mini.iso)
91
+ * [32bit image](http://archive.ubuntu.com/ubuntu/dists/precise/main/installer-i386/current/images/netboot/boot.img.gz)
92
+ * [32bit ISO](http://archive.ubuntu.com/ubuntu/dists/precise/main/installer-i386/current/images/netboot/mini.iso)
93
+ * Images can be written to USB with (Be sure to eject the drive correctly):
94
+ * `gunzip boot.img.gz && sudo dd if=boot.img of=/dev/sdX` where `sdX` is your USB device (use `dmesg` to get this)
95
+ * Insert the USB stick and boot from it to install Ubuntu
96
+ * Install SSH Server & note the IP address
97
+
98
+ sudo apt-get update && sudo apt-get -y install openssh-server && ifconfig
99
+
100
+ ### Check the Machinesfile
101
+
102
+ machines dryrun <machine>
103
+ cat log/output.log
104
+
105
+
106
+ ### Check the machine
107
+
108
+ ssh-keygen -R <host ip> # remove host from known_hosts file (handy when testing)
109
+ $ ssh <IP ADDRESS> # Make sure you can connect to the machine
110
+
111
+
112
+ ### Build the machine
113
+
114
+ $ machines build <machine>
115
+
116
+
117
+ Console output:
118
+
119
+ * Running commands are displayed in gray
120
+ * Tasks show in blue
121
+ * Successfully completed commands are displayed in green
122
+ * Failures show in red
123
+ * Yellow indicates there was no check for the command
124
+
125
+ While running open another terminal to view detailed output:
126
+
127
+ tail -f output.log
128
+
129
+
130
+ Commandline Options
131
+ -----------------------------------------------------------
132
+
133
+ machines COMMAND
134
+ COMMAND can be:
135
+ htpasswd Generates basic auth in webserver/conf/htpasswd
136
+ new <DIR> Generates an example machines project in DIR
137
+ dryrun Logs commands but does not run them
138
+ tasks Lists the available tasks
139
+ build <machine> [task] Builds your chosen machine. Optionally, build just one task
140
+ packages Lists the available packages
141
+ override <PACKAGE> Copies the default package into project/packages so it can be edited/overidden
142
+
143
+
144
+ Global settings
145
+ -----------------------------------------------------------
146
+
147
+ Machines uses a gem I wrote called [app_conf](https://github.com/PhilT/app_conf). It allows settings
148
+ to be loaded from YAML and also set using Ruby. Machines uses it both internally and for package settings.
149
+ Some of the settings set and used by Machines are:
150
+
151
+ * `$conf.appsroot` - Where applications are cloned
152
+ * `$conf.commands` - All the commands that are to be run
153
+ * `$conf.environment` - Environment of the machine (also at `$conf.machine.environment`)
154
+ * `$conf.machine` - Configuration for the selected machine
155
+ * `$conf.machine_name` - Name of the selected machine
156
+ * `$conf.roles` - List of roles for selected machine (also available as `$conf.machine.roles`)
157
+ * `$conf.tasks` - Names of the tasks - Used to check dependencies and display tasks the help
158
+ * `$conf.user` - The selected user name
159
+ * `$conf.user_home` - Users home folder e.g. `/home/phil`
160
+ * `$conf.users` - A list of the available users
161
+ * `$conf.webapps` - A hash of webapps keyed from the name of the webapp specified in webapps.yml
162
+
163
+ Take a look at `template/*.yml` for more.
164
+
165
+
166
+ Setting up a test VM
167
+ -----------------------------------------------------------
168
+
169
+ Make sure you've downloaded one of the ISOs from the list in *Prepare the target machine*.
170
+
171
+ 1. Download and install [VirtualBox](https://www.virtualbox.org/wiki/Downloads)
172
+ 1. Oracle VirtualBox -> New
173
+ * Name: machinesvm
174
+ * Operating System: Linux
175
+ * Version: Ubuntu (64 bit)
176
+ 1. Settings -> Network -> Adapter 2 -> Enable Network Adapter
177
+ * Attached to: Host-only Adapter
178
+ 1. Start -> Media Source Folder Icon -> mini.iso
179
+ 1. Installer boot menu -> Install -> Accept defaults except for:
180
+ * eth0 primary interface
181
+ * Full name for the new user: user
182
+ * Username for your account: user
183
+ * Choose a password for the new user: password
184
+ * Re-enter password to verify: password
185
+ * YES to partition disks (choose partition entire disk if asked)
186
+ * Add OpenSSH from application installer menu
187
+ 1. Devices -> CD/DVD Devices -> Uncheck mini.iso
188
+ 1. Reboot
189
+ * ubuntu Login: user
190
+ * Password: password
191
+ 1. Run `ifconfig` and make a note of eth1 inet addr
192
+ 1. Take a snapshot (restore before each test run)
193
+
194
+
195
+ What's happening under the hood
196
+ -----------------------------------------------------------
197
+
198
+ * An ssh connection is established to send all commands and uploads
199
+ * Ssh uses the specified user and then sudo is added to commands that require it
200
+ * When sudo is needed for file uploads. The file is uploaded to /tmp then sudo cp'd to the destination
201
+ * When `package` is called in the `Machinesfile` that file is loaded either from the projects packages folder
202
+ or from the Machines packages if not found in the project
203
+
204
+
205
+ Limitations
206
+ -----------------------------------------------------------
207
+ * Only one user per machine. Although other users could be setup with additional build runs.
208
+ * One environment per machine - Again additional machines could be configured to use the same physical machine (although could be problems with some environment settings)
209
+ * Servers use www (by default) for nginx/apache, passenger and deployments
210
+ * The system has been designed to allow a certain flexibility in the configuration although some things
211
+ may not yet be totally configurable it should be possible to add or modify the relevant package
212
+ * We are currently focused on Ruby 1.9.2 (Moving to 1.9.3 soon), Rails 3 and Passenger 3
213
+ * Some commands may not properly escape quotes when used with sudo (e.g. append and replace). This may be addressed in a future release
214
+
215
+
216
+ Development, Patches, Pull Requests
217
+ -----------------------------------------------------------
218
+
219
+ * Fork the project
220
+ * Test drive your feature addition or bug fix
221
+ * Commit, do not mess with Rakefile, version, or history
222
+ * Send me a pull request. Please use topic branches
223
+ * Feel free to add/enhance packages and submit pull requests
224
+ * Package tests are a bit of a pain but do catch a lot of potential issues
225
+
226
+
227
+ References
228
+ -----------------------------------------------------------
229
+
230
+ ### APIs
231
+
232
+ * <http://aws.amazon.com/documentation/>
233
+ * <http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/>
234
+ * <http://net-ssh.github.com/>
235
+ * <http://rdoc.info/github/grempe/amazon-ec2>
236
+
237
+
238
+ ### General
239
+
240
+ * Rails deployment guide: <http://kris.me.uk/2010/11/15/rails3-rvm-passenger3-apache.html>
241
+ * Another Rails deployment guide: <http://thoughtsincomputation.com/posts/deploying-in-harmony-capistrano-rvm-bundler-and-git>
242
+ * EC2 deployment for Rails with Rubber: <http://ginzametrics.com/deploy-rails-app-to-ec2-with-rubber.html>
243
+ * MySQL and EBS: <http://aws.amazon.com/articles/1663>
244
+ * Nginx, passenger manual compile: <http://extralogical.net/articles/howto-compile-nginx-passenger.html>
245
+ * Nginx Passenger setup guide: <https://github.com/jnstq/rails-nginx-passenger-ubuntu>
246
+ * Nginx configuration: <http://articles.slicehost.com/2009/3/5/ubuntu-intrepid-nginx-configuration>
247
+ * Bundler Deployment: <http://gembundler.com/deploying.html>
248
+
249
+
250
+ ### RVM
251
+
252
+ * Multiple gemsets in passenger <http://blog.ninjahideout.com/posts/the-path-to-better-rvm-and-passenger-integration>
253
+ * Nginx and Passenger <http://blog.ninjahideout.com/posts/a-guide-to-a-nginx-passenger-and-rvm-server>
254
+
255
+ ### Ubuntu minimal install guides
256
+
257
+ * <http://wiki.dennyhalim.com/ubuntu-minimal-desktop>
258
+ * <http://www.psychocats.net/ubuntu/minimal>
259
+ * <https://help.ubuntu.com/community/Installation/LowMemorySystems>
260
+
261
+ Acknowledgements
262
+ -----------------------------------------------------------
263
+
264
+ Thanks to all the people that published the hundreds of articles, blog posts and APIs I've read.
265
+
266
+
267
+ Copyright
268
+ -----------------------------------------------------------
269
+
270
+ Copyright (c) 2010, 2011, 2012 Phil Thompson. See LICENSE for details.
271
+
data/Rakefile ADDED
@@ -0,0 +1,60 @@
1
+ require 'bundler'
2
+ require 'yard'
3
+ require 'highline/import'
4
+ require 'rake'
5
+ require 'rake/testtask'
6
+
7
+ task :default => [:coverage, :yard, :install]
8
+
9
+ YARD::Rake::YardocTask.new
10
+
11
+ Rake::TestTask.new(:spec) do |t|
12
+ t.libs << './spec'
13
+ t.pattern = './spec/{support_specs,lib}/**/*_spec.rb'
14
+ end
15
+
16
+ Rake::TestTask.new(:acceptance) do |t|
17
+ t.libs << './spec'
18
+ t.pattern = './spec/{acceptance}/**/*_spec.rb'
19
+ end
20
+
21
+ desc 'Generate code coverage'
22
+ task :coverage do
23
+ ENV['COVERAGE'] = 'true'
24
+ Rake::Task['spec'].invoke
25
+ ENV['COVERAGE'] = nil
26
+ end
27
+
28
+ desc 'Build and install the gem'
29
+ task :install do
30
+ gemspec_path = Dir['*.gemspec'].first
31
+ spec = eval(File.read(gemspec_path))
32
+
33
+ result = `gem build #{gemspec_path} 2>&1`
34
+ if result =~ /Successfully built/
35
+ Bundler.with_clean_env do
36
+ system "gem uninstall -x -a #{spec.name} 2>&1"
37
+ system "gem install #{spec.file_name} --no-rdoc --no-ri 2>&1"
38
+ end
39
+ else
40
+ raise result
41
+ end
42
+ end
43
+
44
+ desc 'Run machines'
45
+ task :run do
46
+ $LOAD_PATH << 'lib'
47
+ require 'machines'
48
+ Machines::Base.new.start(ARGV[1])
49
+ end
50
+
51
+ desc 'Git tags and sends the gem to rubygems'
52
+ task :release do
53
+ gemspec_path = Dir['*.gemspec'].first
54
+ spec = eval(File.read(gemspec_path))
55
+
56
+ system "git tag -f -a v#{spec.version} -m 'Version #{spec.version}'"
57
+ system "git push --tags"
58
+ system "gem push #{spec.file_name}"
59
+ end
60
+
data/TODO.md ADDED
@@ -0,0 +1,92 @@
1
+ TODO next
2
+ ----------------------------------------
3
+
4
+ Support missing environment (e.g. scm machine)
5
+ `machines dryrun/build` with no machine name should list the machines available
6
+ DRY up per user config by creating a "common" user config that all users pull default config from
7
+ DRY up further by having default templates in the same way that packages default to built-in ones
8
+ (In other words remove as much as possible from evmachines)
9
+ Complement this by providing a command to view packages and templates
10
+ Move dotfiles to a repo so they can be managed across projects
11
+ Handle apt-get error 110 and retry
12
+
13
+
14
+ Cloud
15
+ ----------------------------------------
16
+ Use EC2 IP address for connecting to database servers
17
+ Create elastic IP address for web servers
18
+
19
+ * Assign private/public keys
20
+ * Create security groups - check they exist and modify or create as required
21
+ Use roles to assign security groups
22
+ * everything gets the ssh group (open port 22)
23
+ * app role gets the web group (open port 80, 443)
24
+
25
+
26
+ EC2 - Look at assigning and freeing elastic IP addresses
27
+
28
+ * machines.machine.address = an elastic IP address
29
+ * machnies.machine.ec2.instance_id = the ec2 id
30
+ * Set $conf.machines_changed when creating a new instance
31
+ * Set up minimal Ubuntu on EC2
32
+ * Must allow multiple dev machines to access cloud (so multiple SSH keys must be assigned)
33
+
34
+ Package and Task Tasks
35
+ ----------------------------------------
36
+
37
+ Support running multiple tasks - e.g. `machines build passenger passenger_nginx nginx`
38
+ Any methods other than `append` that cannot be repeatedly run?
39
+ Display additional install notes for a particular package (at the end of installation) - e.g. printer setup requires Windows share to be setup
40
+ CODE/DOC: Describe difference between package and task or merge packages with tasks if possible
41
+ BUG: Report error if task is nested
42
+ ?? Define packages as a group of tasks?
43
+
44
+
45
+ Misc Tasks
46
+ ----------------------------------------
47
+
48
+ Remove percentage from progress once command has completed
49
+ DOC: How webapps environment specific settings override default settings and how to set your own
50
+ DOC: All config files
51
+ DOC: Why we use ~/.profile (with links)
52
+ On initial SSH connection to machine, test we have an Internet connection. Fail if not.
53
+ Add the check that was run to `CHECK_FAILED/CHECK_PASSED`
54
+ Output progress to log/<machine_name>_progress.log
55
+ Rename output log to log/<machine_name>_output.log
56
+ DOC: machines desc <package> - Should display a detailed description of the package
57
+ machines list - Display a list of machines to build (or maybe machines build/dryrun with no machinename)
58
+ ?? base package may not be needed on DB installs
59
+ ?? Default path for Nginx install is /usr/local - Is it installed correctly for non-default paths?
60
+ ?? I have a new webapp - How can I add it to a server that has already been installed?
61
+ BUG: Uploads throw exception if local file is missing - Get upload to check file existence when adding to queue
62
+ BUG: CTRL+C doesn't quite exit cleanly
63
+ Check $conf.db_server is picked up and used to write database.yml on qa/staging/production
64
+
65
+ Allow $conf.webapps[app].path to be overridden from webapps.yml
66
+ ?? Does webapps.yml structure get preserved? (e.g. when modifying keys and resaving)
67
+ Fix guard notifications
68
+
69
+ Enable YAML to refer to other settings in the same file
70
+ development machines should clone repos
71
+
72
+ Should be able to run Passenger install easily for new versions
73
+ Can more files be ERB templates? Standardise. Need examples (can't remember what they were)
74
+ webapps has gaps in testing (e.g. ssl)
75
+ escape $$ in passwords
76
+ turn off debug output by default
77
+ DOC: webapps.yml loaded into $conf
78
+ MySQL root pass is not set properly
79
+ Recommended practice for overwritting project with new template. Use Git
80
+ Set cron to sensible times /etc/crontab [DEV]
81
+ Need a way to see optional tasks that are not run as part of full build
82
+
83
+ Would `set :variable_name, value` be better than `$conf.variable = value`?
84
+ Need a better DSL to handle $conf and also paths File.join is so verbose
85
+ For exmaple, instead of:
86
+ File.join($conf.appsroot, 'subfolder')
87
+ How about:
88
+ path :appsroot, 'subfolder'
89
+ rvm ruby@gemset --rvmrc to generate passenger compatible .rvmrc
90
+ setup memcached
91
+ passenger_nginx was installed with rvmsudo. Need to test it still works with just sudo
92
+
data/bin/machines ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'machines'
4
+
5
+ Machines::Base.new.execute(ARGV)
6
+
@@ -0,0 +1,54 @@
1
+ module Machines
2
+ module AppSettings
3
+ class AppBuilder < OpenStruct
4
+ def get_binding
5
+ binding
6
+ end
7
+ end
8
+
9
+ def generate_passwords
10
+ $conf.webapps.keys.each do |webapp|
11
+ $conf.webapps[webapp].keys.each do |environment|
12
+ env_settings = $conf.webapps[webapp][environment]
13
+ next unless env_settings.is_a?(AppConf)
14
+ env_settings.password = generate_password unless env_settings.password
15
+ end
16
+ end
17
+ end
18
+
19
+ def load_and_generate_passwords_for_webapps
20
+ $conf.load('webapps.yml')
21
+ generate_passwords
22
+ $conf.save('webapps', 'webapps.yml')
23
+ end
24
+
25
+ # Loads application settings from webapps.yml and makes them available in $conf.webapps as an
26
+ # AppBuilder (bindable OpenStruct) so it can be used in ERB templates to generate config files
27
+ # @param [Array] apps Names of the apps to configure
28
+ def load_app_settings(apps)
29
+ load_and_generate_passwords_for_webapps
30
+ webapps = $conf.webapps.to_hash
31
+ $conf.clear :webapps
32
+ $conf.webapps = {}
33
+ webapps.each do |app_name, settings|
34
+ next unless apps.nil? || apps.include?(app_name)
35
+ environment = settings[$conf.environment.to_s] || {}
36
+ settings['name'] = app_name
37
+ settings['path'] = File.join($conf.appsroot, app_name)
38
+ public_path = "#{$conf.environment == 'development' ? '' : 'current/'}public"
39
+ settings['root'] = File.join(settings['path'], public_path)
40
+
41
+ environment.each { |k, v| settings[k] = v }
42
+ if settings['cert']
43
+ settings['ssl'] = true unless settings['ssl']
44
+ settings['ssl_key'] = settings['cert'] + '.key'
45
+ settings['ssl_crt'] = settings['cert'] + '.crt'
46
+ end
47
+
48
+ $conf.webapps[app_name] = AppBuilder.new(settings.reject{|k, v| v.is_a?(Hash) })
49
+ end
50
+ end
51
+
52
+ end
53
+ end
54
+
@@ -0,0 +1,13 @@
1
+ module Machines
2
+ class Base
3
+ files = Dir[File.join($conf.application_dir, 'machines/**/*.rb')]
4
+ files.reject!{|name| File.basename(name) == 'base.rb' }
5
+ files.sort.each do |lib|
6
+ require lib
7
+ path = ActiveSupport::Inflector.camelize(File.basename(lib, '.rb'))
8
+ module_or_class = eval(path, nil, "eval: #{path}") rescue nil
9
+ include module_or_class unless module_or_class.nil? || module_or_class.is_a?(Class)
10
+ end
11
+ end
12
+ end
13
+
@@ -0,0 +1,63 @@
1
+ module Machines
2
+ module Checks
3
+ def echo_result
4
+ '&& echo CHECK PASSED || echo CHECK FAILED'
5
+ end
6
+
7
+ def check_package package, exists = true
8
+ "dpkg --get-selections | grep #{package}.*#{exists ? '' : 'de'}install #{echo_result}"
9
+ end
10
+
11
+ def check_gem gem, version = nil
12
+ version = " -v #{version}" if version
13
+ "gem search #{gem}#{version} --installed #{echo_result}"
14
+ end
15
+
16
+ def check_file file, exists = true
17
+ "test #{exists ? '' : '! '}-s #{file} #{echo_result}"
18
+ end
19
+
20
+ def check_link link
21
+ "test -L #{link} #{echo_result}"
22
+ end
23
+
24
+ def check_dir dir, exists = true
25
+ "test #{exists ? '' : '! '}-d #{dir} #{echo_result}"
26
+ end
27
+
28
+ def check_perms perms, path
29
+ perms = perms.to_s
30
+ mods = %w(--- --x -w- -wx r-- r-x rw- rwx)
31
+ "ls -la #{path} | grep #{mods[perms[0..0].to_i]}#{mods[perms[1..1].to_i]}#{mods[perms[2..2].to_i]} #{echo_result}"
32
+ end
33
+
34
+ def check_owner user, path
35
+ "ls -la #{path} | grep \"#{user}.*#{user}\" #{echo_result}"
36
+ end
37
+
38
+ def check_string string, file
39
+ "grep \"#{string}\" #{file} #{echo_result}"
40
+ end
41
+
42
+ def check_daemon daemon, exists = true
43
+ command = 'ps aux'
44
+ search_for = "| grep #{daemon}"
45
+ remove_grep = '| grep -v grep'
46
+ negative = "| grep -v #{daemon} " unless exists
47
+ "#{command} #{search_for} #{remove_grep} #{negative}#{echo_result}"
48
+ end
49
+
50
+ def check_init_d name
51
+ "test -L /etc/rc0.d/K20#{name} #{echo_result}"
52
+ end
53
+
54
+ def check_command command, match = nil
55
+ if match
56
+ "#{command} | grep #{match} #{echo_result}"
57
+ else
58
+ "#{command} #{echo_result}"
59
+ end
60
+ end
61
+ end
62
+ end
63
+