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.
- data/CHANGELOG +2 -0
- data/LICENSE +0 -0
- data/Manifest +51 -49
- data/README +0 -0
- data/RUBYFORGE +0 -0
- data/Rakefile +7 -11
- data/ext/rpwn_setup_notice/extconf.rb +24 -16
- data/lib/{pwnage → rails_pwnerer}/app/cluster_config.rb +17 -17
- data/lib/{pwnage → rails_pwnerer}/app/config.rb +14 -14
- data/lib/{pwnage → rails_pwnerer}/app/db/mysql.rb +9 -9
- data/lib/{pwnage → rails_pwnerer}/app/files.rb +13 -13
- data/lib/{pwnage → rails_pwnerer}/app/gems.rb +3 -3
- data/lib/{pwnage → rails_pwnerer}/app/main.rb +4 -4
- data/lib/{pwnage → rails_pwnerer}/app/nginx_config.rb +7 -7
- data/lib/{pwnage → rails_pwnerer}/app/scripts.rb +4 -4
- data/lib/{pwnage → rails_pwnerer}/app/vcs/git.rb +9 -9
- data/lib/{pwnage → rails_pwnerer}/app/vcs/perforce.rb +11 -11
- data/lib/{pwnage → rails_pwnerer}/app/vcs/svn.rb +9 -9
- data/lib/{pwnage → rails_pwnerer}/base/atomics.rb +1 -1
- data/lib/{pwnage → rails_pwnerer}/base/cpus.rb +1 -1
- data/lib/{pwnage → rails_pwnerer}/base/dirs.rb +1 -1
- data/lib/{pwnage → rails_pwnerer}/base/gems.rb +2 -2
- data/lib/{pwnage → rails_pwnerer}/base/hostname.rb +1 -1
- data/lib/{pwnage → rails_pwnerer}/base/input.rb +1 -1
- data/lib/rails_pwnerer/base/packages.rb +272 -0
- data/lib/{pwnage → rails_pwnerer}/base/process.rb +1 -1
- data/lib/{pwnage → rails_pwnerer}/base/rails.rb +1 -1
- data/lib/{pwnage → rails_pwnerer}/base/startup.rb +1 -1
- data/lib/{pwnage → rails_pwnerer}/base.rb +1 -1
- data/lib/{pwnage → rails_pwnerer}/config/app.rb +1 -1
- data/lib/{pwnage → rails_pwnerer}/config/frontends.rb +1 -1
- data/lib/rails_pwnerer/config/main.rb +3 -0
- data/lib/{pwnage → rails_pwnerer}/config/paths.rb +1 -1
- data/lib/{pwnage → rails_pwnerer}/config/ports.rb +1 -1
- data/lib/{pwnage → rails_pwnerer}/config/repository.rb +7 -7
- data/lib/rails_pwnerer/ctl_executor.rb +19 -0
- data/lib/{pwnage → rails_pwnerer}/dev_executor.rb +2 -2
- data/lib/{pwnage → rails_pwnerer}/executor.rb +17 -17
- data/lib/{pwnage → rails_pwnerer}/scaffolds/config.rb +7 -7
- data/lib/{pwnage → rails_pwnerer}/scaffolds/dir_permissions.rb +4 -4
- data/lib/{pwnage → rails_pwnerer}/scaffolds/dirs.rb +3 -3
- data/lib/{pwnage → rails_pwnerer}/scaffolds/gems.rb +2 -2
- data/lib/{pwnage → rails_pwnerer}/scaffolds/hook_daemon.rb +2 -2
- data/lib/{pwnage → rails_pwnerer}/scaffolds/hook_dyndns.rb +3 -3
- data/lib/{pwnage → rails_pwnerer}/scaffolds/mysql_config.rb +2 -2
- data/lib/rails_pwnerer/scaffolds/packages.rb +118 -0
- data/lib/{pwnage → rails_pwnerer}/scaffolds/rubygems.rb +2 -2
- data/lib/{pwnage → rails_pwnerer}/scaffolds/sshd.rb +2 -2
- data/lib/{pwnage → rails_pwnerer}/util/kill_process_set.rb +1 -1
- data/lib/rails_pwnerer/util/main.rb +5 -0
- data/lib/rails_pwnerer.rb +52 -52
- data/rails_pwnerer.gemspec +17 -7
- data/test/base_package_test.rb +126 -0
- data/test/helper.rb +25 -0
- metadata +151 -107
- data/lib/pwnage/base/packages.rb +0 -159
- data/lib/pwnage/config/main.rb +0 -3
- data/lib/pwnage/ctl_executor.rb +0 -19
- data/lib/pwnage/scaffolds/packages.rb +0 -110
- 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
|
4
|
-
include
|
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 :
|
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 :
|
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
|
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
|
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 =
|
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 =
|
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 =
|
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
|
9
|
-
include
|
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 :
|
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 :
|
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
|
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 =
|
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
|
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 =
|
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 =
|
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 =
|
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
|
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
|
9
|
-
include
|
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 :
|
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 :
|
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
|
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
|
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 =
|
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 =
|
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 =
|
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
|
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)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# extends Base with gem-related functions
|
2
2
|
|
3
|
-
module
|
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
|
53
|
+
module RailsPwnerer::Base
|
54
54
|
def install_gems(gem_names)
|
55
55
|
unroll_collection(gem_names) { |n| install_gem(n) }
|
56
56
|
end
|
@@ -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
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# computes the number of frontends to be used in an application
|
2
2
|
|
3
|
-
module
|
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
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# important paths in the filesystem
|
2
2
|
|
3
|
-
module
|
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
|