rails_pwnerer 0.6.64 → 0.6.65

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 (60) hide show
  1. data/CHANGELOG +2 -0
  2. data/LICENSE +0 -0
  3. data/Manifest +51 -49
  4. data/README +0 -0
  5. data/RUBYFORGE +0 -0
  6. data/Rakefile +7 -11
  7. data/ext/rpwn_setup_notice/extconf.rb +24 -16
  8. data/lib/{pwnage → rails_pwnerer}/app/cluster_config.rb +17 -17
  9. data/lib/{pwnage → rails_pwnerer}/app/config.rb +14 -14
  10. data/lib/{pwnage → rails_pwnerer}/app/db/mysql.rb +9 -9
  11. data/lib/{pwnage → rails_pwnerer}/app/files.rb +13 -13
  12. data/lib/{pwnage → rails_pwnerer}/app/gems.rb +3 -3
  13. data/lib/{pwnage → rails_pwnerer}/app/main.rb +4 -4
  14. data/lib/{pwnage → rails_pwnerer}/app/nginx_config.rb +7 -7
  15. data/lib/{pwnage → rails_pwnerer}/app/scripts.rb +4 -4
  16. data/lib/{pwnage → rails_pwnerer}/app/vcs/git.rb +9 -9
  17. data/lib/{pwnage → rails_pwnerer}/app/vcs/perforce.rb +11 -11
  18. data/lib/{pwnage → rails_pwnerer}/app/vcs/svn.rb +9 -9
  19. data/lib/{pwnage → rails_pwnerer}/base/atomics.rb +1 -1
  20. data/lib/{pwnage → rails_pwnerer}/base/cpus.rb +1 -1
  21. data/lib/{pwnage → rails_pwnerer}/base/dirs.rb +1 -1
  22. data/lib/{pwnage → rails_pwnerer}/base/gems.rb +2 -2
  23. data/lib/{pwnage → rails_pwnerer}/base/hostname.rb +1 -1
  24. data/lib/{pwnage → rails_pwnerer}/base/input.rb +1 -1
  25. data/lib/rails_pwnerer/base/packages.rb +272 -0
  26. data/lib/{pwnage → rails_pwnerer}/base/process.rb +1 -1
  27. data/lib/{pwnage → rails_pwnerer}/base/rails.rb +1 -1
  28. data/lib/{pwnage → rails_pwnerer}/base/startup.rb +1 -1
  29. data/lib/{pwnage → rails_pwnerer}/base.rb +1 -1
  30. data/lib/{pwnage → rails_pwnerer}/config/app.rb +1 -1
  31. data/lib/{pwnage → rails_pwnerer}/config/frontends.rb +1 -1
  32. data/lib/rails_pwnerer/config/main.rb +3 -0
  33. data/lib/{pwnage → rails_pwnerer}/config/paths.rb +1 -1
  34. data/lib/{pwnage → rails_pwnerer}/config/ports.rb +1 -1
  35. data/lib/{pwnage → rails_pwnerer}/config/repository.rb +7 -7
  36. data/lib/rails_pwnerer/ctl_executor.rb +19 -0
  37. data/lib/{pwnage → rails_pwnerer}/dev_executor.rb +2 -2
  38. data/lib/{pwnage → rails_pwnerer}/executor.rb +17 -17
  39. data/lib/{pwnage → rails_pwnerer}/scaffolds/config.rb +7 -7
  40. data/lib/{pwnage → rails_pwnerer}/scaffolds/dir_permissions.rb +4 -4
  41. data/lib/{pwnage → rails_pwnerer}/scaffolds/dirs.rb +3 -3
  42. data/lib/{pwnage → rails_pwnerer}/scaffolds/gems.rb +2 -2
  43. data/lib/{pwnage → rails_pwnerer}/scaffolds/hook_daemon.rb +2 -2
  44. data/lib/{pwnage → rails_pwnerer}/scaffolds/hook_dyndns.rb +3 -3
  45. data/lib/{pwnage → rails_pwnerer}/scaffolds/mysql_config.rb +2 -2
  46. data/lib/rails_pwnerer/scaffolds/packages.rb +118 -0
  47. data/lib/{pwnage → rails_pwnerer}/scaffolds/rubygems.rb +2 -2
  48. data/lib/{pwnage → rails_pwnerer}/scaffolds/sshd.rb +2 -2
  49. data/lib/{pwnage → rails_pwnerer}/util/kill_process_set.rb +1 -1
  50. data/lib/rails_pwnerer/util/main.rb +5 -0
  51. data/lib/rails_pwnerer.rb +52 -52
  52. data/rails_pwnerer.gemspec +17 -7
  53. data/test/base_package_test.rb +126 -0
  54. data/test/helper.rb +25 -0
  55. metadata +151 -107
  56. data/lib/pwnage/base/packages.rb +0 -159
  57. data/lib/pwnage/config/main.rb +0 -3
  58. data/lib/pwnage/ctl_executor.rb +0 -19
  59. data/lib/pwnage/scaffolds/packages.rb +0 -110
  60. data/lib/pwnage/util/main.rb +0 -5
@@ -1,11 +1,11 @@
1
1
  # checks out and updates the application from a Git repository
2
2
 
3
- class RailsPwnage::App::Git
4
- include RailsPwnage::Base
3
+ class RailsPwnerer::App::Git
4
+ include RailsPwnerer::Base
5
5
 
6
6
  # remove any files not in Git in the application dir
7
7
  def cleanup_app_dir(app_name, instance_name, target_dir, app_name_is_dir = false)
8
- Dir.chdir(app_name_is_dir ? app_name : RailsPwnage::Config[app_name, instance_name][:app_path]) do
8
+ Dir.chdir(app_name_is_dir ? app_name : RailsPwnerer::Config[app_name, instance_name][:app_path]) do
9
9
  Kernel.system "git clean -d -f -x -- #{target_dir}"
10
10
  Kernel.system "git checkout -- #{target_dir}"
11
11
  end
@@ -14,7 +14,7 @@ class RailsPwnage::App::Git
14
14
  # clean up the application directory by removing caches
15
15
  def cleanup_app_caches(app_name, instance_name, app_name_is_dir = false)
16
16
  # TODO: this is almost-duplicated in git.rb -- pull up somewhere
17
- app_path = app_name_is_dir ? app_name : RailsPwnage::Config[app_name, instance_name][:app_path]
17
+ app_path = app_name_is_dir ? app_name : RailsPwnerer::Config[app_name, instance_name][:app_path]
18
18
  return unless File.exists?(File.join(app_path, '.git'))
19
19
 
20
20
  # TODO: learn how Rails caches work and kill those too
@@ -26,7 +26,7 @@ class RailsPwnage::App::Git
26
26
 
27
27
  # reverts the config changes made by rpwn, so git fetch doesn't get confused
28
28
  def revert_config_changes(app_name, instance_name)
29
- Dir.chdir RailsPwnage::Config[app_name, instance_name][:app_path] do
29
+ Dir.chdir RailsPwnerer::Config[app_name, instance_name][:app_path] do
30
30
  ['config', 'Gemfile'].each do |dir|
31
31
  Kernel.system "git clean -d -f -x -- #{dir}"
32
32
  Kernel.system "git checkout -- #{dir}"
@@ -35,14 +35,14 @@ class RailsPwnage::App::Git
35
35
  end
36
36
 
37
37
  def git_update(app_name, instance_name)
38
- Dir.chdir RailsPwnage::Config[app_name, instance_name][:app_path] do
38
+ Dir.chdir RailsPwnerer::Config[app_name, instance_name][:app_path] do
39
39
  print "Doing Git pull, please enter your password if prompted...\n"
40
40
  Kernel.system 'git pull'
41
41
  end
42
42
  end
43
43
 
44
44
  def update(app_name, instance_name)
45
- app_path = RailsPwnage::Config[app_name, instance_name][:app_path]
45
+ app_path = RailsPwnerer::Config[app_name, instance_name][:app_path]
46
46
  return unless File.exists?(File.join(app_path, '.git'))
47
47
  # TODO: maybe backup old version before issuing the git update?
48
48
 
@@ -52,7 +52,7 @@ class RailsPwnage::App::Git
52
52
  end
53
53
 
54
54
  def update_prefetch(app_name, instance_name)
55
- app_path = RailsPwnage::Config[app_name, instance_name][:app_path]
55
+ app_path = RailsPwnerer::Config[app_name, instance_name][:app_path]
56
56
  return unless File.exists?(File.join(app_path, '.git'))
57
57
 
58
58
  Dir.chdir app_path do
@@ -75,7 +75,7 @@ class RailsPwnage::App::Git
75
75
  end
76
76
 
77
77
  return :next unless git_repository =~ /\.git(\/.*)?$/
78
- app_path = RailsPwnage::Config[app_name, instance_name][:app_path]
78
+ app_path = RailsPwnerer::Config[app_name, instance_name][:app_path]
79
79
 
80
80
  FileUtils.rm_rf app_path
81
81
  print "Doing Git clone, please enter your password if prompted...\n"
@@ -5,14 +5,14 @@ require 'fileutils'
5
5
  require 'pathname'
6
6
  require 'set'
7
7
 
8
- class RailsPwnage::App::Perforce
9
- include RailsPwnage::Base
8
+ class RailsPwnerer::App::Perforce
9
+ include RailsPwnerer::Base
10
10
 
11
11
  # TODO(costan): figure out how to remove unused files in perforce and do it
12
12
 
13
13
  # remove any files not in client workspace
14
14
  def cleanup_app_dir(app_name, instance_name, target_dir, app_name_is_dir = false)
15
- path_base = app_name_is_dir ? app_name : RailsPwnage::Config[app_name, instance_name][:app_path]
15
+ path_base = app_name_is_dir ? app_name : RailsPwnerer::Config[app_name, instance_name][:app_path]
16
16
  path_base = File.join path_base, target_dir
17
17
  path_base = path_base[0...-1] if path_base[-1] == '/'
18
18
  Dir.chdir path_base do
@@ -41,7 +41,7 @@ class RailsPwnage::App::Perforce
41
41
  # clean up the application directory by removing caches
42
42
  def cleanup_app_caches(app_name, instance_name, app_name_is_dir = false)
43
43
  # TODO: this is almost-duplicated in git.rb -- pull up somewhere
44
- app_path = app_name_is_dir ? app_name : RailsPwnage::Config[app_name, instance_name][:app_path]
44
+ app_path = app_name_is_dir ? app_name : RailsPwnerer::Config[app_name, instance_name][:app_path]
45
45
  return unless File.exists?(File.join(app_path, '.p4clientspec'))
46
46
 
47
47
  # TODO: learn how Rails caches work and kill those too
@@ -73,7 +73,7 @@ class RailsPwnage::App::Perforce
73
73
  end
74
74
 
75
75
  def perforce_update(app_name, instance_name)
76
- Dir.chdir RailsPwnage::Config[app_name, instance_name][:app_path] do
76
+ Dir.chdir RailsPwnerer::Config[app_name, instance_name][:app_path] do
77
77
  perforce_config_file
78
78
 
79
79
  print "Doing Perforce sync...\n"
@@ -85,7 +85,7 @@ class RailsPwnage::App::Perforce
85
85
  end
86
86
 
87
87
  def checkout(remote_path, app_name, instance_name)
88
- app_path = RailsPwnage::Config[app_name, instance_name][:app_path]
88
+ app_path = RailsPwnerer::Config[app_name, instance_name][:app_path]
89
89
 
90
90
  # paths look like p4://user@depot:port/path/to/application
91
91
  path_regexp = /^p4\:\/\/([^\@\/]*\@)?([^\:\/]*)(:[1-9]+)?\/(.*)$/
@@ -127,7 +127,7 @@ END_SETTINGS
127
127
  end
128
128
 
129
129
  print "Creating Perforce client...\n"
130
- Dir.chdir RailsPwnage::Config[app_name, instance_name][:app_path] do
130
+ Dir.chdir RailsPwnerer::Config[app_name, instance_name][:app_path] do
131
131
  success = Kernel.system "p4 client -i < .p4clientspec"
132
132
  if !success
133
133
  Kernel.system "p4 client -i < .p4clientspec" if try_prompting_for_perforce_password
@@ -142,7 +142,7 @@ END_SETTINGS
142
142
  end
143
143
 
144
144
  def update(app_name, instance_name)
145
- app_path = RailsPwnage::Config[app_name, instance_name][:app_path]
145
+ app_path = RailsPwnerer::Config[app_name, instance_name][:app_path]
146
146
  return unless File.exists?(File.join(app_path, '.p4clientspec'))
147
147
 
148
148
  # TODO: maybe backup old version before issuing the p4 sync?
@@ -152,19 +152,19 @@ END_SETTINGS
152
152
  end
153
153
 
154
154
  def update_prefetch(app_name, instance_name)
155
- app_path = RailsPwnage::Config[app_name, instance_name][:app_path]
155
+ app_path = RailsPwnerer::Config[app_name, instance_name][:app_path]
156
156
  return unless File.exists?(File.join(app_path, '.p4clientspec'))
157
157
 
158
158
  # TODO: maybe figure out a way to prefetch Perforce, if it's ever worth it
159
159
  end
160
160
 
161
161
  def remove(app_name, instance_name)
162
- app_path = RailsPwnage::Config[app_name, instance_name][:app_path]
162
+ app_path = RailsPwnerer::Config[app_name, instance_name][:app_path]
163
163
  return unless File.exists?(File.join(app_path, '.p4clientspec'))
164
164
 
165
165
 
166
166
  print "Deleting Perforce client...\n"
167
- Dir.chdir RailsPwnage::Config[app_name, instance_name][:app_path] do
167
+ Dir.chdir RailsPwnerer::Config[app_name, instance_name][:app_path] do
168
168
  p4_config = File.read perforce_config_file
169
169
  client_match = /^P4CLIENT=(.*)$/.match p4_config
170
170
  p4_client = client_match[1]
@@ -5,12 +5,12 @@ require 'fileutils'
5
5
  require 'pathname'
6
6
  require 'rexml/document'
7
7
 
8
- class RailsPwnage::App::Svn
9
- include RailsPwnage::Base
8
+ class RailsPwnerer::App::Svn
9
+ include RailsPwnerer::Base
10
10
 
11
11
  # remove any files not in SVN in the application dir
12
12
  def cleanup_app_dir(app_name, instance_name, target_dir, app_name_is_dir = false)
13
- Dir.chdir(app_name_is_dir ? app_name : RailsPwnage::Config[app_name, instance_name][:app_path]) do
13
+ Dir.chdir(app_name_is_dir ? app_name : RailsPwnerer::Config[app_name, instance_name][:app_path]) do
14
14
  # get a listing of what happened in that directory
15
15
  xml_status = `svn status --xml #{target_dir}`
16
16
  xsdoc = REXML::Document.new xml_status
@@ -27,7 +27,7 @@ class RailsPwnage::App::Svn
27
27
  # clean up the application directory by removing caches
28
28
  def cleanup_app_caches(app_name, instance_name, app_name_is_dir = false)
29
29
  # TODO: this is almost-duplicated in git.rb -- pull up somewhere
30
- app_path = app_name_is_dir ? app_name : RailsPwnage::Config[app_name, instance_name][:app_path]
30
+ app_path = app_name_is_dir ? app_name : RailsPwnerer::Config[app_name, instance_name][:app_path]
31
31
  return unless File.exists?(File.join(app_path, '.svn'))
32
32
 
33
33
  # TODO: learn how Rails caches work and kill those too
@@ -39,7 +39,7 @@ class RailsPwnage::App::Svn
39
39
 
40
40
  # reverts the config changes made by rpwn, so svn update doesn't get confused
41
41
  def revert_config_changes(app_name, instance_name)
42
- Dir.chdir RailsPwnage::Config[app_name, instance_name][:app_path] do
42
+ Dir.chdir RailsPwnerer::Config[app_name, instance_name][:app_path] do
43
43
  ['config', 'Gemfile'].each do |dir|
44
44
  Kernel.system "svn revert --recursive #{dir}"
45
45
  end
@@ -47,7 +47,7 @@ class RailsPwnage::App::Svn
47
47
  end
48
48
 
49
49
  def svn_update(app_name, instance_name)
50
- Dir.chdir RailsPwnage::Config[app_name, instance_name][:app_path] do
50
+ Dir.chdir RailsPwnerer::Config[app_name, instance_name][:app_path] do
51
51
  print "Doing SVN update, please enter your password if prompted...\n"
52
52
  success = Kernel.system 'svn update'
53
53
  unless success
@@ -60,7 +60,7 @@ class RailsPwnage::App::Svn
60
60
  end
61
61
 
62
62
  def checkout(remote_path, app_name, instance_name)
63
- app_path = RailsPwnage::Config[app_name, instance_name][:app_path]
63
+ app_path = RailsPwnerer::Config[app_name, instance_name][:app_path]
64
64
  return :next unless remote_path =~ /svn.*\:\/\// or remote_path =~ /http.*\:\/\/.*svn/
65
65
 
66
66
  print "Doing SVN checkout, please enter your password if prompted...\n"
@@ -71,7 +71,7 @@ class RailsPwnage::App::Svn
71
71
  end
72
72
 
73
73
  def update(app_name, instance_name)
74
- app_path = RailsPwnage::Config[app_name, instance_name][:app_path]
74
+ app_path = RailsPwnerer::Config[app_name, instance_name][:app_path]
75
75
  return unless File.exists?(File.join(app_path, '.svn'))
76
76
 
77
77
  # TODO: maybe backup old version before issuing the svn update?
@@ -82,7 +82,7 @@ class RailsPwnage::App::Svn
82
82
  end
83
83
 
84
84
  def update_prefetch(app_name, instance_name)
85
- app_path = RailsPwnage::Config[app_name, instance_name][:app_path]
85
+ app_path = RailsPwnerer::Config[app_name, instance_name][:app_path]
86
86
  return unless File.exists?(File.join(app_path, '.svn'))
87
87
 
88
88
  # TODO: figure out a way to prefetch using SVN (hidden local repo mirror?)
@@ -4,7 +4,7 @@ require 'digest/md5'
4
4
  require 'fileutils'
5
5
  require 'yaml'
6
6
 
7
- module RailsPwnage::Base
7
+ module RailsPwnerer::Base
8
8
  # reads the content of one file
9
9
  # returns nil if the file is corrupted, otherwise returns [file data, timestamp]
10
10
  def atomic_read_internal(file_name)
@@ -44,7 +44,7 @@ else
44
44
 
45
45
  end
46
46
 
47
- module RailsPwnage::Base
47
+ module RailsPwnerer::Base
48
48
  # returns information for each core in the system
49
49
  def cpu_cores
50
50
  cpus = []
@@ -3,7 +3,7 @@
3
3
  require 'etc'
4
4
  require 'fileutils'
5
5
 
6
- module RailsPwnage::Base
6
+ module RailsPwnerer::Base
7
7
  # gets the UID associated with the username
8
8
  def uid_for_username(name)
9
9
  passwd_entry = Etc.getpwnam(name)
@@ -1,6 +1,6 @@
1
1
  # extends Base with gem-related functions
2
2
 
3
- module RailsPwnage::Base
3
+ module RailsPwnerer::Base
4
4
  # TODO: use the Gem API instead of the command line
5
5
 
6
6
  def install_gem(gem_name)
@@ -50,7 +50,7 @@ module RailsPwnage::Base
50
50
  end
51
51
  end
52
52
 
53
- module RailsPwnage::Base
53
+ module RailsPwnerer::Base
54
54
  def install_gems(gem_names)
55
55
  unroll_collection(gem_names) { |n| install_gem(n) }
56
56
  end
@@ -3,6 +3,6 @@
3
3
  require 'digest/md5'
4
4
  require 'yaml'
5
5
 
6
- module RailsPwnage::Base
6
+ module RailsPwnerer::Base
7
7
 
8
8
  end
@@ -7,7 +7,7 @@ rescue Exception
7
7
  # no highline... tough luck
8
8
  end
9
9
 
10
- module RailsPwnage::Base
10
+ module RailsPwnerer::Base
11
11
  def prompt_user_for_password(prompt, fail_prompt)
12
12
  unless defined?(HighLine)
13
13
  print "#{fail_prompt}\n"
@@ -0,0 +1,272 @@
1
+ # extends Base with OS package-related functions
2
+
3
+ require 'English'
4
+ require 'fileutils'
5
+ require 'shellwords'
6
+
7
+ module RailsPwnerer::Base
8
+ # TODO: this works for debian-only
9
+
10
+ # Installs a package matching a pattern or list of patterns.
11
+ #
12
+ # Args:
13
+ # patterns:: same as for best_package_matching
14
+ # options:: same as for install_package
15
+ #
16
+ # Returns true for success, false if something went wrong.
17
+ def install_package_matching(patterns, options = {})
18
+ package_name = best_package_matching patterns
19
+ install_package package_name, options
20
+ end
21
+
22
+ # Installs a package.
23
+ #
24
+ # Args:
25
+ # package_name:: the exact name of the package to be installed
26
+ # options:: accepts the following:
27
+ # :source:: if true, a source package is installed and built
28
+ # :skip_proxy:: if true, apt is instructed to bypass any proxy that might
29
+ # be
30
+ #
31
+ # Returns true for success, false if something went wrong.
32
+ def install_package(package_name, options = {})
33
+ return true if install_package_impl(package_name, options)
34
+ if options[:source]
35
+ if options[:no_proxy]
36
+ install_package package_name, options.merge(:source => false)
37
+ else
38
+ install_package package_name, options.merge(:no_proxy => true)
39
+ end
40
+ else
41
+ return false unless options[:no_proxy]
42
+ install_package package_name, options.merge(:no_proxy => true)
43
+ end
44
+ end
45
+
46
+ # Removes a package.
47
+ #
48
+ # Args:
49
+ # package_name:: the exact name of the package to be installed
50
+ #
51
+ # Returns true for success, false if something went wrong.
52
+ def remove_package(package_name, options = {})
53
+ prefix, params = apt_params_for options
54
+ del_cmd = "#{prefix } apt-get remove #{params} #{package_name}"
55
+ Kernel.system(del_cmd) ? true : false
56
+ end
57
+
58
+ # Internals for install_package.
59
+ def install_package_impl(package_name, options)
60
+ prefix, params = apt_params_for options
61
+ if options[:source]
62
+ with_temp_dir(:root => true) do
63
+ dep_cmd = "#{prefix} apt-get build-dep #{params} #{package_name}"
64
+ return false unless Kernel.system(dep_cmd)
65
+ fetch_cmd = "#{prefix} apt-get source -b #{params} #{package_name}"
66
+ return false unless Kernel.system(fetch_cmd)
67
+ deb_files = Dir.glob '*.deb', File::FNM_DOTMATCH
68
+ build_cmd = "#{prefix} dpkg -i #{deb_files.join(' ')}"
69
+ return false unless Kernel.system(build_cmd)
70
+ end
71
+ else
72
+ install_cmd = "#{prefix} apt-get install #{params} #{package_name}"
73
+ return false unless Kernel.system(install_cmd)
74
+ end
75
+ return true
76
+ end
77
+
78
+ # Executes the given block in the context of having new package sources.
79
+ #
80
+ # Args:
81
+ # source_url:: the source URL, e.g. http://security.ubuntu.com/ubuntu
82
+ # repositories:: the package repositories to use, e.g. ['main', 'universe']
83
+ # options:: supports the following keys:
84
+ # :source:: if true, will use source-form packages from the new
85
+ # sources; by default, binary packages will be used
86
+ #
87
+ # Returns the block's return value.
88
+ #
89
+ # After adding the new package source, the package metadata is refreshed, so
90
+ # the block can focus on installing new packages.
91
+ #
92
+ # If the package source already exists, the given block is yielded without
93
+ # making any changes to the package configuration.
94
+ def with_package_source(source_url, source_repos = [], options = {})
95
+ source_prefix = options[:source] ? 'deb-src' : 'deb'
96
+ source_patterns = [source_prefix, source_url] + source_repos
97
+
98
+ source_contents = File.read '/etc/apt/sources.list'
99
+ sources = source_contents.split(/(\r|\n)+/)
100
+ source_exists = sources.any? do |source_line|
101
+ source_frags = source_line.split(' ')
102
+ source_patterns.all? { |pattern| source_frags.any? { |frag| frag == pattern } }
103
+ end
104
+
105
+ unless source_exists
106
+ File.open('/etc/apt/sources.list', 'a') do |f|
107
+ f.write "#{source_prefix} #{source_url} #{source_repos.join(' ')}\n"
108
+ end
109
+ update_package_metadata
110
+ end
111
+
112
+ begin
113
+ yield
114
+ ensure
115
+ unless source_exists
116
+ File.open('/etc/apt/sources.list', 'w') { |f| f.write source_contents }
117
+ update_package_metadata
118
+ end
119
+ end
120
+ end
121
+
122
+ # Updates the metadata for all the packages.
123
+ #
124
+ # Options:
125
+ # :skip_proxy:: if true, apt is instructed to bypass the proxy
126
+ #
127
+ # Returns true for success, false if something went wrong.
128
+ def update_package_metadata(options = {})
129
+ if update_package_metadata_impl(options)
130
+ # Reset the metadata cache.
131
+ RailsPwnerer::Base.instance_variable_set :@packages, nil
132
+ return true
133
+ end
134
+
135
+ return false if options[:skip_proxy]
136
+ update_package_metadata options.merge(:skip_proxy => true)
137
+ end
138
+
139
+ # Internals for update_package_metadata.
140
+ def update_package_metadata_impl(options)
141
+ prefix, params = apt_params_for options
142
+ Kernel.system("#{prefix} apt-get update #{params}") ?
143
+ true : false
144
+ end
145
+ private :update_package_metadata_impl
146
+
147
+ # Builds apt-get parameters for an option hash.
148
+ #
149
+ # Args:
150
+ # options:: an option hash, as passed to install_package, update_package,
151
+ # or update_package_metadata
152
+ #
153
+ # Returns prefix, args, where prefix is a prefix for the apt- command, and
154
+ # args is one or more command-line arguments.
155
+ def apt_params_for(options = {})
156
+ prefix = 'env DEBIAN_FRONTEND=noninteractive '
157
+ prefix += 'DEBIAN_PRIORITY=critical '
158
+ prefix += 'DEBCONF_TERSE=yes '
159
+
160
+ params = "-qq -y"
161
+ params += " -o Acquire::http::Proxy=false" if options[:skip_proxy]
162
+ return prefix, params
163
+ end
164
+ private :apt_params_for
165
+
166
+ # Package info for the best package matching a pattern or set of patterns.
167
+ #
168
+ # Args:
169
+ # patterns:: a String or Regexp, or an array of such Strings or Regexps
170
+ #
171
+ # Returns a hash with the following keys:
172
+ # :name:: the package name
173
+ # :version:: the package version
174
+ #
175
+ # Each pattern is searched for in turn. Once there are packages matching a
176
+ # pattern, the
177
+ def best_package_matching(patterns)
178
+ patterns = [patterns] unless patterns.kind_of?(Enumerable)
179
+ patterns.each do |pattern|
180
+ packages = search_packages(pattern)
181
+ next if packages.empty?
182
+ best = packages.sort_by { |key, value|
183
+ [
184
+ pattern.kind_of?(Regexp) ? ((key.index(pattern) == 0) ? 1 : 0) :
185
+ ((key == pattern) ? 1 : 0),
186
+ value.split(/[.-]/)
187
+ ]
188
+ }.last
189
+ return { :name => best.first, :version => best.last }
190
+ end
191
+ nil
192
+ end
193
+
194
+ # Searches for packages matching a name.
195
+ #
196
+ # Args:
197
+ # pattern:: a String or Regexp containing a pattern that should be matched
198
+ # by the package names
199
+ #
200
+ # Returns a hash where the keys are matching package names, and the values
201
+ # are version numbers.
202
+ def search_packages(pattern)
203
+ Hash[*(RailsPwnerer::Base.all_packages.select { |key, value|
204
+ pattern.kind_of?(Regexp) ? (pattern =~ key) : key.index(pattern)
205
+ }.flatten)]
206
+ end
207
+
208
+ # A hash of all the packages in the system, associated with their versions.
209
+ @packages = nil
210
+ def self.all_packages
211
+ @packages ||= all_packages_without_caching
212
+ end
213
+
214
+ # A hash of all the packages in the system, associated with their versions.
215
+ #
216
+ # This method is slow as hell, so it's memoized in all_packages.
217
+ def self.all_packages_without_caching
218
+ output = Kernel.` "apt-cache search --full ."
219
+ versions = output.split("\n\n").map(&:strip).reject(&:empty?).map { |info|
220
+ info_hash = Hash[*(info.split(/\n(?=\w)/).
221
+ map { |s| s.split(': ', 2) }.flatten)]
222
+ [info_hash['Package'], info_hash['Version']]
223
+ }
224
+ Hash[*(versions.flatten)]
225
+ end
226
+
227
+ # Upgrades a package to the latest version.
228
+ def upgrade_package(package_name, options = {})
229
+ return install_package(package_name, options) if options[:source]
230
+
231
+ return true if upgrade_package_impl(package_name, options)
232
+
233
+ return false if options[:no_proxy]
234
+ upgrade_package package_name, options.merge(:no_proxy => true)
235
+ end
236
+
237
+ # Internals for upgrade_package.
238
+ def upgrade_package_impl(package_name, options)
239
+ prefix, params = apt_params_for options
240
+ update_cmd = "#{prefix} apt-get upgrade #{params} #{package_name}"
241
+ Kernel.system(update_cmd) ? true : false
242
+ end
243
+
244
+ # Upgrades all the packages on the system to the latest version.
245
+ def update_all_packages(options = {})
246
+ return true if update_all_packages_impl(options)
247
+
248
+ return false if options[:no_proxy]
249
+ update_all_packages options.merge(:no_proxy => true)
250
+ end
251
+
252
+ # Internals for upgrade_all_packages.
253
+ def update_all_packages_impl(options)
254
+ prefix, params = apt_params_for options
255
+ success = Kernel.system "#{prefix} apt-get upgrade #{params}"
256
+ success ? true : false
257
+ end
258
+ end
259
+
260
+ module RailsPwnerer::Base
261
+ def install_packages(package_names, options = {})
262
+ unroll_collection(package_names) { |n| install_package(n, options) }
263
+ end
264
+
265
+ def upgrade_packages(package_names, options = {})
266
+ unroll_collection(package_names) { |n| upgrade_package(n, options) }
267
+ end
268
+
269
+ def remove_packages(package_names)
270
+ unroll_collection(package_names) { |n| remove_package(n) }
271
+ end
272
+ end
@@ -31,7 +31,7 @@ rescue Exception
31
31
  end
32
32
  end
33
33
 
34
- module RailsPwnage::Base
34
+ module RailsPwnerer::Base
35
35
  # returns information about a process
36
36
  def process_info(pid = nil)
37
37
  info = Hash.new
@@ -1,6 +1,6 @@
1
1
  # extends Base with Rails-related functions
2
2
 
3
- module RailsPwnage::Base
3
+ module RailsPwnerer::Base
4
4
  # check if the given path is the root of a Rails application
5
5
  def check_rails_root(path = '.')
6
6
  ['app', 'config', 'db', 'public', 'script', 'vendor',
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'fileutils'
4
4
 
5
- module RailsPwnage::Base
5
+ module RailsPwnerer::Base
6
6
  # TODO: make this work w/o initd (OSX, Windows)
7
7
 
8
8
  # returns the filesystem path to a boot script
@@ -1,4 +1,4 @@
1
- module RailsPwnage::Base
1
+ module RailsPwnerer::Base
2
2
  # initializes the module in UNIX mode
3
3
  def self._setup_unix
4
4
  #SUDO_PREFIX = 'sudo '
@@ -1,6 +1,6 @@
1
1
  # application-specific configuration functions
2
2
 
3
- module RailsPwnage::Config
3
+ module RailsPwnerer::Config
4
4
  # the name of the database storing an app's configuration
5
5
  def self.app_db_name(app_name, instance_name)
6
6
  return "#{app_name}.#{instance_name}"
@@ -1,6 +1,6 @@
1
1
  # computes the number of frontends to be used in an application
2
2
 
3
- module RailsPwnage::Config
3
+ module RailsPwnerer::Config
4
4
  # the number of frontends for an application
5
5
  def self.app_frontends(app_name, instance_name)
6
6
  # TODO: this is duplicated in cluster_config.rb -- pull up somewhere
@@ -0,0 +1,3 @@
1
+ module RailsPwnerer::Config
2
+
3
+ end
@@ -1,6 +1,6 @@
1
1
  # important paths in the filesystem
2
2
 
3
- module RailsPwnage::Config
3
+ module RailsPwnerer::Config
4
4
  # the path to something important (e.g. :apps --> path to all production applications)
5
5
  def self.path_to(what = :prod, app_name = nil)
6
6
  # need to hardcode path to config to avoid endless recursion
@@ -1,6 +1,6 @@
1
1
  # keeps track of the available ports on the machine
2
2
 
3
- module RailsPwnage::Config
3
+ module RailsPwnerer::Config
4
4
  def self.init_ports(free_ports = [[8000, 16000]])
5
5
  self.create_db :free_ports
6
6
  self[:free_ports][:list] = free_ports