machines 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+