automate-it 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +19 -0
- data/.hgignore +10 -0
- data/.loadpath +5 -0
- data/.project +17 -0
- data/CHANGES.txt +314 -0
- data/Hoe.rake +40 -0
- data/Manifest.txt +164 -0
- data/README.txt +40 -0
- data/Rakefile +256 -0
- data/TESTING.txt +57 -0
- data/TODO.txt +50 -0
- data/TUTORIAL.txt +391 -0
- data/automate-it.gemspec +25 -0
- data/bin/ai +3 -0
- data/bin/aifield +75 -0
- data/bin/aissh +93 -0
- data/bin/aitag +134 -0
- data/bin/automateit +133 -0
- data/docs/friendly_errors.txt +50 -0
- data/docs/previews.txt +86 -0
- data/examples/basic/Rakefile +26 -0
- data/examples/basic/config/automateit_env.rb +16 -0
- data/examples/basic/config/fields.yml +3 -0
- data/examples/basic/config/tags.yml +7 -0
- data/examples/basic/dist/README.txt +9 -0
- data/examples/basic/dist/myapp_server.erb +30 -0
- data/examples/basic/install.log +15 -0
- data/examples/basic/lib/README.txt +10 -0
- data/examples/basic/recipes/README.txt +4 -0
- data/examples/basic/recipes/install.rb +61 -0
- data/examples/basic/recipes/uninstall.rb +6 -0
- data/gpl.txt +674 -0
- data/helpers/cpan_wrapper.pl +220 -0
- data/helpers/which.cmd +7 -0
- data/lib/automateit.rb +55 -0
- data/lib/automateit/account_manager.rb +114 -0
- data/lib/automateit/account_manager/base.rb +138 -0
- data/lib/automateit/account_manager/etc.rb +128 -0
- data/lib/automateit/account_manager/nscd.rb +33 -0
- data/lib/automateit/account_manager/passwd_expect.rb +40 -0
- data/lib/automateit/account_manager/passwd_pty.rb +69 -0
- data/lib/automateit/account_manager/posix.rb +138 -0
- data/lib/automateit/address_manager.rb +88 -0
- data/lib/automateit/address_manager/base.rb +171 -0
- data/lib/automateit/address_manager/bsd.rb +28 -0
- data/lib/automateit/address_manager/freebsd.rb +59 -0
- data/lib/automateit/address_manager/linux.rb +42 -0
- data/lib/automateit/address_manager/openbsd.rb +66 -0
- data/lib/automateit/address_manager/portable.rb +37 -0
- data/lib/automateit/address_manager/sunos.rb +34 -0
- data/lib/automateit/cli.rb +85 -0
- data/lib/automateit/common.rb +65 -0
- data/lib/automateit/constants.rb +35 -0
- data/lib/automateit/download_manager.rb +48 -0
- data/lib/automateit/edit_manager.rb +321 -0
- data/lib/automateit/error.rb +10 -0
- data/lib/automateit/field_manager.rb +103 -0
- data/lib/automateit/interpreter.rb +631 -0
- data/lib/automateit/package_manager.rb +257 -0
- data/lib/automateit/package_manager/apt.rb +27 -0
- data/lib/automateit/package_manager/cpan.rb +101 -0
- data/lib/automateit/package_manager/dpkg.rb +54 -0
- data/lib/automateit/package_manager/egg.rb +64 -0
- data/lib/automateit/package_manager/gem.rb +201 -0
- data/lib/automateit/package_manager/pear.rb +95 -0
- data/lib/automateit/package_manager/pecl.rb +80 -0
- data/lib/automateit/package_manager/portage.rb +69 -0
- data/lib/automateit/package_manager/yum.rb +65 -0
- data/lib/automateit/platform_manager.rb +49 -0
- data/lib/automateit/platform_manager/darwin.rb +30 -0
- data/lib/automateit/platform_manager/debian.rb +26 -0
- data/lib/automateit/platform_manager/freebsd.rb +29 -0
- data/lib/automateit/platform_manager/gentoo.rb +26 -0
- data/lib/automateit/platform_manager/lsb.rb +44 -0
- data/lib/automateit/platform_manager/openbsd.rb +28 -0
- data/lib/automateit/platform_manager/struct.rb +80 -0
- data/lib/automateit/platform_manager/sunos.rb +39 -0
- data/lib/automateit/platform_manager/uname.rb +29 -0
- data/lib/automateit/platform_manager/windows.rb +40 -0
- data/lib/automateit/plugin.rb +7 -0
- data/lib/automateit/plugin/base.rb +32 -0
- data/lib/automateit/plugin/driver.rb +256 -0
- data/lib/automateit/plugin/manager.rb +224 -0
- data/lib/automateit/project.rb +493 -0
- data/lib/automateit/root.rb +17 -0
- data/lib/automateit/service_manager.rb +93 -0
- data/lib/automateit/service_manager/chkconfig.rb +39 -0
- data/lib/automateit/service_manager/rc_update.rb +37 -0
- data/lib/automateit/service_manager/sysv.rb +139 -0
- data/lib/automateit/service_manager/update_rcd.rb +35 -0
- data/lib/automateit/shell_manager.rb +316 -0
- data/lib/automateit/shell_manager/base_link.rb +67 -0
- data/lib/automateit/shell_manager/link.rb +24 -0
- data/lib/automateit/shell_manager/portable.rb +523 -0
- data/lib/automateit/shell_manager/symlink.rb +32 -0
- data/lib/automateit/shell_manager/which_base.rb +30 -0
- data/lib/automateit/shell_manager/which_unix.rb +16 -0
- data/lib/automateit/shell_manager/which_windows.rb +20 -0
- data/lib/automateit/tag_manager.rb +127 -0
- data/lib/automateit/tag_manager/struct.rb +121 -0
- data/lib/automateit/tag_manager/tag_parser.rb +93 -0
- data/lib/automateit/tag_manager/yaml.rb +29 -0
- data/lib/automateit/template_manager.rb +56 -0
- data/lib/automateit/template_manager/base.rb +181 -0
- data/lib/automateit/template_manager/erb.rb +17 -0
- data/lib/ext/metaclass.rb +17 -0
- data/lib/ext/object.rb +18 -0
- data/lib/ext/shell_escape.rb +7 -0
- data/lib/hashcache.rb +22 -0
- data/lib/helpful_erb.rb +63 -0
- data/lib/inactive_support.rb +53 -0
- data/lib/inactive_support/basic_object.rb +6 -0
- data/lib/inactive_support/clean_logger.rb +127 -0
- data/lib/inactive_support/core_ext/array/extract_options.rb +19 -0
- data/lib/inactive_support/core_ext/blank.rb +50 -0
- data/lib/inactive_support/core_ext/class/attribute_accessors.rb +48 -0
- data/lib/inactive_support/core_ext/class/inheritable_attributes.rb +140 -0
- data/lib/inactive_support/core_ext/enumerable.rb +63 -0
- data/lib/inactive_support/core_ext/hash/keys.rb +54 -0
- data/lib/inactive_support/core_ext/module/aliasing.rb +70 -0
- data/lib/inactive_support/core_ext/numeric/time.rb +91 -0
- data/lib/inactive_support/core_ext/string/inflections.rb +153 -0
- data/lib/inactive_support/core_ext/symbol.rb +14 -0
- data/lib/inactive_support/core_ext/time/conversions.rb +96 -0
- data/lib/inactive_support/duration.rb +96 -0
- data/lib/inactive_support/inflections.rb +53 -0
- data/lib/inactive_support/inflector.rb +282 -0
- data/lib/nested_error.rb +33 -0
- data/lib/nitpick.rb +33 -0
- data/lib/queued_logger.rb +68 -0
- data/lib/tempster.rb +250 -0
- data/misc/index_gem_repository.rb +304 -0
- data/misc/setup_egg.rb +12 -0
- data/misc/setup_gem_dependencies.sh +6 -0
- data/misc/setup_rubygems.sh +21 -0
- metadata +279 -0
@@ -0,0 +1,257 @@
|
|
1
|
+
# == PackageManager
|
2
|
+
#
|
3
|
+
# The PackageManager provides a way to manage packages, e.g., install,
|
4
|
+
# uninstall and query if the Apache package is installed with APT.
|
5
|
+
#
|
6
|
+
# Examples:
|
7
|
+
#
|
8
|
+
# package_manager.installed?("apache2") # => false
|
9
|
+
# package_manager.install("apache2") # => true
|
10
|
+
# package_manager.installed?("apache2") # => true
|
11
|
+
# package_manager.uninstall("apache2") # => true
|
12
|
+
# package_manager.not_installed("apache2") # => true
|
13
|
+
#
|
14
|
+
# Commands can accept arrays:
|
15
|
+
#
|
16
|
+
# package_manager.install("apache2", "bash")
|
17
|
+
# package_manager.installed? %w(apache2 bash)
|
18
|
+
#
|
19
|
+
# Commands can also accept a single, annotated string as a manifest -- useful
|
20
|
+
# for installing large numbers of packages at once:
|
21
|
+
#
|
22
|
+
# package_manager.install <<HERE, :with => :apt
|
23
|
+
# # One per line
|
24
|
+
# apache
|
25
|
+
# bash
|
26
|
+
#
|
27
|
+
# # Or many on the same line
|
28
|
+
# sysvconfig sysv-rc-conf
|
29
|
+
# HERE
|
30
|
+
#
|
31
|
+
# Commands can also accept a hash of names to paths -- necessary for installing
|
32
|
+
# packages stored on the filesystem:
|
33
|
+
#
|
34
|
+
# # Is the package called "TracTags" installed? If not, run the installer
|
35
|
+
# # with the "/tmp/tractags_latest" path as an argument:
|
36
|
+
# package.manager.install({"TracTags" => "/tmp/tractags_latest"}, :with => :egg)
|
37
|
+
class AutomateIt::PackageManager < AutomateIt::Plugin::Manager
|
38
|
+
# Alias for #install
|
39
|
+
def add(*packages) dispatch_to(:install, *packages) end
|
40
|
+
|
41
|
+
# Alias for #uninstall
|
42
|
+
def remove(*packages) dispatch_to(:uninstall, *packages) end
|
43
|
+
|
44
|
+
# Are these +packages+ installed?
|
45
|
+
#
|
46
|
+
# Options:
|
47
|
+
# * :details -- Returns an array containing the boolean result value and an
|
48
|
+
# array with a subset of installed +packages+. Boolean, defaults to false.
|
49
|
+
def installed?(*packages) dispatch(*packages) end
|
50
|
+
|
51
|
+
# Are these +packages+ not installed?
|
52
|
+
#
|
53
|
+
# Options:
|
54
|
+
# * :details -- Returns an array containing the boolean result value and an
|
55
|
+
# array with a subset of +packages+ not installed. Boolean, defaults to false.
|
56
|
+
def not_installed?(*packages) dispatch(*packages) end
|
57
|
+
|
58
|
+
# Install these +packages+. Returns +true+ if any packages are installed
|
59
|
+
# successfully; or +false+ if all packages were already installed.
|
60
|
+
def install(*packages) dispatch(*packages) end
|
61
|
+
|
62
|
+
# Uninstall these +packages+. Returns +true+ if any packages are uninstalled
|
63
|
+
# successfully; or +false+ if none of the packages are installed.
|
64
|
+
def uninstall(*packages) dispatch(*packages) end
|
65
|
+
end
|
66
|
+
|
67
|
+
# == PackageManager::BaseDriver
|
68
|
+
#
|
69
|
+
# Base class for all PackageManager drivers.
|
70
|
+
class AutomateIt::PackageManager::BaseDriver < AutomateIt::Plugin::Driver
|
71
|
+
protected
|
72
|
+
|
73
|
+
# Are these +packages+ installed? Works like PackageManager#installed?
|
74
|
+
# but calls a block that actually checks whether the packages are
|
75
|
+
# installed and returns an array of packages installed.
|
76
|
+
#
|
77
|
+
# For example:
|
78
|
+
# _installed_helper?("package1", "package2", :details => true) do |packages, opts|
|
79
|
+
# # Dummy code which reports that these packages are installed:
|
80
|
+
# ["package1]
|
81
|
+
# end
|
82
|
+
def _installed_helper?(*packages, &block) # :yields: filtered_packages, opts
|
83
|
+
_raise_unless_available
|
84
|
+
|
85
|
+
packages, opts = args_and_opts(*packages)
|
86
|
+
packages = _list_normalizer(packages)
|
87
|
+
packages = packages.keys if Hash === packages
|
88
|
+
|
89
|
+
available = block.call(packages, opts)
|
90
|
+
truth = (packages - available).empty?
|
91
|
+
result = opts[:details] ? [truth, available] : truth
|
92
|
+
log.debug(PNOTE+"installed?(#{packages.inspect}) => #{truth}: #{available.inspect}")
|
93
|
+
return result
|
94
|
+
end
|
95
|
+
|
96
|
+
# Are these +packages+ not installed?
|
97
|
+
def _not_installed_helper?(*packages)
|
98
|
+
_raise_unless_available
|
99
|
+
|
100
|
+
# Requires that your PackageManager#installed? method is implemented.
|
101
|
+
packages, opts = args_and_opts(*packages)
|
102
|
+
packages = _list_normalizer(packages)
|
103
|
+
packages = packages.keys if Hash === packages
|
104
|
+
|
105
|
+
available = [installed?(packages, :details => true)].flatten
|
106
|
+
missing = packages - available
|
107
|
+
truth = (packages - missing).empty?
|
108
|
+
result = opts[:details] ? [truth, missing] : truth
|
109
|
+
log.debug(PNOTE+"not_installed?(#{packages.inspect}) => #{truth}: #{missing.inspect}")
|
110
|
+
return result
|
111
|
+
end
|
112
|
+
|
113
|
+
# Install these +packages+. Works like PackageManager#install but calls a
|
114
|
+
# block that's responsible for actually installing the packages and
|
115
|
+
# returning true if the installation succeeded. This block is only called
|
116
|
+
# if packages need to be installed and receives a filtered list of
|
117
|
+
# packages that are guaranteed not to be installed on the system already.
|
118
|
+
#
|
119
|
+
# For example:
|
120
|
+
# _install_helper("package1", "package2", :quiet => true) do |packages, opts|
|
121
|
+
# # Dummy code that installs packages here, e.g:
|
122
|
+
# system("apt-get", "install", "-y", packages)
|
123
|
+
# end
|
124
|
+
def _install_helper(*packages, &block) # :yields: filtered_packages, opts
|
125
|
+
_raise_unless_available
|
126
|
+
|
127
|
+
packages, opts = args_and_opts(*packages)
|
128
|
+
packages = _list_normalizer(packages)
|
129
|
+
|
130
|
+
check_packages = \
|
131
|
+
case packages
|
132
|
+
when Hash
|
133
|
+
packages.keys
|
134
|
+
else
|
135
|
+
packages
|
136
|
+
end
|
137
|
+
|
138
|
+
missing = not_installed?(check_packages, :details => true)[1]
|
139
|
+
return false if missing.blank?
|
140
|
+
|
141
|
+
install_packages = \
|
142
|
+
case packages
|
143
|
+
when Hash
|
144
|
+
missing.map{|t| packages[t]}
|
145
|
+
else
|
146
|
+
missing
|
147
|
+
end
|
148
|
+
block.call(install_packages, opts)
|
149
|
+
|
150
|
+
return true if preview?
|
151
|
+
unless (failed = not_installed?(check_packages, :details => true)[1]).empty?
|
152
|
+
raise ArgumentError.new("Couldn't install: #{failed.join(' ')}")
|
153
|
+
else
|
154
|
+
return true
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
# Uninstall these +packages+. Works like PackageManager#uninstall but calls a
|
159
|
+
# block that's responsible for actually uninstalling the packages and
|
160
|
+
# returning true if the uninstall succeeded. This block is only called
|
161
|
+
# if packages need to be uninstalled and receives a filtered list of
|
162
|
+
# packages that are guaranteed to be installed on the system.
|
163
|
+
#
|
164
|
+
# For example:
|
165
|
+
# _uninstall_helper("package1", "package2", :quiet => true) do |packages, opts|
|
166
|
+
# # Dummy code that removes packages here, e.g:
|
167
|
+
# system("apt-get", "remove", "-y", packages)
|
168
|
+
# end
|
169
|
+
def _uninstall_helper(*packages, &block) # :yields: filtered_packages, opts
|
170
|
+
_raise_unless_available
|
171
|
+
|
172
|
+
packages, opts = args_and_opts(*packages)
|
173
|
+
packages = _list_normalizer(packages)
|
174
|
+
|
175
|
+
check_packages = \
|
176
|
+
case packages
|
177
|
+
when Hash
|
178
|
+
packages.keys
|
179
|
+
else
|
180
|
+
packages
|
181
|
+
end
|
182
|
+
|
183
|
+
present = installed?(check_packages, :details => true)[1]
|
184
|
+
return false if present.blank?
|
185
|
+
|
186
|
+
uninstall_packages = \
|
187
|
+
case packages
|
188
|
+
when Hash
|
189
|
+
present.map{|t| packages[t]}
|
190
|
+
else
|
191
|
+
present
|
192
|
+
end
|
193
|
+
block.call(uninstall_packages, opts)
|
194
|
+
|
195
|
+
return true if preview?
|
196
|
+
unless (failed = installed?(check_packages, :details => true)[1]).empty?
|
197
|
+
raise ArgumentError.new("Couldn't uninstall: #{failed.join(' ')}")
|
198
|
+
else
|
199
|
+
return true
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
# Returns a normalized array of packages. Transforms manifest string into
|
204
|
+
# packages. Turns symbols into string, strips blank lines and comments.
|
205
|
+
def _list_normalizer(*packages)
|
206
|
+
packages = [packages].flatten
|
207
|
+
if packages.size == 1
|
208
|
+
packages = packages.first
|
209
|
+
nitpick "LN SI %s" % packages.inspect
|
210
|
+
nitpick "LN Sc %s" % packages.class
|
211
|
+
case packages
|
212
|
+
when Symbol
|
213
|
+
nitpick "LN Sy"
|
214
|
+
packages = [packages.to_s]
|
215
|
+
when String
|
216
|
+
nitpick "LN Ss"
|
217
|
+
packages = _string_to_packages(packages)
|
218
|
+
when Hash
|
219
|
+
# Don't do anything
|
220
|
+
nitpick "LN Sh"
|
221
|
+
else
|
222
|
+
nitpick "LN S?"
|
223
|
+
raise TypeError.new("Unknown input type: #{packages.class}")
|
224
|
+
end
|
225
|
+
nitpick "LN SO %s" % packages.inspect
|
226
|
+
end
|
227
|
+
|
228
|
+
case packages
|
229
|
+
when Array
|
230
|
+
result = packages.map(&:to_s).map{|t| _string_to_packages(t)}.flatten.uniq
|
231
|
+
when Hash
|
232
|
+
result = packages.stringify_keys
|
233
|
+
when Symbol, String
|
234
|
+
result = packages.to_s
|
235
|
+
else
|
236
|
+
raise TypeError.new("Unknown input type: #{packages.class}")
|
237
|
+
end
|
238
|
+
|
239
|
+
nitpick "LN RR %s" % result.inspect
|
240
|
+
return result
|
241
|
+
end
|
242
|
+
|
243
|
+
def _string_to_packages(string)
|
244
|
+
string.scan(/^\s*([^#]+)\s*/).flatten.map{|t| t.split}.flatten.uniq
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
# Drivers
|
249
|
+
require 'automateit/package_manager/dpkg'
|
250
|
+
require 'automateit/package_manager/apt'
|
251
|
+
require 'automateit/package_manager/yum'
|
252
|
+
require 'automateit/package_manager/gem'
|
253
|
+
require 'automateit/package_manager/egg'
|
254
|
+
require 'automateit/package_manager/portage'
|
255
|
+
require 'automateit/package_manager/pear'
|
256
|
+
require 'automateit/package_manager/pecl'
|
257
|
+
require 'automateit/package_manager/cpan'
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# == PackageManager::APT
|
2
|
+
#
|
3
|
+
# The APT driver for the PackageManager provides a way to manage software
|
4
|
+
# packages on Debian-style systems using <tt>apt-get</tt> and <tt>dpkg</tt>.
|
5
|
+
class AutomateIt::PackageManager::APT < AutomateIt::PackageManager::DPKG
|
6
|
+
depends_on :programs => %w(apt-get dpkg)
|
7
|
+
|
8
|
+
def suitability(method, *args) # :nodoc:
|
9
|
+
return available? ? 1 : 0
|
10
|
+
end
|
11
|
+
|
12
|
+
# See AutomateIt::PackageManager#install
|
13
|
+
def install(*packages)
|
14
|
+
return _install_helper(*packages) do |list, opts|
|
15
|
+
# apt-get options:
|
16
|
+
# -y : yes to all queries
|
17
|
+
# -q : no interactive progress bars
|
18
|
+
cmd = "export DEBIAN_FRONTEND=noninteractive; apt-get"
|
19
|
+
cmd << " -t #{opts[:backports]}" if opts[:backports]
|
20
|
+
cmd << " install -y -q "+list.join(" ")+" < /dev/null"
|
21
|
+
cmd << " > /dev/null" if opts[:quiet]
|
22
|
+
cmd << " 2>&1"
|
23
|
+
|
24
|
+
interpreter.sh(cmd)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
# == PackageManager::CPAN
|
2
|
+
#
|
3
|
+
# A PackageManager driver for Perl CPAN (Comprehensive Perl Archive Network)
|
4
|
+
# software packages.
|
5
|
+
#
|
6
|
+
# === No automatic dependency installation
|
7
|
+
#
|
8
|
+
# Unlike other AutomateIt PackageManager drivers, the CPAN driver will not install a package's dependencies automatically. This protects you because many CPAN packages require a specific version of Perl, often one which you don't have installed, and installing that dependency will destroy your Perl interpreter and everything that depends on it. Therefore, you must specify all package dependencies manually. If a package dependency isn't found, the install will fail.
|
9
|
+
#
|
10
|
+
# === Specifying Perl interpreter
|
11
|
+
#
|
12
|
+
# Use #setup to specify the Perl interpreter to use for all subsequent calls.
|
13
|
+
#
|
14
|
+
# Example:
|
15
|
+
#
|
16
|
+
# package_manager[:cpan].setup(:perl => "/usr/local/bin/perl")
|
17
|
+
# package_manager.install %w(File::Next App::Ack), :with => :cpan
|
18
|
+
class ::AutomateIt::PackageManager::CPAN < ::AutomateIt::PackageManager::BaseDriver
|
19
|
+
CPAN_WRAPPER = File.join(::AutomateIt::Constants::HELPERS_DIR, "cpan_wrapper.pl")
|
20
|
+
|
21
|
+
# Path to Perl interpreter
|
22
|
+
attr_accessor :perl
|
23
|
+
|
24
|
+
# FIXME How to get #depends_on to use same Perl interpreter as #perl? The trouble is that Plugin::Driver#available? checks a class variable populated by #depends_on, so it can't see the instance's #perl variable that's been set by the user. A general solution would address this problem for all drivers that use commands with different names, e.g. "gem1.8", "python2.5.1", etc.
|
25
|
+
depends_on :programs => %w(perl)
|
26
|
+
|
27
|
+
# Setup the PackageManager::CPAN driver.
|
28
|
+
#
|
29
|
+
# Options:
|
30
|
+
# * :perl -- The absolute, relative or unqualified path for the Perl interpreter to use. E.g., "perl" or "/usr/local/bin/perl".
|
31
|
+
def setup(*args)
|
32
|
+
super(*args)
|
33
|
+
|
34
|
+
args, opts = args_and_opts(*args)
|
35
|
+
if opts[:perl]
|
36
|
+
self.perl = opts[:perl]
|
37
|
+
else
|
38
|
+
self.perl ||= "perl"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def suitability(method, *args) # :nodoc:
|
43
|
+
# Never select as default driver
|
44
|
+
return 0
|
45
|
+
end
|
46
|
+
|
47
|
+
# Options:
|
48
|
+
# * :perl -- Command to use as the Perl interpreter, otherwise defaults to the one specified during #setup or to "perl"
|
49
|
+
#
|
50
|
+
# See AutomateIt::PackageManager#installed?
|
51
|
+
def installed?(*packages)
|
52
|
+
return _installed_helper?(*packages) do |list, opts|
|
53
|
+
perl = opts[:perl] || self.perl
|
54
|
+
cmd = "#{perl} #{CPAN_WRAPPER} --query #{list.join(' ')}"
|
55
|
+
|
56
|
+
# FIXME if CPAN isn't configured, this will hang because Perl will demand input
|
57
|
+
log.debug(PEXEC+cmd)
|
58
|
+
output = `#{cmd}`
|
59
|
+
output.sub!(/.*---(\s[^\n]+)?\n/m, '')
|
60
|
+
struct = ::YAML.load(output)
|
61
|
+
|
62
|
+
struct["available"] || []
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
# See AutomateIt::PackageManager#not_installed?
|
67
|
+
def not_installed?(*packages)
|
68
|
+
# TODO Move #not_installed? up to BaseDriver
|
69
|
+
return _not_installed_helper?(*packages)
|
70
|
+
end
|
71
|
+
|
72
|
+
# Options:
|
73
|
+
# * :perl -- Command to use as the Perl interpreter, otherwise defaults to the one specified during #setup or to "perl"
|
74
|
+
#
|
75
|
+
# See AutomateIt::PackageManager#install
|
76
|
+
def install(*packages)
|
77
|
+
return _install_helper(*packages) do |list, opts|
|
78
|
+
perl = opts[:perl] || self.perl
|
79
|
+
cmd = "#{perl} #{CPAN_WRAPPER} --install #{list.join(' ')}"
|
80
|
+
cmd << " > /dev/null" if opts[:quiet]
|
81
|
+
cmd << " 2>&1"
|
82
|
+
|
83
|
+
interpreter.sh(cmd)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
# Options:
|
88
|
+
# * :perl -- Command to use as the Perl interpreter, otherwise defaults to the one specified during #setup or to "perl"
|
89
|
+
#
|
90
|
+
# See AutomateIt::PackageManager#uninstall
|
91
|
+
def uninstall(*packages)
|
92
|
+
return _uninstall_helper(*packages) do |list, opts|
|
93
|
+
perl = opts[:perl] || self.perl
|
94
|
+
cmd = "#{perl} #{CPAN_WRAPPER} --uninstall #{list.join(' ')} < /dev/null"
|
95
|
+
cmd << " > /dev/null" if opts[:quiet]
|
96
|
+
cmd << " 2>&1"
|
97
|
+
|
98
|
+
interpreter.sh(cmd)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# == PackageManager::DPKG
|
2
|
+
#
|
3
|
+
# The DPKG driver for the PackageManager provides a way to manage software
|
4
|
+
# packages on Debian-style systems using <tt>dpkg</tt>.
|
5
|
+
class AutomateIt::PackageManager::DPKG < AutomateIt::PackageManager::BaseDriver
|
6
|
+
depends_on :programs => %w(dpkg)
|
7
|
+
|
8
|
+
# See AutomateIt::PackageManager#installed?
|
9
|
+
def installed?(*packages)
|
10
|
+
return _installed_helper?(*packages) do |list, opts|
|
11
|
+
### data = `dpkg --status nomarch apache2 not_a_real_package 2>&1`
|
12
|
+
cmd = "dpkg --status "+list.join(" ")+" 2>&1"
|
13
|
+
|
14
|
+
log.debug(PEXEC+cmd)
|
15
|
+
data = `#{cmd}`
|
16
|
+
matches = data.scan(/^Package: (.+)$\s*^Status: (.+)$/)
|
17
|
+
available = matches.inject([]) do |sum, match|
|
18
|
+
package, status = match
|
19
|
+
sum << package if status.match(/(?:^|\s)installed\b/)
|
20
|
+
sum
|
21
|
+
end
|
22
|
+
|
23
|
+
available
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# See AutomateIt::PackageManager#not_installed?
|
28
|
+
def not_installed?(*packages)
|
29
|
+
return _not_installed_helper?(*packages)
|
30
|
+
end
|
31
|
+
|
32
|
+
# See AutomateIt::PackageManager#install
|
33
|
+
def install(*packages)
|
34
|
+
return _install_helper(*packages) do |list, opts|
|
35
|
+
cmd = "export DEBIAN_FRONTEND=noninteractive; dpkg --install --skip-same-version "+list.join(" ")+" < /dev/null"
|
36
|
+
cmd << " > /dev/null" if opts[:quiet]
|
37
|
+
cmd << " 2>&1"
|
38
|
+
|
39
|
+
interpreter.sh(cmd)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# See AutomateIt::PackageManager#uninstall
|
44
|
+
def uninstall(*packages)
|
45
|
+
return _uninstall_helper(*packages) do |list, opts|
|
46
|
+
cmd = "export DEBIAN_FRONTEND=noninteractive; dpkg --remove "+list.join(" ")+" < /dev/null"
|
47
|
+
cmd << " > /dev/null" if opts[:quiet]
|
48
|
+
cmd << " 2>&1"
|
49
|
+
|
50
|
+
interpreter.sh(cmd)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# == PackageManager::Egg
|
2
|
+
#
|
3
|
+
# The Egg driver for the PackageManager provides a way to manage
|
4
|
+
# Python software packages with the PEAK +easy_install+ tool.
|
5
|
+
class AutomateIt::PackageManager::Egg < AutomateIt::PackageManager::BaseDriver
|
6
|
+
depends_on :programs => %w(python easy_install)
|
7
|
+
|
8
|
+
def suitability(method, *args) # :nodoc:
|
9
|
+
# Never select as default driver
|
10
|
+
return 0
|
11
|
+
end
|
12
|
+
|
13
|
+
# See AutomateIt::PackageManager#installed?
|
14
|
+
def installed?(*packages)
|
15
|
+
return _installed_helper?(*packages) do |list, opts|
|
16
|
+
cmd = "python -c 'import sys; print(sys.path)' 2>&1"
|
17
|
+
|
18
|
+
log.debug(PEXEC+cmd)
|
19
|
+
data = `#{cmd}`
|
20
|
+
# Extract array elements, turn them into basenames, and then split on
|
21
|
+
# '-' because that's the separator for the name and version.
|
22
|
+
found = data.scan(/'([^']+\.egg)'/).flatten.map{|t| File.basename(t).split('-', 2)[0]}
|
23
|
+
available = found & list
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# See AutomateIt::PackageManager#not_installed?
|
28
|
+
def not_installed?(*packages)
|
29
|
+
return _not_installed_helper?(*packages)
|
30
|
+
end
|
31
|
+
|
32
|
+
# See AutomateIt::PackageManager#install
|
33
|
+
def install(*packages)
|
34
|
+
return _install_helper(*packages) do |list, opts|
|
35
|
+
# easy_install options:
|
36
|
+
# -Z : install into a direcory rather than a file
|
37
|
+
cmd = "easy_install -Z "+list.join(" ")+" < /dev/null"
|
38
|
+
cmd << " > /dev/null" if opts[:quiet]
|
39
|
+
cmd << " 2>&1"
|
40
|
+
|
41
|
+
interpreter.sh(cmd)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# See AutomateIt::PackageManager#uninstall
|
46
|
+
def uninstall(*packages)
|
47
|
+
return _uninstall_helper(*packages) do |list, opts|
|
48
|
+
# easy_install options:
|
49
|
+
# -m : removes package from the easy-install.pth
|
50
|
+
cmd = "easy_install -m "+list.join(" ")+" < /dev/null"
|
51
|
+
cmd << " > /dev/null" if opts[:quiet]
|
52
|
+
cmd << " 2>&1"
|
53
|
+
|
54
|
+
# Parse output for paths and remove the orphaned entries
|
55
|
+
log.info(PEXEC+cmd)
|
56
|
+
return packages if preview?
|
57
|
+
data = `#{cmd}`
|
58
|
+
paths = data.scan(/^Using ([^\n]+\.egg)$/m).flatten
|
59
|
+
for path in paths
|
60
|
+
interpreter.rm_rf(path)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|