locarails 1.2.0
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/bin/locarails +240 -0
- data/bin/locarails.cmd +1 -0
- data/lib/locarails.rb +4 -0
- data/lib/locarails/base.rb +24 -0
- data/lib/locarails/copy.rb +73 -0
- data/lib/locarails/fix.rb +14 -0
- data/lib/locarails/git.rb +39 -0
- data/lib/locarails/none.rb +10 -0
- data/lib/locarails/version.rb +9 -0
- data/tasks/gems.rake +43 -0
- data/templates/.gitignore +22 -0
- data/templates/database.locaweb.yml.erb +8 -0
- data/templates/deploy.common.rb.erb +136 -0
- data/templates/deploy.rb.erb +77 -0
- data/templates/locaweb_backup.rb +30 -0
- data/templates/ssh_helper.rb +319 -0
- metadata +99 -0
data/bin/locarails
ADDED
@@ -0,0 +1,240 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# Created on 2008-8-19.
|
4
|
+
# Copyright (c) 2008. All rights reserved.
|
5
|
+
# Fabio Akita - akitaonrails.com
|
6
|
+
|
7
|
+
begin
|
8
|
+
require 'rubygems'
|
9
|
+
rescue LoadError
|
10
|
+
# no rubygems to load, so we fail silently
|
11
|
+
end
|
12
|
+
|
13
|
+
require 'ostruct'
|
14
|
+
require 'optparse'
|
15
|
+
require 'erb'
|
16
|
+
require 'highline/import'
|
17
|
+
|
18
|
+
# configuracoes da sua hospedagem
|
19
|
+
class MyOpenStruct < OpenStruct
|
20
|
+
def blank?(campo)
|
21
|
+
send(campo).nil? || send(campo).empty?
|
22
|
+
end
|
23
|
+
|
24
|
+
def input(campo, message, default_value = nil)
|
25
|
+
unless blank?(campo)
|
26
|
+
puts "* #{message} > #{message =~ /senha/ ? "********" : send(campo)}"
|
27
|
+
return send(campo)
|
28
|
+
end
|
29
|
+
result = if message =~ /senha/
|
30
|
+
ask("* #{message} > ") { |q| q.echo = "*" }
|
31
|
+
else
|
32
|
+
ask("* #{message} > ")
|
33
|
+
end
|
34
|
+
send("#{campo}=", (default_value && result.empty?) ? default_value : result)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
config = MyOpenStruct.new
|
39
|
+
mysqlcfg = MyOpenStruct.new
|
40
|
+
|
41
|
+
# defaults
|
42
|
+
config.force = false
|
43
|
+
config.mode = 'copy'
|
44
|
+
|
45
|
+
OptionParser.new do |opts|
|
46
|
+
opts.banner = <<-STR
|
47
|
+
LocaRails - configurador de Capistrano para projetos Rails
|
48
|
+
especifico para hospedagens Linux da Locaweb
|
49
|
+
|
50
|
+
Uso: #{File.basename($0)} [caminho] [opcoes]
|
51
|
+
STR
|
52
|
+
|
53
|
+
opts.on("--version", "Mostra versao atual do locarails") do
|
54
|
+
require 'locarails'
|
55
|
+
puts "Locarails v#{Locarails::VERSION::STRING}"
|
56
|
+
exit 0
|
57
|
+
end
|
58
|
+
|
59
|
+
opts.on("-h", "--help", "Mostra esta tela de ajuda") do
|
60
|
+
puts opts
|
61
|
+
exit 0
|
62
|
+
end
|
63
|
+
|
64
|
+
opts.on("-m", "--mode=tipo", "modo de deployment (copy/git)", "Padrao: copy") do |mode|
|
65
|
+
config.mode = mode
|
66
|
+
unless "copy|git".include?(mode)
|
67
|
+
puts "#{mode} nao existe. Escolha copy ou git como --mode."
|
68
|
+
exit 0
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
opts.on("-s", "--sshkey=caminho", "local da sua chave privada SSH", "Padrao: ~/.ssh/id_rsa") do |path|
|
73
|
+
config.ssh_key_path = path
|
74
|
+
unless File.exists?(path)
|
75
|
+
puts "Chave inexistente no caminho #{path}."
|
76
|
+
exit 0
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
opts.on("-f", "--force", "Sobrescreve seu config/deploy.rb, caso exista.", "Cuidado: voce ira perder sua configuracao anterior") do
|
81
|
+
config.force = true
|
82
|
+
end
|
83
|
+
|
84
|
+
opts.on("-u", "--usuario=login", "Usuario da hospedagem Linux") do |usuario|
|
85
|
+
config.usuario = usuario
|
86
|
+
end
|
87
|
+
|
88
|
+
opts.on("-a", "--aplicacao=aplicacao", "Nome da sua aplicacao", "O mesmo do apontamento /public_html/aplicacao") do |aplicacao|
|
89
|
+
config.app_name = aplicacao
|
90
|
+
end
|
91
|
+
|
92
|
+
opts.on("-d", "--dominio=URL", "Dominio do seu site", "ex. www.seu_dominio.com") do |dominio|
|
93
|
+
config.dominio = dominio
|
94
|
+
end
|
95
|
+
|
96
|
+
opts.on("-q", "--banco=banco", "Nome do seu banco de dados") do |db|
|
97
|
+
mysqlcfg.db = db
|
98
|
+
end
|
99
|
+
|
100
|
+
opts.on("-l", "--banco-usuario=login", "Login do seu banco de dados MySQL") do |dbuser|
|
101
|
+
mysqlcfg.user = dbuser
|
102
|
+
end
|
103
|
+
|
104
|
+
opts.on("-p", "--banco-senha=senha", "Senha do seu banco de dados MySQL") do |dbpass|
|
105
|
+
mysqlcfg.pass = dbpass
|
106
|
+
end
|
107
|
+
|
108
|
+
opts.on("-v", "--banco-servidor=servidor", "Servidor do seu banco de dados", "ex. mysql6666.locaweb.com.br") do |dbhost|
|
109
|
+
mysqlcfg.host = dbhost
|
110
|
+
end
|
111
|
+
|
112
|
+
opts.on("-b", "--git-branch=branch", "Branch local do seu repositorio Git", "padrao: master") do |gitbranch|
|
113
|
+
config.branch = gitbranch
|
114
|
+
end
|
115
|
+
|
116
|
+
opts.on("-r", "--git-remote=remote", "Nome do repositorio remoto gravado no seu .git/config", "padrao: locaweb") do |gitname|
|
117
|
+
config.remote_repo = gitname
|
118
|
+
end
|
119
|
+
|
120
|
+
begin
|
121
|
+
opts.parse!(ARGV)
|
122
|
+
rescue OptionParser::ParseError => e
|
123
|
+
warn e.message
|
124
|
+
puts opts
|
125
|
+
exit 1
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
if ARGV.empty?
|
130
|
+
abort "Por favor, especifique o diretorio do seu projeto Rails, e.g. `#{File.basename($0)} .'"
|
131
|
+
elsif !File.exists?(ARGV.first)
|
132
|
+
abort "`#{ARGV.first}' nao existe. Tente novamente."
|
133
|
+
elsif !File.directory?(ARGV.first)
|
134
|
+
abort "`#{ARGV.first}' nao eh um diretorio. Tente novamente."
|
135
|
+
end
|
136
|
+
|
137
|
+
# configuracoes locais da sua maquina
|
138
|
+
config.bin_path = File.dirname(File.expand_path(__FILE__))
|
139
|
+
config.local_path = File.expand_path(ARGV.shift)
|
140
|
+
config.app_name ||= config.local_path.split('/').last
|
141
|
+
|
142
|
+
if !config.force && File.exists?(File.join(config.local_path, 'config/deploy.rb'))
|
143
|
+
abort "Voce ja tem capistrano configurado em config/deploy.rb. Configuracao abortada."
|
144
|
+
end
|
145
|
+
|
146
|
+
puts <<-STR
|
147
|
+
========================================================
|
148
|
+
Bem Vindos ao configurador de projetos da Locaweb.
|
149
|
+
|
150
|
+
Vamos configurar seu projeto Rails para melhor se
|
151
|
+
Adequar nas nossas hospedagens Linux compartilhada.
|
152
|
+
|
153
|
+
O comando locarails deve ser executado *dentro* do
|
154
|
+
diretorio do seu projeto, na sua maquina local.
|
155
|
+
|
156
|
+
Para tanto precisaremos de algumas informacoes:
|
157
|
+
========================================================
|
158
|
+
|
159
|
+
Estrategia de instalacao via: #{config.mode}
|
160
|
+
|
161
|
+
Garanta que a seguinte pasta contem sua aplicacao Rails:
|
162
|
+
#{config.local_path}
|
163
|
+
|
164
|
+
STR
|
165
|
+
|
166
|
+
# configuracoes inseridas manualmente pelo usuario
|
167
|
+
config.input( :app_name, "Nome da sua aplicacao" )
|
168
|
+
config.input( :dominio, "Dominio do seu site (ex. teste.tempsite.ws)" )
|
169
|
+
config.input( :usuario, "Seu usuario de hospedagem" )
|
170
|
+
mysqlcfg.input( :db, "Nome do seu banco mysql (enter para '#{config.usuario}')", config.usuario )
|
171
|
+
mysqlcfg.input( :user, "Seu usuario de mysql (enter para #{mysqlcfg.db})", mysqlcfg.db )
|
172
|
+
mysqlcfg.input( :pass, "Sua senha de mysql" )
|
173
|
+
mysqlcfg.input( :host, "Seu servidor mysql (ex. mysqlxxxx.locaweb.com.br)" )
|
174
|
+
if config.mode == 'git'
|
175
|
+
config.input( :branch, "Git branch local (enter para 'master')", 'master' )
|
176
|
+
config.input( :remote_repo, "Nome do repositorio remoto (enter para 'locaweb')", 'locaweb' )
|
177
|
+
config.remote_git = "#{config.usuario}@#{config.dominio}:~/repo/#{config.app_name}.git"
|
178
|
+
end
|
179
|
+
|
180
|
+
# forca rodar capistrano
|
181
|
+
unless File.exists?("#{config.local_path}/Capfile")
|
182
|
+
puts "- Executando Capistrano no seu projeto ..."
|
183
|
+
begin
|
184
|
+
`capify .`
|
185
|
+
rescue Exception => e
|
186
|
+
puts <<-STR
|
187
|
+
ERRO: Voce provavelmente nao tem Capistrano instalado
|
188
|
+
Rode: sudo gem install capistrano
|
189
|
+
|
190
|
+
STR
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
if config.mode == 'git'
|
195
|
+
begin
|
196
|
+
FileUtils.copy_file("#{config.bin_path}/../templates/.gitignore",
|
197
|
+
"#{config.local_path}/.gitignore") unless File.exists?("#{config.local_path}/.gitignore")
|
198
|
+
rescue
|
199
|
+
puts "Error copying file #{config.bin_path}/../templates/.gitignore"
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
begin
|
204
|
+
FileUtils.copy_file("#{config.bin_path}/../templates/locaweb_backup.rb",
|
205
|
+
"#{config.local_path}/config/locaweb_backup.rb") unless File.exists?("#{config.local_path}/config/locaweb_backup.rb")
|
206
|
+
rescue
|
207
|
+
puts "Error copying file #{config.bin_path}/../templates/locaweb_backup.rb"
|
208
|
+
end
|
209
|
+
|
210
|
+
begin
|
211
|
+
FileUtils.copy_file("#{config.bin_path}/../templates/ssh_helper.rb",
|
212
|
+
"#{config.local_path}/config/ssh_helper.rb") unless File.exists?("#{config.local_path}/config/ssh_helper.rb")
|
213
|
+
rescue
|
214
|
+
puts "Error copying file #{config.bin_path}/../templates/ssh_helper.rb"
|
215
|
+
end
|
216
|
+
|
217
|
+
File.open("#{config.local_path}/config/deploy.rb", 'w') do |out|
|
218
|
+
erb = ERB.new(File.read("#{config.bin_path}/../templates/deploy.rb.erb"))
|
219
|
+
buffer = erb.result(config.send(:binding))
|
220
|
+
erb = ERB.new(File.read("#{config.bin_path}/../templates/deploy.common.rb.erb"))
|
221
|
+
buffer << erb.result(config.send(:binding))
|
222
|
+
out.puts buffer
|
223
|
+
end
|
224
|
+
|
225
|
+
File.open("#{config.local_path}/config/database.locaweb.yml", 'w') do |out|
|
226
|
+
erb = ERB.new(File.read("#{config.bin_path}/../templates/database.locaweb.yml.erb"))
|
227
|
+
out.puts erb.result(mysqlcfg.send(:binding))
|
228
|
+
end
|
229
|
+
|
230
|
+
puts <<-STR
|
231
|
+
|
232
|
+
# Parabens, voce terminou de configurar sua aplicacao Rails!
|
233
|
+
# Execute apenas uma vez 'cap deploy:setup' para configurar os
|
234
|
+
diretorios remotamente na sua hospedagem.
|
235
|
+
# Em seguida execute 'cap deploy' para transportar sua aplicacao
|
236
|
+
para a hospedagem. Sempre que quiser atualizar sua aplicacao
|
237
|
+
no servidor apenas execute novamente 'cap deploy'
|
238
|
+
|
239
|
+
[finalizado!]
|
240
|
+
STR
|
data/bin/locarails.cmd
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
@ruby "C:/ruby/bin/locarails" %*
|
data/lib/locarails.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
module Capistrano
|
2
|
+
module Deploy
|
3
|
+
module Strategy
|
4
|
+
class Base
|
5
|
+
protected
|
6
|
+
# A wrapper for Kernel#system that logs the command being executed.
|
7
|
+
def system(*args)
|
8
|
+
cmd = args.join(' ')
|
9
|
+
if RUBY_PLATFORM =~ /win32/
|
10
|
+
cmd.gsub!('/','\\') # Replace / with \\
|
11
|
+
cmd.gsub!(/^cd /,'cd /D ') # Replace cd with cd /D
|
12
|
+
cmd.gsub!(/&& cd /,'&& cd /D ') # Replace cd with cd /D
|
13
|
+
cmd.gsub!('%%', '/') # Avoid windows command line parameters to be erroneously replaced by backslashes
|
14
|
+
logger.trace "executing locally: #{cmd}"
|
15
|
+
super(cmd)
|
16
|
+
else
|
17
|
+
logger.trace "executing locally: #{cmd}"
|
18
|
+
super
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
class Capistrano::Deploy::Strategy::Copy
|
2
|
+
# Obtains a copy of the source code locally (via the #command method),
|
3
|
+
# compresses it to a single file, copies that file to all target
|
4
|
+
# servers, and uncompresses it on each of them into the deployment
|
5
|
+
# directory.
|
6
|
+
def deploy!
|
7
|
+
if copy_cache
|
8
|
+
if File.exists?(copy_cache)
|
9
|
+
logger.debug "refreshing local cache to revision #{revision} at #{copy_cache}"
|
10
|
+
system(source.sync(revision, copy_cache))
|
11
|
+
else
|
12
|
+
logger.debug "preparing local cache at #{copy_cache}"
|
13
|
+
system(source.checkout(revision, copy_cache))
|
14
|
+
end
|
15
|
+
|
16
|
+
logger.debug "copying cache to deployment staging area #{destination}"
|
17
|
+
Dir.chdir(copy_cache) do
|
18
|
+
FileUtils.mkdir_p(destination)
|
19
|
+
queue = Dir.glob("*", File::FNM_DOTMATCH)
|
20
|
+
while queue.any?
|
21
|
+
item = queue.shift
|
22
|
+
name = File.basename(item)
|
23
|
+
|
24
|
+
next if name == "." || name == ".."
|
25
|
+
next if copy_exclude.any? { |pattern| File.fnmatch(pattern, item) }
|
26
|
+
|
27
|
+
if File.symlink?(item)
|
28
|
+
FileUtils.ln_s(File.readlink(File.join(copy_cache, item)), File.join(destination, item))
|
29
|
+
elsif File.directory?(item)
|
30
|
+
queue += Dir.glob("#{item}/*", File::FNM_DOTMATCH)
|
31
|
+
FileUtils.mkdir(File.join(destination, item))
|
32
|
+
else
|
33
|
+
FileUtils.ln(File.join(copy_cache, item), File.join(destination, item))
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
else
|
38
|
+
logger.debug "getting (via #{copy_strategy}) revision #{revision} to #{destination}"
|
39
|
+
system(command)
|
40
|
+
|
41
|
+
if copy_exclude.any?
|
42
|
+
logger.debug "processing exclusions..."
|
43
|
+
if copy_exclude.any?
|
44
|
+
copy_exclude.each do |pattern|
|
45
|
+
delete_list = Dir.glob(File.join(destination, pattern), File::FNM_DOTMATCH)
|
46
|
+
# avoid the /.. trap that deletes the parent directories
|
47
|
+
delete_list.delete_if { |dir| dir =~ /\/\.\.$/ }
|
48
|
+
FileUtils.rm_rf(delete_list.compact)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
File.open(File.join(destination, "REVISION"), "w") { |f| f.puts(revision) }
|
55
|
+
|
56
|
+
logger.trace "compressing #{destination} to #{filename}"
|
57
|
+
# if it is Windows, force gzip using the pure Ruby minitar library
|
58
|
+
if Capistrano::Deploy::LocalDependency.on_windows?
|
59
|
+
require 'zlib'
|
60
|
+
require 'archive/tar/minitar'
|
61
|
+
Dir.chdir(tmpdir) { Archive::Tar::Minitar.pack(File.basename(destination), Zlib::GzipWriter.new(File.open(File.basename(filename), 'wb'))) }
|
62
|
+
configuration[:copy_compression] = :gzip
|
63
|
+
else
|
64
|
+
Dir.chdir(tmpdir) { system(compress(File.basename(destination), File.basename(filename)).join(" ")) }
|
65
|
+
end
|
66
|
+
|
67
|
+
upload(filename, remote_filename)
|
68
|
+
run "cd #{configuration[:releases_path]} && #{decompress(remote_filename).join(" ")} && rm #{remote_filename}"
|
69
|
+
ensure
|
70
|
+
FileUtils.rm filename rescue nil
|
71
|
+
FileUtils.rm_rf destination rescue nil
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
unless Gem.source_index.find_name('capistrano').select { |g| g.version.to_s =~ /^2\.5/ }.empty?
|
3
|
+
puts "Loading temporary fixes for Capistrano 2.5.x"
|
4
|
+
require 'capistrano'
|
5
|
+
require 'capistrano/recipes/deploy/dependencies'
|
6
|
+
require 'capistrano/recipes/deploy/strategy/base'
|
7
|
+
require 'capistrano/recipes/deploy/strategy/copy'
|
8
|
+
require 'capistrano/recipes/deploy/scm/git'
|
9
|
+
require 'capistrano/recipes/deploy/scm/none'
|
10
|
+
require 'locarails/base'
|
11
|
+
require 'locarails/copy'
|
12
|
+
require 'locarails/git'
|
13
|
+
require 'locarails/none'
|
14
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
class Capistrano::Deploy::SCM::Git
|
2
|
+
alias :checkout_old :checkout
|
3
|
+
def checkout(revision, destination)
|
4
|
+
sub_wrapper(:checkout_old, revision, destination)
|
5
|
+
end
|
6
|
+
|
7
|
+
alias :sync_old :sync
|
8
|
+
def sync(revision, destination)
|
9
|
+
sub_wrapper(:sync_old, revision, destination)
|
10
|
+
end
|
11
|
+
|
12
|
+
def sub_wrapper(method, revision, destination)
|
13
|
+
execute = send(method, revision, destination) # execute original method
|
14
|
+
# filter the git URL to force it to a local file:// URL
|
15
|
+
execute.collect do |line|
|
16
|
+
if line.include?(configuration[:repository])
|
17
|
+
line.sub(configuration[:repository], remote_repository)
|
18
|
+
else
|
19
|
+
line
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# force the remote git commands to fetch from the local filesystem instead
|
25
|
+
# making a round-trip to itself through ssh
|
26
|
+
def remote_repository
|
27
|
+
url = "#{configuration[:user]}@#{configuration[:domain]}:"
|
28
|
+
@remote_repository ||= if configuration[:repository].include?(url)
|
29
|
+
tmp = configuration[:repository].sub(url, "file://")
|
30
|
+
if tmp.include?("~")
|
31
|
+
tmp.sub!("~", "/home/#{configuration[:user]}")
|
32
|
+
end
|
33
|
+
tmp
|
34
|
+
else
|
35
|
+
configuration[:repository]
|
36
|
+
end
|
37
|
+
@remote_repository
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
class Capistrano::Deploy::SCM::None
|
2
|
+
# Simply does a copy from the :repository directory to the
|
3
|
+
# :destination directory.
|
4
|
+
# fix: avoid xcopy parameters to be erroneously replaced by backslashes
|
5
|
+
def checkout(revision, destination)
|
6
|
+
!Capistrano::Deploy::LocalDependency.on_windows? ? "cp -R #{repository} #{destination}" : "xcopy #{repository} \"#{destination}\" %%S%%I%%Y%%Q%%E"
|
7
|
+
end
|
8
|
+
|
9
|
+
alias_method :export, :checkout
|
10
|
+
end
|
data/tasks/gems.rake
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
locarails_gemspec = Gem::Specification.new do |s|
|
2
|
+
s.name = "locarails"
|
3
|
+
s.version = Locarails::VERSION::STRING
|
4
|
+
s.homepage = "http://www.locaweb.com.br/rails"
|
5
|
+
s.summary = "Configuracao de Capistrano automatica para hospedagens Linux Locaweb."
|
6
|
+
s.authors = ["Fabio Akita"]
|
7
|
+
s.date = %q{Time.now.strftime("%Y/%d/%m")}
|
8
|
+
s.default_executable = "locarails"
|
9
|
+
s.description = "A maneira mais simples para instalar aplicacoes Rails na hospedagem Linux da Locaweb."
|
10
|
+
s.email = "fabio.akita@locaweb.com.br"
|
11
|
+
s.executables = ["locarails"]
|
12
|
+
s.files = Dir.glob("{bin,lib,templates,tasks}/**/*") + ['templates/.gitignore']
|
13
|
+
s.has_rdoc = true
|
14
|
+
s.require_paths = ["lib"]
|
15
|
+
|
16
|
+
s.add_runtime_dependency("capistrano", [">= 2.0.0"])
|
17
|
+
s.add_runtime_dependency("highline", [">= 0"])
|
18
|
+
s.add_runtime_dependency("archive-tar-minitar", [">= 0.5.2"])
|
19
|
+
end
|
20
|
+
|
21
|
+
|
22
|
+
Rake::GemPackageTask.new(locarails_gemspec) do |pkg|
|
23
|
+
pkg.gem_spec = locarails_gemspec
|
24
|
+
end
|
25
|
+
|
26
|
+
namespace :gem do
|
27
|
+
namespace :spec do
|
28
|
+
desc "Update locarails.gemspec"
|
29
|
+
task :generate do
|
30
|
+
File.open("locarails.gemspec", "w") do |f|
|
31
|
+
f.puts(locarails_gemspec.to_ruby)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
desc "Generate package and install"
|
38
|
+
task :install => :package do
|
39
|
+
sh %{sudo gem install --local pkg/locarails-#{Locarails::VERSION}}
|
40
|
+
end
|
41
|
+
|
42
|
+
desc "Remove all generated artifacts"
|
43
|
+
task :clean => :clobber_package
|
@@ -0,0 +1,22 @@
|
|
1
|
+
log/*.log
|
2
|
+
log/*.out
|
3
|
+
log/*.pid
|
4
|
+
tmp/**/*
|
5
|
+
.DS_Store
|
6
|
+
db/schema.rb
|
7
|
+
db/schema.sql
|
8
|
+
db/*.sqlite3*
|
9
|
+
config/database.yml
|
10
|
+
config/database.locaweb.yml
|
11
|
+
public/photos/*
|
12
|
+
public/upload/*
|
13
|
+
public/assets/*
|
14
|
+
.project
|
15
|
+
.#*
|
16
|
+
tmp/.*
|
17
|
+
\#*
|
18
|
+
*~
|
19
|
+
vendor/**/**/doc/*
|
20
|
+
rsa_key*
|
21
|
+
coverage/
|
22
|
+
coverage
|
@@ -0,0 +1,136 @@
|
|
1
|
+
# =============================================================================
|
2
|
+
# TAREFAS - NAO MEXER A MENOS QUE SAIBA O QUE ESTA FAZENDO
|
3
|
+
# =============================================================================
|
4
|
+
desc "Garante que o database.yml foi corretamente configurado"
|
5
|
+
task :before_symlink do
|
6
|
+
on_rollback {}
|
7
|
+
run "test -d #{release_path}/tmp || mkdir -m 755 #{release_path}/tmp"
|
8
|
+
run "test -d #{release_path}/db || mkdir -m 755 #{release_path}/db"
|
9
|
+
run "cp #{deploy_to}/etc/database.yml #{release_path}/config/database.yml"
|
10
|
+
run "cd #{release_path} && rake db:migrate RAILS_ENV=production"
|
11
|
+
end
|
12
|
+
|
13
|
+
desc "Garante que as configuracoes estao adequadas"
|
14
|
+
task :before_setup do
|
15
|
+
ts = Time.now.strftime("%y%m%d%H%M%S")
|
16
|
+
<% if config.mode == 'git' %>
|
17
|
+
# git folder
|
18
|
+
run "test -d #{git_repo} || mkdir -p -m 755 #{git_repo}"
|
19
|
+
run "test -d #{git_repo}/.git || cd #{git_repo} && git init"
|
20
|
+
git_config = File.join(File.dirname(__FILE__), "../.git/config")
|
21
|
+
|
22
|
+
has_git = false
|
23
|
+
if File.exists?(git_config)
|
24
|
+
`git remote rm #{remote_repo}` if File.read(git_config) =~ /\[remote\s+\"#{remote_repo}\"\]/
|
25
|
+
`git remote add #{remote_repo} #{repository}`
|
26
|
+
output = `git branch`.strip
|
27
|
+
`git checkout master && git checkout -b #{branch}` if output !~ /#{branch}/
|
28
|
+
`git checkout #{branch}` if output !~ /^\*\s+#{branch}/
|
29
|
+
`git push #{remote_repo} #{branch}`
|
30
|
+
has_git = true
|
31
|
+
end
|
32
|
+
<% end %>
|
33
|
+
|
34
|
+
run "test -d /home/#{user}/rails_app || mkdir -m 755 /home/#{user}/rails_app"
|
35
|
+
run "if [ -d #{deploy_to} ]; then mv #{deploy_to} #{deploy_to}-#{ts}.old ; fi"
|
36
|
+
run "test -d #{deploy_to} || mkdir -m 755 #{deploy_to}"
|
37
|
+
run "test -d #{deploy_to}/etc || mkdir -m 755 #{deploy_to}/etc"
|
38
|
+
run "if [ -d #{site_path} ]; then mv #{site_path} #{site_path}-#{ts}.old ; fi"
|
39
|
+
run "if [ -h #{site_path} ]; then mv #{site_path} #{site_path}-#{ts}.old ; fi"
|
40
|
+
run "ln -s #{deploy_to}/current/public #{public_html}/#{application}"
|
41
|
+
upload File.join(File.dirname(__FILE__), "database.locaweb.yml"), "#{deploy_to}/etc/database.yml"
|
42
|
+
upload File.join(File.dirname(__FILE__), "locaweb_backup.rb"), "#{deploy_to}/etc/locaweb_backup.rb"
|
43
|
+
upload File.join(File.dirname(__FILE__), "ssh_helper.rb"), "#{deploy_to}/etc/ssh_helper.rb"
|
44
|
+
|
45
|
+
<% if config.mode == 'git' %>
|
46
|
+
# ssh keygen
|
47
|
+
run "test -f ~/.ssh/id_rsa || ruby #{deploy_to}/etc/ssh_helper.rb /home/#{user}/.ssh/id_rsa #{domain} #{user}"
|
48
|
+
|
49
|
+
unless has_git
|
50
|
+
2.times { puts "" }
|
51
|
+
puts "==============================================================="
|
52
|
+
puts "Rode os seguintes comandos depois de criar seu repositorio Git:"
|
53
|
+
puts ""
|
54
|
+
puts " git remote add #{remote_repo} #{repository}"
|
55
|
+
puts " git push #{remote_repo} #{branch}"
|
56
|
+
puts "==============================================================="
|
57
|
+
2.times { puts "" }
|
58
|
+
end
|
59
|
+
<% end %>
|
60
|
+
end
|
61
|
+
|
62
|
+
desc "Prepare the production database before migration"
|
63
|
+
task :before_cold do
|
64
|
+
end
|
65
|
+
|
66
|
+
namespace :deploy do
|
67
|
+
desc "Pede restart ao servidor Passenger"
|
68
|
+
task :restart, :roles => :app do
|
69
|
+
run "chmod -R 755 #{release_path}"
|
70
|
+
run "touch #{deploy_to}/current/tmp/restart.txt"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
[:start, :stop].each do |t|
|
75
|
+
desc "A tarefa #{t} nao eh necessaria num ambiente com Passenger"
|
76
|
+
task t, :roles => :app do ; end
|
77
|
+
end
|
78
|
+
|
79
|
+
namespace :log do
|
80
|
+
desc "tail production log files"
|
81
|
+
task :tail, :roles => :app do
|
82
|
+
run "tail -f #{shared_path}/log/production.log" do |channel, stream, data|
|
83
|
+
puts # para uma linha extra
|
84
|
+
puts "#{channel[:host]}: #{data}"
|
85
|
+
break if stream == :err
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
namespace :db do
|
91
|
+
desc "Faz o backup remoto e download do banco de dados MySQL"
|
92
|
+
task :backup, :roles => :db do
|
93
|
+
backup_rb ||= "#{deploy_to}/etc/locaweb_backup.rb"
|
94
|
+
run "if [ -f #{backup_rb} ]; then ruby #{backup_rb} backup #{deploy_to} ; fi"
|
95
|
+
get "#{deploy_to}/etc/dump.tar.gz", "dump.tar.gz"
|
96
|
+
run "rm #{deploy_to}/etc/dump.tar.gz"
|
97
|
+
end
|
98
|
+
|
99
|
+
desc "Faz o upload e o restore remoto do banco de dados MySQL"
|
100
|
+
task :restore, :roles => :db do
|
101
|
+
unless File.exists?("dump.tar.gz")
|
102
|
+
puts "Backup dump.tar.gz nao encontrado"
|
103
|
+
exit 0
|
104
|
+
end
|
105
|
+
backup_rb ||= "#{deploy_to}/etc/locaweb_backup.rb"
|
106
|
+
upload "dump.tar.gz", "#{deploy_to}/etc/dump.tar.gz"
|
107
|
+
run "if [ -f #{backup_rb} ]; then ruby #{backup_rb} restore #{deploy_to} ; fi"
|
108
|
+
end
|
109
|
+
|
110
|
+
desc "Apaga todas as tabelas do banco de dados [CUIDADO! OPERACAO SEM VOLTA!]"
|
111
|
+
task :drop_all, :roles => :db do
|
112
|
+
backup_rb ||= "#{deploy_to}/etc/locaweb_backup.rb"
|
113
|
+
run "if [ -f #{backup_rb} ]; then ruby #{backup_rb} drop_all #{deploy_to} ; fi"
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
namespace :ssh do
|
118
|
+
desc "Faz upload da sua chave publica"
|
119
|
+
task :upload_key, :roles => :app do
|
120
|
+
public_key_path = File.expand_path("~/.ssh/id_rsa.pub")
|
121
|
+
unless File.exists?(public_key_path)
|
122
|
+
puts %{
|
123
|
+
Chave publica nao encontrada em #{public_key_path}
|
124
|
+
Crie sua chave - sem passphrase - com o comando:
|
125
|
+
ssh_keygen -t rsa
|
126
|
+
}
|
127
|
+
exit 0
|
128
|
+
end
|
129
|
+
ssh_path = "/home/#{user}/.ssh"
|
130
|
+
run "test -d #{ssh_path} || mkdir -m 755 #{ssh_path}"
|
131
|
+
upload public_key_path, "#{ssh_path}/../id_rsa.pub"
|
132
|
+
run "test -f #{ssh_path}/authorized_keys || touch #{ssh_path}/authorized_keys"
|
133
|
+
run "cat #{ssh_path}/../id_rsa.pub >> #{ssh_path}/authorized_keys"
|
134
|
+
run "chmod 755 #{ssh_path}/authorized_keys"
|
135
|
+
end
|
136
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
# =============================================================================
|
2
|
+
# Receita de Capistrano 2.x para hospedagem compartilhada Linux
|
3
|
+
# utilizando estratégia de cópia sem servidor de versionamento
|
4
|
+
# =============================================================================
|
5
|
+
#
|
6
|
+
# 1. Esta receita é executada na sua maquina local e nao na hospedagem remota
|
7
|
+
#
|
8
|
+
# 2. O Locarails depende da gem Capistrano
|
9
|
+
#
|
10
|
+
# 3. A estrategia de deployment padrao eh Copy, que comprime seu projeto e envia
|
11
|
+
# para o servidor via SCP, e la eh descomprimido. Esta opcao funciona em
|
12
|
+
# qualquer sistema operacional sem mais nenhuma dependencia, incluindo
|
13
|
+
# Windows
|
14
|
+
#
|
15
|
+
# 4. A opcao -m git ativa a receita via Git que eh um repositorio descentralizado
|
16
|
+
# muito eficiente e que garante um deployment ainda mais rapido. Eh necessario
|
17
|
+
# que seu projeto local esteja em git e voce precisa do Git instalado na sua
|
18
|
+
# maquina
|
19
|
+
#
|
20
|
+
# 5. Ainda nao existe suporte a Subversion
|
21
|
+
#
|
22
|
+
#
|
23
|
+
# Autor: Fabio Akita
|
24
|
+
# E-mail: fabio.akita@locaweb.com.br
|
25
|
+
# Locaweb Serviços de Internet S/A
|
26
|
+
# Todos os direitos reservados
|
27
|
+
|
28
|
+
# correcao temporaria para capistrano 2.5.0
|
29
|
+
require 'locarails/fix'
|
30
|
+
|
31
|
+
# =============================================================================
|
32
|
+
# CONFIGURE OS VALORES DE ACORDO COM SUA HOSPEDAGEM
|
33
|
+
# =============================================================================
|
34
|
+
set :user, "<%= config.usuario %>"
|
35
|
+
set :domain, "<%= config.dominio %>"
|
36
|
+
set :application, "<%= config.app_name %>"
|
37
|
+
<% if config.mode == 'git' %>
|
38
|
+
set :repository, "<%= config.remote_git %>"
|
39
|
+
set :remote_repo, '<%= config.remote_repo %>'
|
40
|
+
set :branch, '<%= config.branch %>'
|
41
|
+
set :git_repo, "/home/#{user}/repo/#{application}.git"
|
42
|
+
<% else %>
|
43
|
+
set :repository, "<%= config.local_path %>"
|
44
|
+
<% end %>
|
45
|
+
<% if config.ssh_key_path %>
|
46
|
+
ssh_options[:keys] = File.expand_path("<%= config.ssh_key_path %>") # apenas descomente se tiver chave
|
47
|
+
<% end %>
|
48
|
+
|
49
|
+
# =============================================================================
|
50
|
+
# NAO MEXER DAQUI PARA BAIXO
|
51
|
+
# =============================================================================
|
52
|
+
role :web, domain
|
53
|
+
role :app, domain
|
54
|
+
role :db, domain
|
55
|
+
|
56
|
+
set :deploy_to, "/home/#{user}/rails_app/#{application}"
|
57
|
+
set :public_html, "/home/#{user}/public_html"
|
58
|
+
set :site_path, "#{public_html}/#{application}"
|
59
|
+
set :runner, nil
|
60
|
+
set :use_sudo, false
|
61
|
+
set :no_release, true
|
62
|
+
|
63
|
+
<% if config.mode == 'git' %>
|
64
|
+
set :scm, :git
|
65
|
+
set :deploy_via, :remote_cache
|
66
|
+
set :git_shallow_clone, 1
|
67
|
+
set :remote, user
|
68
|
+
set :scm_verbose, true
|
69
|
+
<% else %>
|
70
|
+
set :scm, :none
|
71
|
+
set :deploy_via, :copy
|
72
|
+
<% end %>
|
73
|
+
set :copy_exclude, %w(.git/* .svn/* log/* tmp/* .gitignore)
|
74
|
+
set :keep_releases, 5
|
75
|
+
|
76
|
+
ssh_options[:username] = user
|
77
|
+
ssh_options[:paranoid] = false
|
@@ -0,0 +1,30 @@
|
|
1
|
+
#!/usr/bin/env ruby -wKU
|
2
|
+
require 'yaml'
|
3
|
+
require 'erb'
|
4
|
+
|
5
|
+
operation, deploy_to = ARGV
|
6
|
+
cfg = YAML::load(ERB.new(IO.read("#{deploy_to}/etc/database.yml")).result)
|
7
|
+
exit 0 unless cfg['production'] # sai se nao encontrar o arquivo de banco
|
8
|
+
prd = cfg['production']
|
9
|
+
mysql_opts = "-u #{prd['username']} -p#{prd['password']} -h #{prd['host']} #{prd['database']}"
|
10
|
+
mysql_opts_no_data = "-u #{prd['username']} -p#{prd['password']} -h #{prd['host']} --add-drop-table --no-data #{prd['database']}"
|
11
|
+
|
12
|
+
commands = []
|
13
|
+
|
14
|
+
case operation
|
15
|
+
when 'backup'
|
16
|
+
commands << "mysqldump #{mysql_opts} > #{deploy_to}/etc/dump.sql"
|
17
|
+
commands << "cd #{deploy_to}/etc && tar cvfz dump.tar.gz dump.sql"
|
18
|
+
commands << "rm #{deploy_to}/etc/dump.sql"
|
19
|
+
when 'restore'
|
20
|
+
commands << "cd #{deploy_to}/etc && if [ -f dump.tar.gz ]; then tar xvfz dump.tar.gz dump.sql ; fi"
|
21
|
+
commands << "if [ -f #{deploy_to}/etc/dump.sql ]; then mysql -u #{mysql_opts} < #{deploy_to}/etc/dump.sql && rm #{deploy_to}/etc/dump.sql ; fi"
|
22
|
+
when 'drop_all'
|
23
|
+
commands << "mysqldump #{mysql_opts_no_data} | grep ^DROP | mysql #{mysql_opts}"
|
24
|
+
end
|
25
|
+
|
26
|
+
commands.each do |cmd|
|
27
|
+
puts "executando: #{cmd.gsub(prd['password'], '*****')}"
|
28
|
+
`#{cmd}`
|
29
|
+
end
|
30
|
+
puts "operacao #{operation} finalizada."
|
@@ -0,0 +1,319 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
gem "net-ssh", ">= 1.1.3"
|
3
|
+
require 'base64'
|
4
|
+
require 'net/ssh'
|
5
|
+
|
6
|
+
#--
|
7
|
+
# =============================================================================
|
8
|
+
# Copyright (c) 2004,2005 Jamis Buck (jamis@37signals.com)
|
9
|
+
# All rights reserved.
|
10
|
+
#
|
11
|
+
# This source file is distributed as part of the Net::SSH Secure Shell Client
|
12
|
+
# library for Ruby. This file (and the library as a whole) may be used only as
|
13
|
+
# allowed by either the BSD license, or the Ruby license (or, by association
|
14
|
+
# with the Ruby license, the GPL). See the "doc" subdirectory of the Net::SSH
|
15
|
+
# distribution for the texts of these licenses.
|
16
|
+
# -----------------------------------------------------------------------------
|
17
|
+
# net-ssh website : http://net-ssh.rubyforge.org
|
18
|
+
# project website: http://rubyforge.org/projects/net-ssh
|
19
|
+
# =============================================================================
|
20
|
+
#++
|
21
|
+
|
22
|
+
module Net
|
23
|
+
module SSH
|
24
|
+
|
25
|
+
module Util
|
26
|
+
|
27
|
+
# The abstract ancestor module of both ReaderBufferImpl and
|
28
|
+
# WriterBufferImpl. It defines the common interface for both submodules.
|
29
|
+
module BufferBase
|
30
|
+
|
31
|
+
# exposes the content of the buffer
|
32
|
+
attr_reader :content
|
33
|
+
|
34
|
+
# the length of the buffer's content.
|
35
|
+
def length
|
36
|
+
@content.length
|
37
|
+
end
|
38
|
+
|
39
|
+
# returns a copy of the buffer's content.
|
40
|
+
def to_s
|
41
|
+
( @content || "" ).dup
|
42
|
+
end
|
43
|
+
|
44
|
+
# Compares the contents of the two buffers.
|
45
|
+
def ==( buffer )
|
46
|
+
to_s == buffer.to_s
|
47
|
+
end
|
48
|
+
|
49
|
+
# Resets the buffer, making it empty.
|
50
|
+
def clear!
|
51
|
+
@content = ""
|
52
|
+
end
|
53
|
+
|
54
|
+
def init_BufferBase( content="" )
|
55
|
+
@content = content
|
56
|
+
end
|
57
|
+
private :init_BufferBase
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
# A convenience module for representing a string of encoded data. It
|
62
|
+
# provides an interface for easily reading and decoding the buffer.
|
63
|
+
module ReaderBufferImpl
|
64
|
+
|
65
|
+
# the current position of the pointer in the buffer
|
66
|
+
attr_reader :position
|
67
|
+
|
68
|
+
# used by derived modules and classes to perform any
|
69
|
+
# reader-buffer-specific initialization.
|
70
|
+
def init_ReaderBufferImpl
|
71
|
+
@position = 0
|
72
|
+
end
|
73
|
+
private :init_ReaderBufferImpl
|
74
|
+
|
75
|
+
# Appends the given text to the end of the buffer.
|
76
|
+
def append( text )
|
77
|
+
@content << text
|
78
|
+
end
|
79
|
+
|
80
|
+
# Returns all text from the current pointer to the end of the buffer as
|
81
|
+
# a new buffer as the same class as the receiver.
|
82
|
+
def remainder_as_buffer
|
83
|
+
self.class.new( @content[ @position..-1 ] )
|
84
|
+
end
|
85
|
+
|
86
|
+
# Reads +count+ bytes from the buffer. If +count+ is +nil+, this will
|
87
|
+
# return all remaining text in the buffer. This method will increment
|
88
|
+
# the pointer.
|
89
|
+
def read( count = nil )
|
90
|
+
count = length - @position unless count
|
91
|
+
return nil if @position + count > length
|
92
|
+
|
93
|
+
@position += count
|
94
|
+
@content[ @position-count, count ]
|
95
|
+
end
|
96
|
+
|
97
|
+
# Return the next 8 bytes as a 64-bit integer (in network byte order).
|
98
|
+
def read_int64
|
99
|
+
hi = read_long
|
100
|
+
lo = read_long
|
101
|
+
return ( hi << 32 ) + lo
|
102
|
+
end
|
103
|
+
|
104
|
+
# Return the next four bytes as a long integer (in network byte order).
|
105
|
+
def read_long
|
106
|
+
b = read( 4 ) or return nil
|
107
|
+
b.unpack( "N" ).first
|
108
|
+
end
|
109
|
+
|
110
|
+
# Read the next two bytes as a short integer (in network byte order).
|
111
|
+
def read_short
|
112
|
+
b = read( 2 ) or return nil
|
113
|
+
b.unpack( "n" ).first
|
114
|
+
end
|
115
|
+
|
116
|
+
# Read and return the next byte in the buffer.
|
117
|
+
def read_byte
|
118
|
+
b = read( 1 ) or return nil
|
119
|
+
b[0]
|
120
|
+
end
|
121
|
+
|
122
|
+
# Read and return an SSH2-encoded string. The string starts with a long
|
123
|
+
# integer that describes the number of bytes remaining in the string.
|
124
|
+
def read_string
|
125
|
+
length = read_long or return nil
|
126
|
+
read( length )
|
127
|
+
end
|
128
|
+
|
129
|
+
# Read a single byte and convert it into a boolean, using 'C' rules
|
130
|
+
# (i.e., zero is false, non-zero is true).
|
131
|
+
def read_bool
|
132
|
+
b = read( 1 ) or return nil
|
133
|
+
b[0] != 0
|
134
|
+
end
|
135
|
+
|
136
|
+
# Resets the pointer to the start of the buffer.
|
137
|
+
def reset!
|
138
|
+
@position = 0
|
139
|
+
end
|
140
|
+
|
141
|
+
# Returns true if the pointer is at the end of the buffer.
|
142
|
+
def eof?
|
143
|
+
@position >= length
|
144
|
+
end
|
145
|
+
|
146
|
+
# Resets the buffer, making it empty.
|
147
|
+
def clear!
|
148
|
+
@content = ""
|
149
|
+
@position = 0
|
150
|
+
end
|
151
|
+
|
152
|
+
end # ReaderBufferImpl
|
153
|
+
|
154
|
+
# A convenience module for writing a string of encoded data. It provides
|
155
|
+
# an interface for easily writing and encoding data.
|
156
|
+
module WriterBufferImpl
|
157
|
+
|
158
|
+
def init_WriterBufferImpl
|
159
|
+
# nothing
|
160
|
+
end
|
161
|
+
private :init_WriterBufferImpl
|
162
|
+
|
163
|
+
# Writes the given data literally into the string.
|
164
|
+
def write( *data )
|
165
|
+
@content << data.join
|
166
|
+
end
|
167
|
+
|
168
|
+
# Writes each argument to the buffer as a network-byte-order-encoded
|
169
|
+
# 64-bit integer (8 bytes).
|
170
|
+
def write_int64( *n )
|
171
|
+
n.each do |i|
|
172
|
+
hi = ( i >> 32 ) & 0xFFFFFFFF
|
173
|
+
lo = i & 0xFFFFFFFF
|
174
|
+
@content << [ hi, lo ].pack( "N2" )
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
# Writes each argument to the buffer as a network-byte-order-encoded
|
179
|
+
# long (4-byte) integer.
|
180
|
+
def write_long( *n )
|
181
|
+
@content << n.pack( "N*" )
|
182
|
+
end
|
183
|
+
|
184
|
+
# Writes each argument to the buffer as a network-byte-order-encoded
|
185
|
+
# short (2-byte) integer.
|
186
|
+
def write_short( *n )
|
187
|
+
@content << n.pack( "n*" )
|
188
|
+
end
|
189
|
+
|
190
|
+
# Writes each argument to the buffer as a byte.
|
191
|
+
def write_byte( *n )
|
192
|
+
@content << n.map { |c| c.chr }.join
|
193
|
+
end
|
194
|
+
|
195
|
+
# Writes each argument to the buffer as an SSH2-encoded string. Each
|
196
|
+
# string is prefixed by its length, encoded as a 4-byte long integer.
|
197
|
+
def write_string( *text )
|
198
|
+
text.each do |string|
|
199
|
+
write_long( string.length )
|
200
|
+
write( string )
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
# Writes each argument to the buffer as a (C-style) boolean, with 1
|
205
|
+
# meaning true, and 0 meaning false.
|
206
|
+
def write_bool( *b )
|
207
|
+
@content << b.map { |v| ( v ? 1 : 0 ).chr }.join
|
208
|
+
end
|
209
|
+
|
210
|
+
# Writes each argument to the buffer as a bignum (SSH2-style). No
|
211
|
+
# checking is done to ensure that the arguments are, in fact, bignums.
|
212
|
+
def write_bignum( *n )
|
213
|
+
@content << n.map { |b| b.to_ssh }.join
|
214
|
+
end
|
215
|
+
|
216
|
+
# Writes the given arguments to the buffer as SSH2-encoded keys.
|
217
|
+
def write_key( *key )
|
218
|
+
key.each do |k|
|
219
|
+
write_string( k.ssh_type )
|
220
|
+
|
221
|
+
case k.ssh_type
|
222
|
+
when "ssh-dss"
|
223
|
+
write_bignum( k.p )
|
224
|
+
write_bignum( k.q )
|
225
|
+
write_bignum( k.g )
|
226
|
+
write_bignum( k.pub_key )
|
227
|
+
|
228
|
+
when "ssh-rsa"
|
229
|
+
write_bignum( k.e )
|
230
|
+
write_bignum( k.n )
|
231
|
+
|
232
|
+
else
|
233
|
+
raise NotImplementedError,
|
234
|
+
"unsupported key type '#{k.ssh_type}'"
|
235
|
+
end
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
end # class WriterBufferImpl
|
240
|
+
|
241
|
+
# A convenience class for a read-only buffer.
|
242
|
+
class ReaderBuffer
|
243
|
+
include BufferBase
|
244
|
+
include ReaderBufferImpl
|
245
|
+
|
246
|
+
def initialize( content )
|
247
|
+
init_BufferBase( content )
|
248
|
+
init_ReaderBufferImpl
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
# A convenience class for a write-only buffer.
|
253
|
+
class WriterBuffer
|
254
|
+
include BufferBase
|
255
|
+
include WriterBufferImpl
|
256
|
+
|
257
|
+
def initialize( content="" )
|
258
|
+
init_BufferBase( content )
|
259
|
+
init_WriterBufferImpl
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
# A convenience class for a read/write buffer.
|
264
|
+
class Buffer
|
265
|
+
include BufferBase
|
266
|
+
include ReaderBufferImpl
|
267
|
+
include WriterBufferImpl
|
268
|
+
|
269
|
+
def initialize( content="" )
|
270
|
+
init_BufferBase( content )
|
271
|
+
init_ReaderBufferImpl
|
272
|
+
init_WriterBufferImpl
|
273
|
+
end
|
274
|
+
end
|
275
|
+
|
276
|
+
end # module Util
|
277
|
+
|
278
|
+
end # module SSH
|
279
|
+
end # module Net
|
280
|
+
|
281
|
+
class SSHHelper
|
282
|
+
def self.generate_keys(filename)
|
283
|
+
authorized_file = "#{File.dirname(filename)}/authorized_keys"
|
284
|
+
|
285
|
+
private_key = OpenSSL::PKey::RSA.new(2048)
|
286
|
+
public_pem = export_ssh_pubkey( private_key )
|
287
|
+
|
288
|
+
File.delete( filename ) if File.exists?( filename )
|
289
|
+
File.open( filename, "w" ) { |file| file.write private_key.export }
|
290
|
+
File.delete( "#{filename}.pub" ) if File.exists?("#{filename}.pub")
|
291
|
+
File.open( "#{filename}.pub", "w" ) { |file| file.write public_pem }
|
292
|
+
File.open( authorized_file, 'w') { |file| file.write public_pem + "\n"}
|
293
|
+
|
294
|
+
FileUtils.chmod 0755, authorized_file
|
295
|
+
FileUtils.chmod 0600, filename
|
296
|
+
end
|
297
|
+
|
298
|
+
def self.test_connection(hostname, username)
|
299
|
+
# will create known_host
|
300
|
+
Net::SSH.start(hostname, username) { |ssh| puts ssh.exec!('hostname') }
|
301
|
+
end
|
302
|
+
|
303
|
+
private
|
304
|
+
def self.export_ssh_pubkey( key )
|
305
|
+
s = key.ssh_type + " "
|
306
|
+
|
307
|
+
writer = Net::SSH::Util::WriterBuffer.new
|
308
|
+
writer.write_key key
|
309
|
+
s << Base64.encode64( writer.to_s ).strip.gsub( /[\n\r\t ]/, "" )
|
310
|
+
s << " #{ENV['USER']}@#{ENV['HOSTNAME']}"
|
311
|
+
|
312
|
+
s
|
313
|
+
end
|
314
|
+
end
|
315
|
+
|
316
|
+
if ARGV && ARGV.size == 3
|
317
|
+
SSHHelper.generate_keys(ARGV[0])
|
318
|
+
SSHHelper.test_connection(ARGV[1], ARGV[2])
|
319
|
+
end
|
metadata
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: locarails
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.2.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Fabio Akita
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-09-22 00:00:00 -03:00
|
13
|
+
default_executable: locarails
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: capistrano
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 2.0.0
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: highline
|
27
|
+
type: :runtime
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: "0"
|
34
|
+
version:
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: archive-tar-minitar
|
37
|
+
type: :runtime
|
38
|
+
version_requirement:
|
39
|
+
version_requirements: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: 0.5.2
|
44
|
+
version:
|
45
|
+
description: A maneira mais simples para instalar aplicacoes Rails na hospedagem Linux da Locaweb.
|
46
|
+
email: fabio.akita@locaweb.com.br
|
47
|
+
executables:
|
48
|
+
- locarails
|
49
|
+
extensions: []
|
50
|
+
|
51
|
+
extra_rdoc_files: []
|
52
|
+
|
53
|
+
files:
|
54
|
+
- bin/locarails
|
55
|
+
- bin/locarails.cmd
|
56
|
+
- lib/locarails/base.rb
|
57
|
+
- lib/locarails/copy.rb
|
58
|
+
- lib/locarails/fix.rb
|
59
|
+
- lib/locarails/git.rb
|
60
|
+
- lib/locarails/none.rb
|
61
|
+
- lib/locarails/version.rb
|
62
|
+
- lib/locarails.rb
|
63
|
+
- templates/database.locaweb.yml.erb
|
64
|
+
- templates/deploy.common.rb.erb
|
65
|
+
- templates/deploy.rb.erb
|
66
|
+
- templates/locaweb_backup.rb
|
67
|
+
- templates/ssh_helper.rb
|
68
|
+
- tasks/gems.rake
|
69
|
+
- templates/.gitignore
|
70
|
+
has_rdoc: true
|
71
|
+
homepage: http://www.locaweb.com.br/rails
|
72
|
+
licenses: []
|
73
|
+
|
74
|
+
post_install_message:
|
75
|
+
rdoc_options: []
|
76
|
+
|
77
|
+
require_paths:
|
78
|
+
- lib
|
79
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - ">="
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: "0"
|
84
|
+
version:
|
85
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: "0"
|
90
|
+
version:
|
91
|
+
requirements: []
|
92
|
+
|
93
|
+
rubyforge_project:
|
94
|
+
rubygems_version: 1.3.5
|
95
|
+
signing_key:
|
96
|
+
specification_version: 3
|
97
|
+
summary: Configuracao de Capistrano automatica para hospedagens Linux Locaweb.
|
98
|
+
test_files: []
|
99
|
+
|