traquitana 0.0.11 → 0.0.12

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. data/.gitignore +2 -0
  2. data/Gemfile +4 -0
  3. data/LICENSE +22 -0
  4. data/README.md +71 -0
  5. data/Rakefile +8 -0
  6. data/bin/traq +28 -5
  7. data/config/default.yml +7 -8
  8. data/config/extra.sh +1 -0
  9. data/config/nginx.sh +6 -0
  10. data/config/passenger.sh +6 -7
  11. data/config/proc.sh +37 -16
  12. data/config/traq.yml +25 -0
  13. data/lib/bar.rb +39 -0
  14. data/lib/cleaner.rb +17 -0
  15. data/lib/config.rb +44 -28
  16. data/lib/deployer.rb +59 -0
  17. data/lib/migrator.rb +25 -0
  18. data/lib/packager.rb +44 -0
  19. data/lib/selector.rb +24 -0
  20. data/lib/ssh.rb +43 -0
  21. data/lib/traquitana.rb +3 -0
  22. data/lib/traquitana/version.rb +3 -0
  23. data/spec/bar_spec.rb +45 -0
  24. data/spec/cleaner_spec.rb +22 -0
  25. data/spec/config/Gemfile +0 -0
  26. data/spec/config/Rakefile +0 -0
  27. data/spec/config/app/controllers/people_controller.rb +0 -0
  28. data/spec/config/app/models/people.rb +0 -0
  29. data/spec/config/app/views/people/index.html.erb +0 -0
  30. data/spec/config/app/views/people/show.html.erb +0 -0
  31. data/spec/config/config.ru +0 -0
  32. data/spec/config/config/application.rb +0 -0
  33. data/spec/config/config/environment.rb +0 -0
  34. data/spec/config/config/environments/production.rb +0 -0
  35. data/spec/config/config/initializers/inflections.rb +0 -0
  36. data/spec/config/config/initializers/mime_types.rb +0 -0
  37. data/spec/config/config/locales/en.yml +0 -0
  38. data/spec/config/config/locales/pt-BR.yml +0 -0
  39. data/spec/config/config/routes.rb +0 -0
  40. data/spec/config/config/traq.yml +25 -0
  41. data/spec/config/db/migrate/one.rb +0 -0
  42. data/spec/config/db/migrate/two.rb +0 -0
  43. data/spec/config/lib/test.rb +0 -0
  44. data/spec/config/network_test.txt +1 -0
  45. data/spec/config/public/images/one.jpg +0 -0
  46. data/spec/config/public/images/themes/dark/dark.jpg +0 -0
  47. data/spec/config/public/images/themes/theme.jpg +0 -0
  48. data/spec/config/public/images/three.jpg +0 -0
  49. data/spec/config/public/images/two.jpg +0 -0
  50. data/spec/config/public/images/uploads/avatars/avatar.jpg +0 -0
  51. data/spec/config/public/images/uploads/people/person.jpg +0 -0
  52. data/spec/config/public/images/uploads/upload.jpg +0 -0
  53. data/spec/config/public/javascripts/application.js +0 -0
  54. data/spec/config/public/stylesheets/application.css +0 -0
  55. data/spec/config_spec.rb +64 -0
  56. data/spec/deploy_spec.rb +11 -0
  57. data/spec/migrator_spec.rb +75 -0
  58. data/spec/network_spec.rb +56 -0
  59. data/spec/packager_spec.rb +44 -0
  60. data/spec/selector_spec.rb +14 -0
  61. data/traq/config.yml +25 -0
  62. data/traquitana.gemspec +21 -0
  63. metadata +109 -14
  64. data/lib/deploy.rb +0 -151
data/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ .*.swp
2
+ *.gem
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in traquitana.gemspec
4
+ gemspec
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
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
+ require 'rake/testtask'
4
+
5
+ Rake::TestTask.new do |t|
6
+ t.libs = ["lib"]
7
+ t.test_files = FileList['spec/**/*_spec.rb']
8
+ end
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 File.dirname(__FILE__)+"/../lib/config.rb"
10
- require File.dirname(__FILE__)+"/../lib/deploy.rb"
9
+ require "optparse"
10
+ require File.dirname(File.expand_path(__FILE__))+"/../lib/traquitana.rb"
11
11
 
12
- traq = Traquitana::Deploy.new
13
- traq.setup if ARGV[0] =~ /setup/
14
- traq.run
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
- :directory: /tmp/traq_test
3
- :ignore: 24
4
- :user: taq
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
- :password: fill your password here
23
- :host: localhost
24
- :server: passenger
25
- :shell: bash -l -c
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
@@ -0,0 +1,6 @@
1
+ if [ -d tmp ]; then
2
+ echo -n "Restarting Nginx ... "
3
+ rm -f tmp/restart.txt
4
+ touch tmp/restart.txt
5
+ echo "done."
6
+ fi
data/config/passenger.sh CHANGED
@@ -1,7 +1,6 @@
1
- echo
2
- echo Restarting Passenger
3
- echo --------------------
4
- # sometimes passenger needs a "forced" tip to restart - removing the file first
5
- rm -f tmp/restart.txt
6
- touch tmp/restart.txt
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
- echo Making a safe copy of the old contents ...
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
- echo Stored on traq/$2.safe.zip
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
- echo Running migrations
24
- echo ------------------
25
- bundle exec rake db:migrate
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
- echo
30
- echo Changing file permissions on public to 0755
31
- echo -------------------------------------------
38
+ if [ "$verbose" == "true" ]; then
39
+ echo -n "Changing file permissions on public to 0755 ... "
40
+ fi
32
41
  chmod -R 0755 public/*
33
- echo Changed.
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
- # restart the server
36
- traq/server.sh
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
- class Config
5
- include Singleton
6
-
7
- def initialize
8
- @configs = {}
9
- end
10
-
11
- def dir
12
- "traq"
13
- end
14
-
15
- def config
16
- "#{dir}/config.yml"
17
- end
18
-
19
- def default
20
- "#{File.dirname(File.expand_path(__FILE__))}/../config/default.yml"
21
- end
22
-
23
- def load(other=nil)
24
- @configs = YAML.load(File.read(other || config))
25
- end
26
-
27
- def method_missing(meth)
28
- c = @configs[meth.to_sym]
29
- c ? c : ""
30
- end
31
- end
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