stackfu 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +24 -0
- data/Manifest +118 -0
- data/README +0 -0
- data/README.md +218 -0
- data/Rakefile +73 -0
- data/bin/stackfu +10 -0
- data/lib/stackfu/api_hooks.rb +17 -0
- data/lib/stackfu/app.rb +69 -0
- data/lib/stackfu/commands/command.rb +127 -0
- data/lib/stackfu/commands/config_command.rb +43 -0
- data/lib/stackfu/commands/deploy_command.rb +144 -0
- data/lib/stackfu/commands/dump_command.rb +101 -0
- data/lib/stackfu/commands/generate_command.rb +107 -0
- data/lib/stackfu/commands/help_command.rb +28 -0
- data/lib/stackfu/commands/list_command.rb +26 -0
- data/lib/stackfu/commands/publish_command.rb +108 -0
- data/lib/stackfu/commands/server_command.rb +124 -0
- data/lib/stackfu/helpers/providers_credentials.rb +82 -0
- data/lib/stackfu/helpers/rendering.rb +201 -0
- data/lib/stackfu/operating_systems.rb +30 -0
- data/lib/stackfu.rb +88 -0
- data/stackfu-installer/config/01-controls.yml +17 -0
- data/stackfu-installer/config/02-requirements.yml +3 -0
- data/stackfu-installer/config/03-scripts.yml +16 -0
- data/stackfu-installer/config/04-validations.yml +3 -0
- data/stackfu-installer/script/dotfiles_installation.sh.erb +22 -0
- data/stackfu-installer/script/github_credentials_setup.sh.erb +31 -0
- data/stackfu-installer/script/nginx_and_passenger.sh.erb +83 -0
- data/stackfu-installer/script/redis_installation.sh.erb +33 -0
- data/stackfu-installer/script/resque_installation.sh.erb +7 -0
- data/stackfu-installer/script/ruby_environment.sh.erb +20 -0
- data/stackfu-installer/script/stackfu.sh.erb +114 -0
- data/stackfu-installer/stack.yml +5 -0
- data/stackfu.gemspec +60 -0
- data/templates/01-controls.yml.erb +31 -0
- data/templates/02-requirements.yml.erb +26 -0
- data/templates/03-scripts.yml.erb +34 -0
- data/templates/04-validations.yml.erb +17 -0
- data/templates/script.sh.erb +7 -0
- data/templates/stack.yml.erb +17 -0
- data/test/fixtures/add_server_error +7 -0
- data/test/fixtures/deployment_add +7 -0
- data/test/fixtures/deployment_add_error +8 -0
- data/test/fixtures/deployments +7 -0
- data/test/fixtures/logs +7 -0
- data/test/fixtures/logs_partial +7 -0
- data/test/fixtures/plugin_add +6 -0
- data/test/fixtures/plugin_add_error +8 -0
- data/test/fixtures/plugin_deployment_add +7 -0
- data/test/fixtures/plugin_not_found +7 -0
- data/test/fixtures/plugin_unauthorized +8 -0
- data/test/fixtures/plugins +7 -0
- data/test/fixtures/plugins_by_name +7 -0
- data/test/fixtures/plugins_by_name_other +7 -0
- data/test/fixtures/plugins_empty +7 -0
- data/test/fixtures/plugins_multiple +7 -0
- data/test/fixtures/providers +7 -0
- data/test/fixtures/providers_servers +7 -0
- data/test/fixtures/server_add +6 -0
- data/test/fixtures/server_add_dupe +7 -0
- data/test/fixtures/server_add_error +7 -0
- data/test/fixtures/server_delete +7 -0
- data/test/fixtures/server_delete_error +7 -0
- data/test/fixtures/servers +7 -0
- data/test/fixtures/servers_by_name +7 -0
- data/test/fixtures/servers_empty +8 -0
- data/test/fixtures/servers_not_found +26 -0
- data/test/fixtures/servers_unauthorized +8 -0
- data/test/fixtures/servers_webbynode +7 -0
- data/test/fixtures/stack/stackfu-installer/config/01-controls.yml +22 -0
- data/test/fixtures/stack/stackfu-installer/config/02-requirements.yml +1 -0
- data/test/fixtures/stack/stackfu-installer/config/03-scripts.yml +23 -0
- data/test/fixtures/stack/stackfu-installer/config/04-validations.yml +1 -0
- data/test/fixtures/stack/stackfu-installer/script/dotfiles_installation.sh.erb +22 -0
- data/test/fixtures/stack/stackfu-installer/script/github_credentials_setup.sh.erb +31 -0
- data/test/fixtures/stack/stackfu-installer/script/nginx_and_passenger.sh.erb +83 -0
- data/test/fixtures/stack/stackfu-installer/script/redis_installation.sh.erb +33 -0
- data/test/fixtures/stack/stackfu-installer/script/resque_installation.sh.erb +7 -0
- data/test/fixtures/stack/stackfu-installer/script/ruby_environment.sh.erb +20 -0
- data/test/fixtures/stack/stackfu-installer/script/stackfu.sh.erb +76 -0
- data/test/fixtures/stack/stackfu-installer/stack.yml +5 -0
- data/test/fixtures/stack_add +6 -0
- data/test/fixtures/stack_add_error +8 -0
- data/test/fixtures/stack_add_error_dupe +8 -0
- data/test/fixtures/stack_adds_by_name +7 -0
- data/test/fixtures/stack_delete_not_found +7 -0
- data/test/fixtures/stacks +7 -0
- data/test/fixtures/stacks_by_name +7 -0
- data/test/fixtures/stacks_by_name_other +7 -0
- data/test/fixtures/stacks_empty +7 -0
- data/test/fixtures/stacks_multiple +7 -0
- data/test/fixtures/stacks_not_found +7 -0
- data/test/fixtures/stacks_realworld +7 -0
- data/test/fixtures/stacks_stackfu-installer +7 -0
- data/test/fixtures/stacks_unauthorized +8 -0
- data/test/fixtures/stacks_with_controls +0 -0
- data/test/fixtures/users +7 -0
- data/test/fixtures/users_no_credentials +7 -0
- data/test/fixtures/users_update +6 -0
- data/test/stack.yml +26 -0
- data/test/support/custom_matchers.rb +69 -0
- data/test/support/fixtures.rb +98 -0
- data/test/support/io_stub.rb +10 -0
- data/test/support/web_fixtures.rb +91 -0
- data/test/test_helper.rb +186 -0
- data/test/unit/commands/test_command.rb +112 -0
- data/test/unit/commands/test_config_command.rb +92 -0
- data/test/unit/commands/test_deploy_command.rb +303 -0
- data/test/unit/commands/test_dump_command.rb +155 -0
- data/test/unit/commands/test_generate_command.rb +112 -0
- data/test/unit/commands/test_help_command.rb +33 -0
- data/test/unit/commands/test_list_command.rb +63 -0
- data/test/unit/commands/test_publish_command.rb +265 -0
- data/test/unit/commands/test_server_command.rb +259 -0
- data/test/unit/helpers/test_rendering.rb +141 -0
- data/test/unit/test_array.rb +26 -0
- data/test/unit/test_provider.rb +14 -0
- data/test/unit/test_stackfu.rb +27 -0
- metadata +311 -0
@@ -0,0 +1,82 @@
|
|
1
|
+
module StackFu
|
2
|
+
module ProvidersCredentials
|
3
|
+
def add_webbynode_credentials(user)
|
4
|
+
while true
|
5
|
+
puts ""
|
6
|
+
puts "Enter your Webbynode API credentials below (or type 'help' for more information or 'abort' to abort)"
|
7
|
+
|
8
|
+
login = ask("Webbynode Login:")
|
9
|
+
|
10
|
+
unless login.try(:downcase) == "abort" or login.try(:downcase) == "help"
|
11
|
+
token = ask("Webbynode Token:")
|
12
|
+
end
|
13
|
+
|
14
|
+
credentials = [login || "", token || ""].map(&:downcase)
|
15
|
+
|
16
|
+
if credentials.include?('help')
|
17
|
+
puts ""
|
18
|
+
puts "== Webbynode StackFu integration ==".foreground(:green).bright
|
19
|
+
puts ""
|
20
|
+
puts "In order to allow StackFu to integrate itself with Webbynode, you need to provide the email address you use to login into Webbynode Manager and your API token."
|
21
|
+
puts ""
|
22
|
+
puts "This can be easily done by visiting your '#{"Account".foreground(:cyan)}' area in Webbynode Manager. On the box where your summary is presented, copy the 'API Token:' field content."
|
23
|
+
puts ""
|
24
|
+
puts "If you need further information, visit #{"http://stackfu.com/faq/webbynode-api-integration".underline} for a complete walkthrough of this process."
|
25
|
+
|
26
|
+
elsif credentials.include?('abort')
|
27
|
+
|
28
|
+
puts "Aborted adding server."
|
29
|
+
return false
|
30
|
+
|
31
|
+
else
|
32
|
+
user.settings.webbynode_login = login
|
33
|
+
user.settings.webbynode_token = token
|
34
|
+
|
35
|
+
if user.save
|
36
|
+
puts ""
|
37
|
+
puts "Webbynode credentials saved."
|
38
|
+
else
|
39
|
+
puts "Error: #{user.errors.full_messages.to_s}"
|
40
|
+
end
|
41
|
+
|
42
|
+
return true
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def add_slicehost_credentials(user)
|
48
|
+
while true
|
49
|
+
puts ""
|
50
|
+
puts "Enter your Slicehost API password (or type 'help' for more information or 'abort' to abort): "
|
51
|
+
|
52
|
+
token = ask("")
|
53
|
+
|
54
|
+
unless ['help', 'abort'].include? token.downcase
|
55
|
+
user.settings.slicehost_token = token
|
56
|
+
if user.save
|
57
|
+
puts ""
|
58
|
+
puts "Slicehost credentials saved."
|
59
|
+
else
|
60
|
+
puts "Error: #{user.errors.full_messages.to_s}"
|
61
|
+
end
|
62
|
+
return true
|
63
|
+
end
|
64
|
+
|
65
|
+
if token.downcase == 'abort'
|
66
|
+
puts ""
|
67
|
+
puts "Aborted adding server."
|
68
|
+
return false
|
69
|
+
else
|
70
|
+
puts ""
|
71
|
+
puts "== Slicehost StackFu integration ==".foreground(:green).bright
|
72
|
+
puts ""
|
73
|
+
puts "In order to allow StackFu to integrate itself with Slicehost, you need to enabled your API Access and provide us your API Password."
|
74
|
+
puts ""
|
75
|
+
puts "This can be easily done by visiting your '#{"Account > API Access".foreground(:cyan)}' area in Slicehost manager."
|
76
|
+
puts ""
|
77
|
+
puts "If you need further information, visit #{"http://stackfu.com/faq/slicehost-api-integration".underline} for a complete walkthrough of this process."
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,201 @@
|
|
1
|
+
module StackFu
|
2
|
+
module Rendering
|
3
|
+
LEFT_MARGIN = 2
|
4
|
+
|
5
|
+
def warning(question)
|
6
|
+
puts "== WARNING ==".foreground(:red)
|
7
|
+
agree(question)
|
8
|
+
end
|
9
|
+
|
10
|
+
def fill_values_from_options(stack, options)
|
11
|
+
params = {}
|
12
|
+
|
13
|
+
stack.controls.each do |c|
|
14
|
+
if (opt = options[c.name.to_sym])
|
15
|
+
case c._type
|
16
|
+
when "Textbox"
|
17
|
+
params[c.name] = opt if opt
|
18
|
+
|
19
|
+
when "Numericbox"
|
20
|
+
begin
|
21
|
+
params[c.name] = Float(opt)
|
22
|
+
rescue ArgumentError
|
23
|
+
error "Value for #{c.name} should be numeric"
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
params
|
31
|
+
end
|
32
|
+
|
33
|
+
def render_target(params, target, options)
|
34
|
+
max_length = target.controls.map { |c| c.label.size }.max
|
35
|
+
|
36
|
+
target.controls.each do |c|
|
37
|
+
unless params[c.name]
|
38
|
+
case c._type
|
39
|
+
when "Textbox"
|
40
|
+
params[c.name] = ask(" #{c.label.rjust(max_length)}: ")
|
41
|
+
|
42
|
+
when "Numericbox"
|
43
|
+
params[c.name] = ask(" #{c.label.rjust(max_length)}: ", Integer)
|
44
|
+
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
params
|
50
|
+
end
|
51
|
+
|
52
|
+
def done(message, more_info=nil)
|
53
|
+
puts "#{"Success:".foreground(:green).bright} #{message}"
|
54
|
+
puts "\n#{more_info}" if more_info
|
55
|
+
end
|
56
|
+
|
57
|
+
def error(message, more_info=nil)
|
58
|
+
puts "#{"Error:".foreground(:red).bright} #{message}"
|
59
|
+
puts "\n#{more_info}" if more_info
|
60
|
+
end
|
61
|
+
|
62
|
+
def menu_for(name, collection, convert=false)
|
63
|
+
choice = choose do |menu|
|
64
|
+
menu.header = "Available #{name.pluralize}"
|
65
|
+
menu.prompt = "\nSelect the #{name}:"
|
66
|
+
menu.shell = true
|
67
|
+
|
68
|
+
collection.each { |p| menu.choice(p.name) }
|
69
|
+
end
|
70
|
+
|
71
|
+
if convert
|
72
|
+
collection.select { |i| i.name == choice }.first.id
|
73
|
+
else
|
74
|
+
choice
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def table(opts)
|
79
|
+
collection = opts[:collection]
|
80
|
+
display = opts[:display]
|
81
|
+
if (classes = opts[:class]).is_a?(Array)
|
82
|
+
single = {}
|
83
|
+
plural = {}
|
84
|
+
opts[:class].each do |kls|
|
85
|
+
single[kls] = kls.name.demodulize.humanize.downcase
|
86
|
+
plural[kls] = single[kls].pluralize
|
87
|
+
end
|
88
|
+
else
|
89
|
+
single = opts[:class].name.demodulize.humanize.downcase
|
90
|
+
plural = single.pluralize
|
91
|
+
end
|
92
|
+
labels = opts[:labels]
|
93
|
+
main_column = opts[:main_column]
|
94
|
+
ascii = opts[:ansi] == false
|
95
|
+
header = opts[:header]
|
96
|
+
|
97
|
+
if collection.empty?
|
98
|
+
msg = opts[:empty]
|
99
|
+
msg ||= "No #{plural}."
|
100
|
+
return msg
|
101
|
+
end
|
102
|
+
|
103
|
+
columns = display.inject([]) do |arr, item|
|
104
|
+
label = labels ? labels[item] : item.to_s.titleize
|
105
|
+
arr << { :name => item.to_s, :label => label }
|
106
|
+
end
|
107
|
+
|
108
|
+
display.each_with_index do |column, i|
|
109
|
+
max_value_size = collection.map do |item|
|
110
|
+
value = block_given? ? yield(item)[i] : item.send(column)
|
111
|
+
value.to_s.size
|
112
|
+
end.max
|
113
|
+
|
114
|
+
size = [max_value_size, column.to_s.size].max
|
115
|
+
columns[i][:size] = size
|
116
|
+
end
|
117
|
+
|
118
|
+
title = header || if classes.is_a?(Array)
|
119
|
+
counter = Hash.new(0)
|
120
|
+
collection.each do |item|
|
121
|
+
counter[item.class] += 1
|
122
|
+
end
|
123
|
+
|
124
|
+
parts = []
|
125
|
+
collection.map(&:class).uniq.each do |k|
|
126
|
+
v = counter[k]
|
127
|
+
parts << "#{v} #{v > 1 ? plural[k] : single[k]}"
|
128
|
+
end
|
129
|
+
|
130
|
+
"Listing #{parts.to_phrase}:\n"
|
131
|
+
else
|
132
|
+
"Listing #{collection.size} #{collection.size > 1 ? plural : single}:\n"
|
133
|
+
end
|
134
|
+
|
135
|
+
table = []
|
136
|
+
if ascii
|
137
|
+
table << columns.inject("") { |str, col| str << "#{col[:label].ljust(col[:size])} " }
|
138
|
+
table << columns.inject("") { |str, col| str << "#{"-" * (col[:size]+1)} " }
|
139
|
+
else
|
140
|
+
# table << columns.inject("") { |str, col| str << "#{col[:label].titleize.ljust(col[:size]+1).underline.foreground(:yellow)} " }
|
141
|
+
table << columns.inject("") { |str, col| str << "#{col[:label].ljust(col[:size]+1).underline.foreground(:yellow)} " }
|
142
|
+
end
|
143
|
+
|
144
|
+
collection.each do |item|
|
145
|
+
values = block_given? ? yield(item) : nil
|
146
|
+
|
147
|
+
idx = 0
|
148
|
+
table << columns.inject("") do |str, col|
|
149
|
+
if block_given?
|
150
|
+
value = values[idx]
|
151
|
+
idx += 1
|
152
|
+
else
|
153
|
+
value = item.send(col[:name])
|
154
|
+
end
|
155
|
+
|
156
|
+
just_method = value.is_a?(Numeric) ? :rjust : :ljust
|
157
|
+
|
158
|
+
if ascii
|
159
|
+
str << "#{value.to_s.send(just_method, col[:size])} "
|
160
|
+
else
|
161
|
+
if col[:name].to_sym == main_column
|
162
|
+
str << "#{value.to_s.send(just_method, col[:size]).foreground(:blue)} "
|
163
|
+
else
|
164
|
+
str << "#{value.to_s.send(just_method, col[:size])} "
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
table.map! { |line| "#{" " * LEFT_MARGIN}#{line}"}
|
171
|
+
|
172
|
+
[title, table].flatten.join("\n")
|
173
|
+
end
|
174
|
+
|
175
|
+
def spinner(&code)
|
176
|
+
chars = %w{ | / - \\ }
|
177
|
+
|
178
|
+
result = nil
|
179
|
+
t = Thread.new {
|
180
|
+
result = code.call
|
181
|
+
}
|
182
|
+
while t.alive?
|
183
|
+
print chars[0]
|
184
|
+
STDOUT.flush
|
185
|
+
|
186
|
+
sleep 0.1
|
187
|
+
|
188
|
+
print "\b"
|
189
|
+
STDOUT.flush
|
190
|
+
|
191
|
+
chars.push chars.shift
|
192
|
+
end
|
193
|
+
|
194
|
+
print " \b"
|
195
|
+
STDOUT.flush
|
196
|
+
|
197
|
+
t.join
|
198
|
+
result
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module StackFu
|
2
|
+
module OperatingSystems
|
3
|
+
OperatingSystems = [
|
4
|
+
:arch_2009, :centos_52, :centos_53, :gentoo_2008, :debian_50,
|
5
|
+
:fedora_10, :ubuntu_804, :ubuntu_810, :ubuntu_904
|
6
|
+
]
|
7
|
+
|
8
|
+
FriendlyNames = {
|
9
|
+
"ArchLinux 2009" => :arch_2009,
|
10
|
+
"Arch 2009" => :arch_2009,
|
11
|
+
"Centos 5.2" => :centos_52,
|
12
|
+
"Centos 5.3" => :centos_53,
|
13
|
+
"Gentoo 2008" => :gentoo_2008,
|
14
|
+
"Debian 5.0" => :debian_50,
|
15
|
+
"Fedora 10" => :fedora_10,
|
16
|
+
"Ubuntu 8.04" => :ubuntu_804,
|
17
|
+
"Ubuntu 8.10" => :ubuntu_810,
|
18
|
+
"Ubuntu 9.04" => :ubuntu_904
|
19
|
+
}
|
20
|
+
|
21
|
+
def convert_os(friendly)
|
22
|
+
StackFu::OperatingSystems::FriendlyNames[friendly] or raise "Unknown OS: #{friendly}"
|
23
|
+
end
|
24
|
+
|
25
|
+
def os_name(os_key)
|
26
|
+
os_key = os_key.try(:to_sym)
|
27
|
+
StackFu::OperatingSystems::FriendlyNames.index(os_key) or raise "Unknown OS: #{os_key}"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/lib/stackfu.rb
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
|
3
|
+
$:.unshift(File.dirname(__FILE__)) unless
|
4
|
+
$:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
|
5
|
+
|
6
|
+
gem 'activesupport', '>=2.3.5'
|
7
|
+
gem 'activeresource', '>=2.3.5'
|
8
|
+
gem 'rainbow', '>=1.0.4'
|
9
|
+
gem 'highline', '>=1.5.1'
|
10
|
+
gem 'httparty', '>=0.4.5'
|
11
|
+
|
12
|
+
begin
|
13
|
+
require 'active_resource'
|
14
|
+
require 'active_support'
|
15
|
+
rescue LoadError
|
16
|
+
require 'activeresource'
|
17
|
+
require 'activesupport'
|
18
|
+
end
|
19
|
+
require 'rainbow'
|
20
|
+
require 'highline/import'
|
21
|
+
require 'httparty'
|
22
|
+
require 'fileutils'
|
23
|
+
|
24
|
+
begin
|
25
|
+
require 'Win32/Console/ANSI' if RUBY_PLATFORM =~ /mswin/
|
26
|
+
rescue LoadError
|
27
|
+
puts "Hint: if you want to make your output better in windows, install the win32console gem:"
|
28
|
+
puts " gem install win32console"
|
29
|
+
puts ""
|
30
|
+
end
|
31
|
+
|
32
|
+
dir = Pathname(__FILE__).dirname.expand_path + 'stackfu'
|
33
|
+
|
34
|
+
require "#{dir}/helpers/rendering"
|
35
|
+
require "#{dir}/helpers/providers_credentials"
|
36
|
+
|
37
|
+
require "#{dir}/operating_systems"
|
38
|
+
require "#{dir}/api_hooks"
|
39
|
+
require "#{dir}/app"
|
40
|
+
|
41
|
+
require "#{dir}/commands/command"
|
42
|
+
require "#{dir}/commands/help_command"
|
43
|
+
require "#{dir}/commands/server_command"
|
44
|
+
require "#{dir}/commands/config_command"
|
45
|
+
require "#{dir}/commands/generate_command"
|
46
|
+
require "#{dir}/commands/publish_command"
|
47
|
+
require "#{dir}/commands/list_command"
|
48
|
+
require "#{dir}/commands/deploy_command"
|
49
|
+
require "#{dir}/commands/dump_command"
|
50
|
+
|
51
|
+
module StackFu
|
52
|
+
VERSION = '0.0.1'
|
53
|
+
API = "http://api.stackfu.com"
|
54
|
+
CONFIG_FILE = "#{ENV['HOME']}/.stackfu"
|
55
|
+
|
56
|
+
include StackFu::OperatingSystems
|
57
|
+
|
58
|
+
module Exceptions
|
59
|
+
class UnknownCommand < StandardError; end
|
60
|
+
class InvalidCommand < StandardError; end
|
61
|
+
class InvalidSubcommand < StandardError; end
|
62
|
+
class InvalidParameter < StandardError; end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
OpenStruct.__send__(:define_method, :id) { @table[:id] || self.object_id }
|
67
|
+
|
68
|
+
class Array
|
69
|
+
def to_phrase
|
70
|
+
self.to_sentence(:words_connector => ", ", :last_word_connector => " and ")
|
71
|
+
end
|
72
|
+
|
73
|
+
def to_structs
|
74
|
+
self.map { |hash| OpenStruct.new(hash) }
|
75
|
+
end
|
76
|
+
|
77
|
+
def to_params
|
78
|
+
self.map { |item| item.to_s.upcase }.join(" ")
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
class String
|
83
|
+
def truncate_words(length = 30, end_string = '…')
|
84
|
+
words = self.split()
|
85
|
+
words[0..(length-1)].join(' ') + (words.length > length ? end_string : '')
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
@@ -0,0 +1,17 @@
|
|
1
|
+
---
|
2
|
+
controls:
|
3
|
+
- label: Github User
|
4
|
+
name: github_user
|
5
|
+
type: Textbox
|
6
|
+
- label: Github Token
|
7
|
+
name: github_token
|
8
|
+
type: Textbox
|
9
|
+
- label: User Name
|
10
|
+
name: user_name
|
11
|
+
type: Textbox
|
12
|
+
- label: User Email
|
13
|
+
name: user_email
|
14
|
+
type: Textbox
|
15
|
+
- label: Ssh Passphrase
|
16
|
+
name: ssh_passphrase
|
17
|
+
type: Textbox
|
@@ -0,0 +1,16 @@
|
|
1
|
+
---
|
2
|
+
scripts:
|
3
|
+
- file: github_credentials_setup
|
4
|
+
description: GitHub Credentials Setup
|
5
|
+
- file: dotfiles_installation
|
6
|
+
description: Dotfiles Installation
|
7
|
+
- file: ruby_environment
|
8
|
+
description: Ruby Environment
|
9
|
+
- file: redis_installation
|
10
|
+
description: Redis Installation
|
11
|
+
- file: resque_installation
|
12
|
+
description: Resque Installation
|
13
|
+
- file: nginx_and_passenger
|
14
|
+
description: Nginx and Passenger
|
15
|
+
- file: stackfu
|
16
|
+
description: StackFu
|
@@ -0,0 +1,22 @@
|
|
1
|
+
#
|
2
|
+
# install_dotfiles.sh
|
3
|
+
# Sun Nov 22 20:46:43 -0200 2009
|
4
|
+
#
|
5
|
+
|
6
|
+
if ! which git>/dev/null; then
|
7
|
+
apt-get install -y git-core
|
8
|
+
fi
|
9
|
+
|
10
|
+
apt-get install -y zsh
|
11
|
+
apt-get install -y ruby
|
12
|
+
apt-get install -y mercurial
|
13
|
+
apt-get install -y build-essential
|
14
|
+
apt-get install -y vim
|
15
|
+
|
16
|
+
git clone git@github.com:fcoury/dotfiles.git bin
|
17
|
+
/root/bin/install-vcprompt
|
18
|
+
cd /root/bin/dotfiles
|
19
|
+
./install
|
20
|
+
|
21
|
+
sed -i s:/bin/bash:/bin/zsh:g /etc/passwd
|
22
|
+
echo "export PATH=/root/bin:$PATH" > /root/.private_profile
|
@@ -0,0 +1,31 @@
|
|
1
|
+
#
|
2
|
+
# install_github.sh
|
3
|
+
# Sun Nov 22 20:46:43 -0200 2009
|
4
|
+
#
|
5
|
+
|
6
|
+
apt-get update
|
7
|
+
apt-get install -y git-core
|
8
|
+
|
9
|
+
key="$HOME/.ssh/id_rsa"
|
10
|
+
pubkey="$key.pub"
|
11
|
+
if [ ! -f "$pubkey" ]; then
|
12
|
+
ssh-keygen -t rsa -N "<%= ssh_passphrase %>" -f $key
|
13
|
+
fi
|
14
|
+
|
15
|
+
gitconfig="$HOME/.gitconfig"
|
16
|
+
if [ ! -f "$gitconfig" ]; then
|
17
|
+
git config --global github.user <%= github_user %>
|
18
|
+
git config --global github.token <%= github_token %>
|
19
|
+
|
20
|
+
git config --global user.name <%= user_name %>
|
21
|
+
git config --global user.email <%= user_email %>
|
22
|
+
fi
|
23
|
+
|
24
|
+
key="$HOME/.ssh/id_rsa"
|
25
|
+
pubkey="$key.pub"
|
26
|
+
key_contents=`cat $pubkey`
|
27
|
+
|
28
|
+
curl --silent -F "login=<%= github_user %>" -F "token=<%= github_token %>" \
|
29
|
+
https://github.com/api/v2/json/user/key/add -F "key=$key_contents"
|
30
|
+
|
31
|
+
ssh -o "StrictHostKeyChecking no" git@github.com || true
|
@@ -0,0 +1,83 @@
|
|
1
|
+
#
|
2
|
+
# install_nginx_passenger.sh
|
3
|
+
# Sun Nov 22 20:46:43 -0200 2009
|
4
|
+
#
|
5
|
+
|
6
|
+
export PATH=/usr/lib/ruby/gems/1.8/gems/passenger-2.2.7/bin:$PATH
|
7
|
+
|
8
|
+
apt-get install -y zlib1g-dev libssl-dev
|
9
|
+
|
10
|
+
gem install passenger
|
11
|
+
passenger-install-nginx-module --auto --auto-download --prefix=/opt/nginx
|
12
|
+
|
13
|
+
echo '#! /bin/sh
|
14
|
+
|
15
|
+
### BEGIN INIT INFO
|
16
|
+
# Provides: nginx
|
17
|
+
# Required-Start: $all
|
18
|
+
# Required-Stop: $all
|
19
|
+
# Default-Start: 2 3 4 5
|
20
|
+
# Default-Stop: 0 1 6
|
21
|
+
# Short-Description: starts the nginx web server
|
22
|
+
# Description: starts nginx using start-stop-daemon
|
23
|
+
### END INIT INFO
|
24
|
+
|
25
|
+
PATH=/opt/nginx/sbin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
|
26
|
+
DAEMON=/opt/nginx/sbin/nginx
|
27
|
+
NAME=nginx
|
28
|
+
DESC=nginx
|
29
|
+
|
30
|
+
test -x $DAEMON || exit 0
|
31
|
+
|
32
|
+
# Include nginx defaults if available
|
33
|
+
if [ -f /etc/default/nginx ] ; then
|
34
|
+
. /etc/default/nginx
|
35
|
+
fi
|
36
|
+
|
37
|
+
set -e
|
38
|
+
|
39
|
+
. /lib/lsb/init-functions
|
40
|
+
|
41
|
+
case "$1" in
|
42
|
+
start)
|
43
|
+
echo -n "Starting $DESC: "
|
44
|
+
start-stop-daemon --start --quiet --pidfile /opt/nginx/logs/$NAME.pid \
|
45
|
+
--exec $DAEMON -- $DAEMON_OPTS || true
|
46
|
+
echo "$NAME."
|
47
|
+
;;
|
48
|
+
stop)
|
49
|
+
echo -n "Stopping $DESC: "
|
50
|
+
start-stop-daemon --stop --quiet --pidfile /opt/nginx/logs/$NAME.pid \
|
51
|
+
--exec $DAEMON || true
|
52
|
+
echo "$NAME."
|
53
|
+
;;
|
54
|
+
restart|force-reload)
|
55
|
+
echo -n "Restarting $DESC: "
|
56
|
+
start-stop-daemon --stop --quiet --pidfile \
|
57
|
+
/opt/nginx/logs/$NAME.pid --exec $DAEMON || true
|
58
|
+
sleep 1
|
59
|
+
start-stop-daemon --start --quiet --pidfile \
|
60
|
+
/opt/nginx/logs/$NAME.pid --exec $DAEMON -- $DAEMON_OPTS || true
|
61
|
+
echo "$NAME."
|
62
|
+
;;
|
63
|
+
reload)
|
64
|
+
echo -n "Reloading $DESC configuration: "
|
65
|
+
start-stop-daemon --stop --signal HUP --quiet --pidfile /opt/nginx/logs/$NAME.pid \
|
66
|
+
--exec $DAEMON || true
|
67
|
+
echo "$NAME."
|
68
|
+
;;
|
69
|
+
status)
|
70
|
+
status_of_proc -p /opt/nginx/logs/$NAME.pid "$DAEMON" nginx && exit 0 || exit $?
|
71
|
+
;;
|
72
|
+
*)
|
73
|
+
N=/etc/init.d/$NAME
|
74
|
+
echo "Usage: $N {start|stop|restart|reload|force-reload|status}" >&2
|
75
|
+
exit 1
|
76
|
+
;;
|
77
|
+
esac
|
78
|
+
|
79
|
+
exit 0
|
80
|
+
' > /etc/init.d/nginx
|
81
|
+
|
82
|
+
chmod +x /etc/init.d/nginx
|
83
|
+
/etc/init.d/nginx start
|
@@ -0,0 +1,33 @@
|
|
1
|
+
#
|
2
|
+
# install_redis.sh
|
3
|
+
# Sun Nov 22 20:46:43 -0200 2009
|
4
|
+
#
|
5
|
+
|
6
|
+
apt-get install -y cronolog
|
7
|
+
gem install rspec
|
8
|
+
|
9
|
+
# cd /usr/src
|
10
|
+
# git clone git://github.com/ezmobius/redis-rb.git
|
11
|
+
# cd redis-rb
|
12
|
+
# rake redis:install
|
13
|
+
# # rake install
|
14
|
+
|
15
|
+
cd /usr/src
|
16
|
+
wget -q http://redis.googlecode.com/files/redis-1.02.tar.gz
|
17
|
+
tar xzvf redis-1.02.tar.gz
|
18
|
+
cd redis-1.02/
|
19
|
+
make -j
|
20
|
+
cp redis.conf /etc
|
21
|
+
ln -s /usr/src/redis-1.02/redis-server /usr/bin/redis-server
|
22
|
+
ln -s /usr/src/redis-1.02/redis-cli /usr/bin/redis-cli
|
23
|
+
|
24
|
+
echo "
|
25
|
+
daemonize no
|
26
|
+
logfile stdout" >> /etc/redis.conf
|
27
|
+
echo "nohup /usr/bin/redis-server /etc/redis.conf | /usr/bin/cronolog /var/log/redis/redis.%Y-%m-%d.log 2>&1 &" > /etc/init.d/redis.sh
|
28
|
+
|
29
|
+
chmod +x /etc/init.d/redis.sh
|
30
|
+
|
31
|
+
#setsid bash -c "nohup /usr/bin/redis-server /etc/redis.conf | /usr/bin/cronolog /var/log/redis/redis.%Y-%m-%d.log 2>&1 &"
|
32
|
+
|
33
|
+
sed -i "s/loglevel debug/loglevel notice/g" /etc/redis.conf
|
@@ -0,0 +1,20 @@
|
|
1
|
+
#
|
2
|
+
# install_dotfiles.sh
|
3
|
+
# Sun Nov 22 20:46:43 -0200 2009
|
4
|
+
#
|
5
|
+
|
6
|
+
apt-get install -y build-essential
|
7
|
+
apt-get install -y ruby irb1.8 ruby1.8-dev libreadline-ruby1.8 libruby1.8 ruby1.8 irb libopenssl-ruby libopenssl-ruby1.8
|
8
|
+
|
9
|
+
cd /usr/src
|
10
|
+
wget http://rubyforge.org/frs/download.php/60718/rubygems-1.3.5.tgz
|
11
|
+
tar xvzf rubygems-1.3.5.tgz
|
12
|
+
cd rubygems-1.3.5
|
13
|
+
sudo ruby setup.rb
|
14
|
+
|
15
|
+
sudo ln -s /usr/bin/gem1.8 /usr/local/bin/gem
|
16
|
+
sudo ln -s /usr/bin/ruby1.8 /usr/local/bin/ruby
|
17
|
+
sudo ln -s /usr/bin/irb1.8 /usr/local/bin/irb
|
18
|
+
|
19
|
+
gem install rake
|
20
|
+
ln -s /usr/lib/ruby/1.8/bin/rake /usr/local/bin/rake
|