machines 0.5.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +11 -0
- data/EXAMPLES.md +18 -0
- data/Gemfile +4 -0
- data/Guardfile +14 -0
- data/INSTALL.md +25 -0
- data/LICENSE +23 -0
- data/README.md +271 -0
- data/Rakefile +60 -0
- data/TODO.md +92 -0
- data/bin/machines +6 -0
- data/lib/machines/app_settings.rb +54 -0
- data/lib/machines/base.rb +13 -0
- data/lib/machines/checks.rb +63 -0
- data/lib/machines/cloud_machine.rb +33 -0
- data/lib/machines/command.rb +86 -0
- data/lib/machines/commandline.rb +148 -0
- data/lib/machines/configuration.rb +49 -0
- data/lib/machines/core.rb +117 -0
- data/lib/machines/database.rb +17 -0
- data/lib/machines/file_operations.rb +104 -0
- data/lib/machines/help.rb +30 -0
- data/lib/machines/installation.rb +151 -0
- data/lib/machines/log_command.rb +22 -0
- data/lib/machines/logger.rb +65 -0
- data/lib/machines/machinesfile.rb +25 -0
- data/lib/machines/named_buffer.rb +9 -0
- data/lib/machines/questions.rb +15 -0
- data/lib/machines/services.rb +24 -0
- data/lib/machines/upload.rb +29 -0
- data/lib/machines/version.rb +4 -0
- data/lib/machines.rb +19 -0
- data/lib/packages/abiword.rb +11 -0
- data/lib/packages/amazon_mp3.rb +4 -0
- data/lib/packages/awstats.rb +16 -0
- data/lib/packages/base.rb +14 -0
- data/lib/packages/chrome.rb +12 -0
- data/lib/packages/cruisecontrol.rb +22 -0
- data/lib/packages/dependencies.rb +10 -0
- data/lib/packages/docky.rb +36 -0
- data/lib/packages/dotfiles.rb +26 -0
- data/lib/packages/file_roller.rb +12 -0
- data/lib/packages/finalise.rb +4 -0
- data/lib/packages/firefox.rb +4 -0
- data/lib/packages/gedit.rb +11 -0
- data/lib/packages/git.rb +4 -0
- data/lib/packages/gmate.rb +33 -0
- data/lib/packages/gnome.rb +10 -0
- data/lib/packages/gnumeric.rb +11 -0
- data/lib/packages/hosts.rb +13 -0
- data/lib/packages/load_machines.rb +38 -0
- data/lib/packages/monit.rb +10 -0
- data/lib/packages/mysql.rb +46 -0
- data/lib/packages/nginx.rb +22 -0
- data/lib/packages/nginx_logrotate.rb +26 -0
- data/lib/packages/openbox.rb +35 -0
- data/lib/packages/passenger.rb +14 -0
- data/lib/packages/passenger_nginx.rb +8 -0
- data/lib/packages/postfix.rb +10 -0
- data/lib/packages/questions.rb +5 -0
- data/lib/packages/rbenv.rb +27 -0
- data/lib/packages/rvm.rb +20 -0
- data/lib/packages/save_machines.rb +4 -0
- data/lib/packages/slim.rb +6 -0
- data/lib/packages/sqlserver.rb +5 -0
- data/lib/packages/subtle.rb +29 -0
- data/lib/packages/sudo_mods.rb +6 -0
- data/lib/packages/time.rb +6 -0
- data/lib/packages/time_daily.rb +5 -0
- data/lib/packages/timezone.rb +10 -0
- data/lib/packages/unison.rb +5 -0
- data/lib/packages/virtualbox.rb +11 -0
- data/lib/packages/virtualbox_guest.rb +7 -0
- data/lib/packages/webapps.rb +36 -0
- data/lib/template/Machinesfile +48 -0
- data/lib/template/certificates/example.com.crt +0 -0
- data/lib/template/certificates/example.com.key +0 -0
- data/lib/template/certificates/selfsigned.crt +14 -0
- data/lib/template/certificates/selfsigned.key +16 -0
- data/lib/template/config.yml +98 -0
- data/lib/template/logrotate/app.erb +10 -0
- data/lib/template/logrotate/nginx.erb +12 -0
- data/lib/template/machines.yml +179 -0
- data/lib/template/misc/awstats.conf.erb +7 -0
- data/lib/template/misc/ntp.conf +7 -0
- data/lib/template/monit/conf.d/delayed_job.erb +11 -0
- data/lib/template/monit/conf.d/mysql.erb +7 -0
- data/lib/template/monit/conf.d/nginx +5 -0
- data/lib/template/monit/conf.d/postfix +7 -0
- data/lib/template/monit/conf.d/ssh +6 -0
- data/lib/template/monit/conf.d/system.erb +14 -0
- data/lib/template/monit/monitrc.erb +10 -0
- data/lib/template/monit/upstart.conf +16 -0
- data/lib/template/mysql/dbmaster.cnf +7 -0
- data/lib/template/mysql/dbslave.cnf +3 -0
- data/lib/template/nginx/app_server.conf.erb +87 -0
- data/lib/template/nginx/nginx.conf.erb +46 -0
- data/lib/template/nginx/upstart.conf.erb +21 -0
- data/lib/template/packages/custom.rb +17 -0
- data/lib/template/packages/productivity.rb +18 -0
- data/lib/template/slim/themes/dark/background.jpg +0 -0
- data/lib/template/slim/themes/dark/panel.png +0 -0
- data/lib/template/slim/themes/dark/slim.theme +39 -0
- data/lib/template/users/phil/dotfiles/bash_aliases +45 -0
- data/lib/template/users/phil/dotfiles/config/Trolltech.conf +4 -0
- data/lib/template/users/phil/dotfiles/config/gtk-3.0/settings.ini +9 -0
- data/lib/template/users/phil/dotfiles/config/openbox/autostart.sh +14 -0
- data/lib/template/users/phil/dotfiles/config/openbox/rc.xml +482 -0
- data/lib/template/users/phil/dotfiles/config/terminator/config +10 -0
- data/lib/template/users/phil/dotfiles/fonts.conf +15 -0
- data/lib/template/users/phil/dotfiles/gitconfig +27 -0
- data/lib/template/users/phil/dotfiles/gtkrc-2.0 +16 -0
- data/lib/template/users/phil/dotfiles/local/share/applications/mimeapps.list +4 -0
- data/lib/template/users/phil/dotfiles/unison/default.prf +33 -0
- data/lib/template/users/www/authorized_keys +0 -0
- data/lib/template/users/www/dotfiles/bash_aliases +40 -0
- data/lib/template/webapps.yml +75 -0
- data/machines.gemspec +44 -0
- data/spec/acceptance/dev_machine_spec.rb +22 -0
- data/spec/lib/machines/app_settings_spec.rb +106 -0
- data/spec/lib/machines/checks_spec.rb +105 -0
- data/spec/lib/machines/cloud_machine_spec.rb +36 -0
- data/spec/lib/machines/command_spec.rb +184 -0
- data/spec/lib/machines/commandline_spec.rb +299 -0
- data/spec/lib/machines/configuration_spec.rb +61 -0
- data/spec/lib/machines/core_spec.rb +299 -0
- data/spec/lib/machines/database_spec.rb +51 -0
- data/spec/lib/machines/file_operations_spec.rb +124 -0
- data/spec/lib/machines/help_spec.rb +22 -0
- data/spec/lib/machines/installation_spec.rb +176 -0
- data/spec/lib/machines/log_command_spec.rb +16 -0
- data/spec/lib/machines/logger_spec.rb +70 -0
- data/spec/lib/machines/machinesfile_spec.rb +34 -0
- data/spec/lib/machines/questions_spec.rb +73 -0
- data/spec/lib/machines/services_spec.rb +26 -0
- data/spec/lib/machines/upload_spec.rb +86 -0
- data/spec/lib/packages/abiword_spec.rb +20 -0
- data/spec/lib/packages/amazon_mp3_spec.rb +17 -0
- data/spec/lib/packages/awstats_spec.rb +26 -0
- data/spec/lib/packages/base_spec.rb +21 -0
- data/spec/lib/packages/chrome_spec.rb +30 -0
- data/spec/lib/packages/cruisecontrol_spec.rb +33 -0
- data/spec/lib/packages/dependencies_spec.rb +20 -0
- data/spec/lib/packages/docky_spec.rb +32 -0
- data/spec/lib/packages/dotfiles_spec.rb +44 -0
- data/spec/lib/packages/file_roller_spec.rb +69 -0
- data/spec/lib/packages/firefox_spec.rb +16 -0
- data/spec/lib/packages/gedit_spec.rb +20 -0
- data/spec/lib/packages/git_spec.rb +16 -0
- data/spec/lib/packages/gmate_spec.rb +39 -0
- data/spec/lib/packages/gnome_spec.rb +22 -0
- data/spec/lib/packages/gnumeric_spec.rb +21 -0
- data/spec/lib/packages/hosts_spec.rb +41 -0
- data/spec/lib/packages/load_machines_spec.rb +118 -0
- data/spec/lib/packages/monit_spec.rb +34 -0
- data/spec/lib/packages/mysql_spec.rb +69 -0
- data/spec/lib/packages/nginx_logrotate_spec.rb +80 -0
- data/spec/lib/packages/nginx_spec.rb +46 -0
- data/spec/lib/packages/openbox_spec.rb +41 -0
- data/spec/lib/packages/passenger_nginx_spec.rb +20 -0
- data/spec/lib/packages/passenger_spec.rb +26 -0
- data/spec/lib/packages/postfix_spec.rb +19 -0
- data/spec/lib/packages/questions_spec.rb +29 -0
- data/spec/lib/packages/rbenv_spec.rb +32 -0
- data/spec/lib/packages/rvm_spec.rb +31 -0
- data/spec/lib/packages/save_machines_spec.rb +51 -0
- data/spec/lib/packages/slim_spec.rb +22 -0
- data/spec/lib/packages/sqlserver_spec.rb +17 -0
- data/spec/lib/packages/timezone_spec.rb +27 -0
- data/spec/lib/packages/unison_spec.rb +17 -0
- data/spec/lib/packages/virtualbox_guest_spec.rb +25 -0
- data/spec/lib/packages/virtualbox_spec.rb +23 -0
- data/spec/lib/packages/webapps_spec.rb +70 -0
- data/spec/spec_helper.rb +103 -0
- data/spec/support/coverage.rb +8 -0
- data/spec/support/fake_out.rb +22 -0
- data/spec/support/fakefs_additions.rb +10 -0
- data/spec/support/minitest.rb +69 -0
- data/spec/support/vm_control.rb +54 -0
- data/tmp/.gitkeep +0 -0
- metadata +581 -0
data/.gitignore
ADDED
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
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,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
|
+
|