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.
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