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