traquitana 0.0.11 → 0.0.12
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 +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
|