traquitana 0.0.11 → 0.0.12
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +71 -0
- data/Rakefile +8 -0
- data/bin/traq +28 -5
- data/config/default.yml +7 -8
- data/config/extra.sh +1 -0
- data/config/nginx.sh +6 -0
- data/config/passenger.sh +6 -7
- data/config/proc.sh +37 -16
- data/config/traq.yml +25 -0
- data/lib/bar.rb +39 -0
- data/lib/cleaner.rb +17 -0
- data/lib/config.rb +44 -28
- data/lib/deployer.rb +59 -0
- data/lib/migrator.rb +25 -0
- data/lib/packager.rb +44 -0
- data/lib/selector.rb +24 -0
- data/lib/ssh.rb +43 -0
- data/lib/traquitana.rb +3 -0
- data/lib/traquitana/version.rb +3 -0
- data/spec/bar_spec.rb +45 -0
- data/spec/cleaner_spec.rb +22 -0
- data/spec/config/Gemfile +0 -0
- data/spec/config/Rakefile +0 -0
- data/spec/config/app/controllers/people_controller.rb +0 -0
- data/spec/config/app/models/people.rb +0 -0
- data/spec/config/app/views/people/index.html.erb +0 -0
- data/spec/config/app/views/people/show.html.erb +0 -0
- data/spec/config/config.ru +0 -0
- data/spec/config/config/application.rb +0 -0
- data/spec/config/config/environment.rb +0 -0
- data/spec/config/config/environments/production.rb +0 -0
- data/spec/config/config/initializers/inflections.rb +0 -0
- data/spec/config/config/initializers/mime_types.rb +0 -0
- data/spec/config/config/locales/en.yml +0 -0
- data/spec/config/config/locales/pt-BR.yml +0 -0
- data/spec/config/config/routes.rb +0 -0
- data/spec/config/config/traq.yml +25 -0
- data/spec/config/db/migrate/one.rb +0 -0
- data/spec/config/db/migrate/two.rb +0 -0
- data/spec/config/lib/test.rb +0 -0
- data/spec/config/network_test.txt +1 -0
- data/spec/config/public/images/one.jpg +0 -0
- data/spec/config/public/images/themes/dark/dark.jpg +0 -0
- data/spec/config/public/images/themes/theme.jpg +0 -0
- data/spec/config/public/images/three.jpg +0 -0
- data/spec/config/public/images/two.jpg +0 -0
- data/spec/config/public/images/uploads/avatars/avatar.jpg +0 -0
- data/spec/config/public/images/uploads/people/person.jpg +0 -0
- data/spec/config/public/images/uploads/upload.jpg +0 -0
- data/spec/config/public/javascripts/application.js +0 -0
- data/spec/config/public/stylesheets/application.css +0 -0
- data/spec/config_spec.rb +64 -0
- data/spec/deploy_spec.rb +11 -0
- data/spec/migrator_spec.rb +75 -0
- data/spec/network_spec.rb +56 -0
- data/spec/packager_spec.rb +44 -0
- data/spec/selector_spec.rb +14 -0
- data/traq/config.yml +25 -0
- data/traquitana.gemspec +21 -0
- metadata +109 -14
- data/lib/deploy.rb +0 -151
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Eustaquio Rangel
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
# Traquitana
|
2
|
+
|
3
|
+
This project is a collection of scripts I used before met Capistrano and the
|
4
|
+
other tools to do that.
|
5
|
+
It send some files from your local Rails app directory to a production remote
|
6
|
+
server, using some
|
7
|
+
default libs on Ruby like net/ssh and net/scp, and rubyzip to zip all the files
|
8
|
+
and try to make
|
9
|
+
things faster.
|
10
|
+
|
11
|
+
It was made to run on GNU/Linux, but should work on similar systems.
|
12
|
+
|
13
|
+
## Installation
|
14
|
+
|
15
|
+
Add this line to your application's Gemfile:
|
16
|
+
|
17
|
+
gem 'traquitana'
|
18
|
+
|
19
|
+
And then execute:
|
20
|
+
|
21
|
+
$ bundle
|
22
|
+
|
23
|
+
Or install it yourself as:
|
24
|
+
|
25
|
+
$ gem install traquitana
|
26
|
+
|
27
|
+
## Usage
|
28
|
+
|
29
|
+
- Go to your Rails app directory.
|
30
|
+
- Run traq setup.
|
31
|
+
- Now you have a traq.yml file on the config dir. Open It.
|
32
|
+
- There are simple configurations there:
|
33
|
+
- host: where your production server is, for example, myhost.com
|
34
|
+
- user: user name to connect to the server (SSH)
|
35
|
+
- password: user password (SSH), can be blank if you use connect with no password to the server
|
36
|
+
- directory: where your app is on the server. please use the full path based on where the login occurs! ex: /home/user/myapp/
|
37
|
+
- ignore: it will just send the files that had changed on less than the number of hours configured here
|
38
|
+
- server: the webserver running on the server. ex: passenger
|
39
|
+
- list: the list of file patterns searched to send to the server
|
40
|
+
|
41
|
+
On the list can have two elements by row, like:
|
42
|
+
|
43
|
+
- - public/images/**/*
|
44
|
+
- public/images/uploads/**/*
|
45
|
+
|
46
|
+
On this example, all below public/images will be send BUT ignoring what is on public/images/uploads. This is a way to
|
47
|
+
make sure you'll not overwrite some production files with your development versions.
|
48
|
+
|
49
|
+
- PLEASE PLEASE PLEASE configure this file. You can create an app on your localhost and
|
50
|
+
make some tests on it 'till you think is safe deal with real apps on production servers.
|
51
|
+
- Run traq (just type traq).
|
52
|
+
- It will search for changed files
|
53
|
+
- Will create a list with the file names found
|
54
|
+
- Will zíp the files.
|
55
|
+
- Will send the list to the server, together with some control files.
|
56
|
+
- What the control files deal: they are shell scripts that will zip the old files (based on what new files are going),
|
57
|
+
unzip the new files, run migrations if needed and restart the web server. There are two files: one generic to make all
|
58
|
+
sort of things BUT not restarting the web server. The webserver script will be send based on what webserver you need.
|
59
|
+
- Now everything should be updated. On the next time you want to update your project, just run traq again.
|
60
|
+
|
61
|
+
* The list and the zip file created with the old files will be used on future versions as a rollback feature.
|
62
|
+
|
63
|
+
Use for your risk. I think it's all ok but I don't give you guarantee if it break something.
|
64
|
+
|
65
|
+
## Contributing
|
66
|
+
|
67
|
+
1. Fork it
|
68
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
69
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
70
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
71
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
data/bin/traq
CHANGED
@@ -6,9 +6,32 @@ require "zip/zip"
|
|
6
6
|
require "net/scp"
|
7
7
|
require "net/ssh"
|
8
8
|
require "fileutils"
|
9
|
-
require
|
10
|
-
require File.dirname(__FILE__)+"/../lib/
|
9
|
+
require "optparse"
|
10
|
+
require File.dirname(File.expand_path(__FILE__))+"/../lib/traquitana.rb"
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
|
12
|
+
@options = {:verbose=>false}
|
13
|
+
|
14
|
+
opts = OptionParser.new
|
15
|
+
opts.banner = "Usage: traq [options] <setup>"
|
16
|
+
|
17
|
+
opts.on("-v","--version","Show version") do
|
18
|
+
puts Traquitana::VERSION
|
19
|
+
exit 0
|
20
|
+
end
|
21
|
+
|
22
|
+
opts.on("-c","--cleanup","Clean up old files") do
|
23
|
+
Traquitana::Cleaner.new.run
|
24
|
+
exit 0
|
25
|
+
end
|
26
|
+
|
27
|
+
opts.on("-V","--verbose","Verbose mode") do
|
28
|
+
@options[:verbose] = true
|
29
|
+
end
|
30
|
+
|
31
|
+
opts.parse!
|
32
|
+
|
33
|
+
if ARGV[0] =~ /setup/
|
34
|
+
Traquitana::Config.instance.setup
|
35
|
+
else
|
36
|
+
Traquitana::Deployer.new(@options).run
|
37
|
+
end
|
data/config/default.yml
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
# Default configuration---
|
2
|
-
|
3
|
-
:
|
4
|
-
:
|
5
|
-
:list:
|
2
|
+
directory: /tmp/traq_test
|
3
|
+
user: taq
|
4
|
+
list:
|
6
5
|
- Rakefile
|
7
6
|
- config.ru
|
8
7
|
- Gemfile
|
@@ -19,7 +18,7 @@
|
|
19
18
|
- - lib/**/*
|
20
19
|
- - public/images/**/*
|
21
20
|
- public/images/uploads/**/*
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
21
|
+
password: fill your password here
|
22
|
+
host: localhost
|
23
|
+
server: passenger
|
24
|
+
shell: bash -l -c
|
data/config/extra.sh
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
# insert custom stuff here
|
data/config/nginx.sh
ADDED
data/config/passenger.sh
CHANGED
@@ -1,7 +1,6 @@
|
|
1
|
-
|
2
|
-
echo Restarting Passenger
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
echo Ok.
|
1
|
+
if [ -d tmp ]; then
|
2
|
+
echo -n "Restarting Passenger ... "
|
3
|
+
rm -f tmp/restart.txt
|
4
|
+
touch tmp/restart.txt
|
5
|
+
echo "done."
|
6
|
+
fi
|
data/config/proc.sh
CHANGED
@@ -4,33 +4,54 @@ export RAILS_ENV=production
|
|
4
4
|
# move to the correct directory
|
5
5
|
cd $1/..
|
6
6
|
|
7
|
+
# verbose mode
|
8
|
+
verbose="$3"
|
9
|
+
|
7
10
|
# make a copy of the old contents
|
8
|
-
|
11
|
+
if [ "$verbose" == "true" ]; then
|
12
|
+
echo -n "Making a safety copy of the old contents on traq/$2 ... "
|
13
|
+
fi
|
9
14
|
zip -q traq/$2.safe.zip `cat traq/$2.list` &> /dev/null
|
10
|
-
|
15
|
+
if [ "$verbose" == "true" ]; then
|
16
|
+
echo "done."
|
17
|
+
fi
|
11
18
|
|
12
19
|
# install the new files
|
13
|
-
echo
|
14
|
-
echo Unzipping the new content
|
15
|
-
echo -------------------------
|
20
|
+
echo -n "Unzipping $2.zip ... "
|
16
21
|
unzip -o traq/$2.zip &> /dev/null
|
22
|
+
echo "done."
|
17
23
|
|
18
24
|
# run migrations if needed
|
19
25
|
migrations=$(grep "^db/migrate" traq/$2.list)
|
20
|
-
|
21
26
|
if [ -n "$migrations" ]; then
|
22
|
-
echo
|
23
|
-
|
24
|
-
|
25
|
-
|
27
|
+
echo "Running migrations ... "
|
28
|
+
bundle exec rake db:migrate 2> /dev/null
|
29
|
+
echo "Migrations done."
|
30
|
+
fi
|
31
|
+
|
32
|
+
# precompile assets if needed
|
33
|
+
if [ -d app/assets ]; then
|
34
|
+
bundle exec rake assets:precompile 2> /dev/null
|
26
35
|
fi
|
27
36
|
|
28
37
|
# change file permissions on public dir
|
29
|
-
|
30
|
-
echo Changing file permissions on public to 0755
|
31
|
-
|
38
|
+
if [ "$verbose" == "true" ]; then
|
39
|
+
echo -n "Changing file permissions on public to 0755 ... "
|
40
|
+
fi
|
32
41
|
chmod -R 0755 public/*
|
33
|
-
|
42
|
+
if [ "$verbose" == "true" ]; then
|
43
|
+
echo "done."
|
44
|
+
fi
|
45
|
+
|
46
|
+
# restart server
|
47
|
+
if [ -x ./traq/server.sh -a -f ./traq/server.sh ]; then
|
48
|
+
./traq/server.sh
|
49
|
+
fi
|
50
|
+
|
51
|
+
# extra configs
|
52
|
+
if [ -x ./traq/extra.sh -a -f ./traq/extra.sh ]; then
|
53
|
+
./traq/extra.sh
|
54
|
+
fi
|
34
55
|
|
35
|
-
#
|
36
|
-
traq
|
56
|
+
# erase file
|
57
|
+
rm traq/$2.zip
|
data/config/traq.yml
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# Sample configuration---
|
2
|
+
directory: /tmp/traq_test
|
3
|
+
user: taq
|
4
|
+
list:
|
5
|
+
- Rakefile
|
6
|
+
- config.ru
|
7
|
+
- Gemfile
|
8
|
+
- - config/application.rb
|
9
|
+
- - config/environment.rb
|
10
|
+
- - config/initializers/**/*
|
11
|
+
- - config/environments/production.rb
|
12
|
+
- - config/locales/**/*
|
13
|
+
- - config/routes.rb
|
14
|
+
- - app/**/*
|
15
|
+
- - db/migrate/**/*
|
16
|
+
- - public/javascripts/**/*
|
17
|
+
- - public/stylesheets/**/*
|
18
|
+
- - lib/**/*
|
19
|
+
- - public/images/**/*
|
20
|
+
- public/images/uploads/**/*
|
21
|
+
- public/images/themes/**/*
|
22
|
+
password: fill your password here
|
23
|
+
host: localhost
|
24
|
+
server: passenger
|
25
|
+
shell: bash -l -c
|
data/lib/bar.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
module Traquitana
|
2
|
+
class Bar
|
3
|
+
attr_reader :current
|
4
|
+
attr_accessor :name, :total
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
reset
|
8
|
+
end
|
9
|
+
|
10
|
+
def reset
|
11
|
+
@name = nil
|
12
|
+
@total = 0
|
13
|
+
@current = 0
|
14
|
+
@bar_size = 20
|
15
|
+
@bar_step = 5
|
16
|
+
end
|
17
|
+
|
18
|
+
def indicator(current)
|
19
|
+
bar = Array.new(@bar_size,"_")
|
20
|
+
return bar.join if current<=0
|
21
|
+
|
22
|
+
prop = current>0 ? ((100/(total/current.to_f))/@bar_step).to_i : 0
|
23
|
+
return bar.join if prop<=0
|
24
|
+
|
25
|
+
bar[0...prop] = Array.new(prop,"#")
|
26
|
+
bar.join
|
27
|
+
end
|
28
|
+
|
29
|
+
def update(current)
|
30
|
+
@current = current
|
31
|
+
file = File.basename(@name).ljust(25)
|
32
|
+
STDOUT.print "#{file} : #{self.indicator(current)}\r"
|
33
|
+
if @current>=@total
|
34
|
+
STDOUT.puts "\n"
|
35
|
+
@current = -1
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/lib/cleaner.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
module Traquitana
|
2
|
+
class Cleaner
|
3
|
+
attr_accessor :network
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
@config = Traquitana::Config.instance
|
7
|
+
@config.load
|
8
|
+
@network = Traquitana::SSH.new(@config.host,@config.user)
|
9
|
+
end
|
10
|
+
|
11
|
+
def run
|
12
|
+
STDOUT.print "Cleaning old files ... "
|
13
|
+
@network.execute(["find #{@config.directory}/traq -type f -iname '*.zip' -o -iname '*.list' | sort | head -n-2 | xargs rm $1"])
|
14
|
+
STDOUT.puts "done."
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/lib/config.rb
CHANGED
@@ -1,32 +1,48 @@
|
|
1
1
|
require "singleton"
|
2
2
|
|
3
3
|
module Traquitana
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
4
|
+
class Config
|
5
|
+
include Singleton
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@configs = {}
|
9
|
+
end
|
10
|
+
|
11
|
+
def filename
|
12
|
+
"config/traq.yml"
|
13
|
+
end
|
14
|
+
|
15
|
+
def default
|
16
|
+
"#{File.dirname(File.expand_path(__FILE__))}/../config/default.yml"
|
17
|
+
end
|
18
|
+
|
19
|
+
def load(file=nil)
|
20
|
+
@configs = YAML.load(File.read(file || self.filename))
|
21
|
+
end
|
22
|
+
|
23
|
+
def method_missing(meth)
|
24
|
+
@configs[meth.to_s] || ""
|
25
|
+
end
|
26
|
+
|
27
|
+
def setup
|
28
|
+
STDOUT.puts "Running setup"
|
29
|
+
if File.exists?(self.filename)
|
30
|
+
STDERR.puts "The configuration file #{self.filename} already exists."
|
31
|
+
return false
|
32
|
+
end
|
33
|
+
|
34
|
+
dir = File.dirname(self.filename)
|
35
|
+
Dir.mkdir(dir) if !File.exist?(dir)
|
36
|
+
|
37
|
+
STDOUT.puts "Writing #{self.filename}"
|
38
|
+
File.open(self.filename,"w") do |file|
|
39
|
+
file << "# Default configuration"
|
40
|
+
file << File.read(self.default)
|
41
|
+
end
|
42
|
+
|
43
|
+
STDOUT.puts "Setup completed!"
|
44
|
+
STDOUT.puts "You MUST check the configurations on #{self.filename} before deploying!"
|
45
|
+
true
|
46
|
+
end
|
47
|
+
end
|
32
48
|
end
|
data/lib/deployer.rb
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
module Traquitana
|
2
|
+
class Deployer
|
3
|
+
def initialize(options=nil)
|
4
|
+
@config = Traquitana::Config.instance
|
5
|
+
@options = @config.password.size>1 ? {:password=>@config.password} : {}
|
6
|
+
@verbose = !options.nil? && options[:verbose]
|
7
|
+
end
|
8
|
+
|
9
|
+
def run
|
10
|
+
STDOUT.puts "Running Traquitana version #{VERSION}\n"
|
11
|
+
Traquitana::Migrator.new.run
|
12
|
+
|
13
|
+
if !File.exist?(@config.filename)
|
14
|
+
STDERR.puts "No config file (#{@config.filename}) found."
|
15
|
+
STDERR.puts "Did you run traq setup?"
|
16
|
+
STDERR.puts "Run it and check the configuration before deploying."
|
17
|
+
exit 1
|
18
|
+
end
|
19
|
+
@config.load
|
20
|
+
|
21
|
+
@shell = @config.shell ? "#{@config.shell} " : ""
|
22
|
+
@network = Traquitana::SSH.new(@config.host,@config.user,@options)
|
23
|
+
|
24
|
+
@packager = Traquitana::Packager.new
|
25
|
+
@packager.verbose = @verbose
|
26
|
+
all_list_file, all_list_zip = @packager.pack
|
27
|
+
if !File.exists?(all_list_file) ||
|
28
|
+
!File.exists?(all_list_zip)
|
29
|
+
STDERR.puts "Could not create the needed files."
|
30
|
+
exit 2
|
31
|
+
end
|
32
|
+
|
33
|
+
# check if the traq destination and config directories exists
|
34
|
+
@network.execute(["mkdir -p #{@config.directory}/traq"],@verbose)
|
35
|
+
@updater = Traquitana::Bar.new
|
36
|
+
|
37
|
+
STDOUT.puts "Sending files ..."
|
38
|
+
@network.send_files([["#{File.dirname(File.expand_path(__FILE__))}/../config/proc.sh","#{@config.directory}/traq/proc.sh"],
|
39
|
+
["#{File.dirname(File.expand_path(__FILE__))}/../config/#{@config.server}.sh","#{@config.directory}/traq/server.sh"],
|
40
|
+
[all_list_file,"#{@config.directory}/traq/#{File.basename(all_list_file)}"],
|
41
|
+
[all_list_zip ,"#{@config.directory}/traq/#{File.basename(all_list_zip)}"]],@updater)
|
42
|
+
STDOUT.puts "All files sent."
|
43
|
+
|
44
|
+
@network.execute(["chmod +x #{@config.directory}/traq/proc.sh"],@verbose)
|
45
|
+
@network.execute(["chmod +x #{@config.directory}/traq/server.sh"],@verbose)
|
46
|
+
|
47
|
+
cmd = "#{@config.directory}/traq/proc.sh #{@config.directory}/traq #{@packager.id} #{@verbose}"
|
48
|
+
cmd = "#{@shell} \"#{cmd}\"" if @shell
|
49
|
+
|
50
|
+
STDOUT.puts "Running remote update commands, please wait ..."
|
51
|
+
STDOUT.puts @network.execute([cmd],@verbose).join
|
52
|
+
|
53
|
+
# clean up
|
54
|
+
File.unlink(all_list_file)
|
55
|
+
File.unlink(all_list_zip)
|
56
|
+
STDOUT.puts "All done. Have fun.\n"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|