automateit 0.70923
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.tar.gz.sig +1 -0
- data/CHANGES.txt +100 -0
- data/Hoe.rake +35 -0
- data/Manifest.txt +111 -0
- data/README.txt +44 -0
- data/Rakefile +284 -0
- data/TESTING.txt +57 -0
- data/TODO.txt +26 -0
- data/TUTORIAL.txt +390 -0
- data/bin/ai +3 -0
- data/bin/aifield +82 -0
- data/bin/aitag +128 -0
- data/bin/automateit +117 -0
- data/docs/friendly_errors.txt +50 -0
- data/docs/previews.txt +86 -0
- data/env.sh +4 -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 +13 -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 +53 -0
- data/examples/basic/recipes/uninstall.rb +6 -0
- data/gpl.txt +674 -0
- data/lib/automateit.rb +66 -0
- data/lib/automateit/account_manager.rb +106 -0
- data/lib/automateit/account_manager/linux.rb +171 -0
- data/lib/automateit/account_manager/passwd.rb +69 -0
- data/lib/automateit/account_manager/portable.rb +136 -0
- data/lib/automateit/address_manager.rb +165 -0
- data/lib/automateit/address_manager/linux.rb +80 -0
- data/lib/automateit/address_manager/portable.rb +37 -0
- data/lib/automateit/cli.rb +80 -0
- data/lib/automateit/common.rb +65 -0
- data/lib/automateit/constants.rb +33 -0
- data/lib/automateit/edit_manager.rb +292 -0
- data/lib/automateit/error.rb +10 -0
- data/lib/automateit/field_manager.rb +103 -0
- data/lib/automateit/interpreter.rb +641 -0
- data/lib/automateit/package_manager.rb +242 -0
- data/lib/automateit/package_manager/apt.rb +63 -0
- data/lib/automateit/package_manager/egg.rb +64 -0
- data/lib/automateit/package_manager/gem.rb +179 -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 +47 -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 +25 -0
- data/lib/automateit/platform_manager/gentoo.rb +26 -0
- data/lib/automateit/platform_manager/lsb.rb +40 -0
- data/lib/automateit/platform_manager/struct.rb +78 -0
- data/lib/automateit/platform_manager/uname.rb +29 -0
- data/lib/automateit/platform_manager/windows.rb +33 -0
- data/lib/automateit/plugin.rb +7 -0
- data/lib/automateit/plugin/base.rb +32 -0
- data/lib/automateit/plugin/driver.rb +218 -0
- data/lib/automateit/plugin/manager.rb +232 -0
- data/lib/automateit/project.rb +460 -0
- data/lib/automateit/root.rb +14 -0
- data/lib/automateit/service_manager.rb +79 -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 +126 -0
- data/lib/automateit/service_manager/update_rcd.rb +35 -0
- data/lib/automateit/shell_manager.rb +261 -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 +421 -0
- data/lib/automateit/shell_manager/symlink.rb +32 -0
- data/lib/automateit/shell_manager/which.rb +25 -0
- data/lib/automateit/tag_manager.rb +63 -0
- data/lib/automateit/tag_manager/struct.rb +101 -0
- data/lib/automateit/tag_manager/tag_parser.rb +91 -0
- data/lib/automateit/tag_manager/yaml.rb +29 -0
- data/lib/automateit/template_manager.rb +55 -0
- data/lib/automateit/template_manager/base.rb +172 -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/hashcache.rb +22 -0
- data/lib/helpful_erb.rb +63 -0
- data/lib/nested_error.rb +33 -0
- data/lib/queued_logger.rb +68 -0
- data/lib/tempster.rb +239 -0
- data/misc/index_gem_repository.rb +303 -0
- data/misc/setup_egg.rb +12 -0
- data/misc/setup_gem_dependencies.sh +7 -0
- data/misc/setup_rubygems.sh +21 -0
- data/misc/which.cmd +6 -0
- data/spec/extras/automateit_service_sysv_test +50 -0
- data/spec/extras/scratch.rb +15 -0
- data/spec/extras/simple_recipe.rb +8 -0
- data/spec/integration/account_manager_spec.rb +218 -0
- data/spec/integration/address_manager_linux_spec.rb +119 -0
- data/spec/integration/address_manager_portable_spec.rb +30 -0
- data/spec/integration/cli_spec.rb +215 -0
- data/spec/integration/examples_spec.rb +54 -0
- data/spec/integration/examples_spec_editor.rb +71 -0
- data/spec/integration/package_manager_spec.rb +104 -0
- data/spec/integration/platform_manager_spec.rb +69 -0
- data/spec/integration/service_manager_sysv_spec.rb +115 -0
- data/spec/integration/shell_manager_spec.rb +471 -0
- data/spec/integration/template_manager_erb_spec.rb +31 -0
- data/spec/spec_helper.rb +23 -0
- data/spec/unit/edit_manager_spec.rb +162 -0
- data/spec/unit/field_manager_spec.rb +79 -0
- data/spec/unit/hashcache_spec.rb +28 -0
- data/spec/unit/interpreter_spec.rb +98 -0
- data/spec/unit/platform_manager_spec.rb +44 -0
- data/spec/unit/plugins_spec.rb +253 -0
- data/spec/unit/tag_manager_spec.rb +189 -0
- data/spec/unit/template_manager_erb_spec.rb +137 -0
- metadata +249 -0
- metadata.gz.sig +0 -0
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
#!/usr/bin/env jruby
|
|
2
|
+
# http://svn.codehaus.org/jruby/trunk/jruby/bin/index_gem_repository.rb
|
|
3
|
+
#--
|
|
4
|
+
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
|
|
5
|
+
# All rights reserved.
|
|
6
|
+
# See LICENSE.txt for permissions.
|
|
7
|
+
#++
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
# Generate the yaml/yaml.Z index files for a gem server directory.
|
|
11
|
+
#
|
|
12
|
+
# Usage: generate_yaml_index.rb --dir DIR [--verbose]
|
|
13
|
+
|
|
14
|
+
$:.unshift '~/rubygems' if File.exist? "~/rubygems"
|
|
15
|
+
|
|
16
|
+
require 'optparse'
|
|
17
|
+
require 'rubygems'
|
|
18
|
+
require 'zlib'
|
|
19
|
+
require 'digest/sha2'
|
|
20
|
+
begin
|
|
21
|
+
require 'builder/xchar'
|
|
22
|
+
rescue LoadError
|
|
23
|
+
fail "index_gem_repository requires that the XML Builder library be installed"
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
Gem.manage_gems
|
|
27
|
+
|
|
28
|
+
######################################################################
|
|
29
|
+
# Mixin that provides a +compress+ method for compressing files on
|
|
30
|
+
# disk.
|
|
31
|
+
#
|
|
32
|
+
module Compressor
|
|
33
|
+
# Compress the given file.
|
|
34
|
+
def compress(filename, ext="rz")
|
|
35
|
+
File.open(filename + ".#{ext}", "w") do |file|
|
|
36
|
+
file.write(zip(File.read(filename)))
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Return a compressed version of the given string.
|
|
41
|
+
def zip(string)
|
|
42
|
+
Zlib::Deflate.deflate(string)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Return an uncompressed version of a compressed string.
|
|
46
|
+
def unzip(string)
|
|
47
|
+
Zlib::Inflate.inflate(string)
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
######################################################################
|
|
52
|
+
# Announcer provides a way of announcing activities to the user.
|
|
53
|
+
#
|
|
54
|
+
module Announcer
|
|
55
|
+
# Announce +msg+ to the user.
|
|
56
|
+
def announce(msg)
|
|
57
|
+
puts msg if @options[:verbose]
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
######################################################################
|
|
62
|
+
# Abstract base class for building gem indicies. Uses the template
|
|
63
|
+
# pattern with subclass specialization in the +begin_index+,
|
|
64
|
+
# +end_index+ and +cleanup+ methods.
|
|
65
|
+
#
|
|
66
|
+
class AbstractIndexBuilder
|
|
67
|
+
include Compressor
|
|
68
|
+
include Announcer
|
|
69
|
+
|
|
70
|
+
# Build a Gem index. Yields to block to handle the details of the
|
|
71
|
+
# actual building. Calls +begin_index+, # +end_index+ and +cleanup+
|
|
72
|
+
# at appropriate times to customize basic operations.
|
|
73
|
+
def build
|
|
74
|
+
if ! @enabled
|
|
75
|
+
yield
|
|
76
|
+
else
|
|
77
|
+
unless File.exist?(@directory)
|
|
78
|
+
FileUtils.mkdir_p(@directory)
|
|
79
|
+
end
|
|
80
|
+
fail "not a directory: #{@directory}" unless File.directory?(@directory)
|
|
81
|
+
File.open(File.join(@directory, @filename), "w") do |file|
|
|
82
|
+
@file = file
|
|
83
|
+
start_index
|
|
84
|
+
yield
|
|
85
|
+
end_index
|
|
86
|
+
end
|
|
87
|
+
cleanup
|
|
88
|
+
end
|
|
89
|
+
ensure
|
|
90
|
+
@file = nil
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# Called immediately before the yield in build. The index file is
|
|
94
|
+
# open and availabe as @file.
|
|
95
|
+
def start_index
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
# Called immediately after the yield in build. The index file is
|
|
99
|
+
# still open and available as @file.
|
|
100
|
+
def end_index
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# Called from within builder after the index file has been closed.
|
|
104
|
+
def cleanup
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
######################################################################
|
|
109
|
+
# Construct the master Gem index file.
|
|
110
|
+
#
|
|
111
|
+
class MasterIndexBuilder < AbstractIndexBuilder
|
|
112
|
+
def initialize(filename, options)
|
|
113
|
+
@filename = filename
|
|
114
|
+
@options = options
|
|
115
|
+
@directory = options[:directory]
|
|
116
|
+
@enabled = true
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def start_index
|
|
120
|
+
super
|
|
121
|
+
@file.puts "--- !ruby/object:Gem::Cache"
|
|
122
|
+
@file.puts "gems:"
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def cleanup
|
|
126
|
+
super
|
|
127
|
+
index_file_name = File.join(@directory, @filename)
|
|
128
|
+
compress(index_file_name, "Z")
|
|
129
|
+
paranoid(index_file_name, "#{index_file_name}.Z")
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def add(spec)
|
|
133
|
+
@file.puts " #{spec.full_name}: #{nest(spec.to_yaml)}"
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def nest(yaml_string)
|
|
137
|
+
yaml_string[4..-1].gsub(/\n/, "\n ")
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
private
|
|
141
|
+
|
|
142
|
+
def paranoid(fn, compressed_fn)
|
|
143
|
+
data = File.read(fn)
|
|
144
|
+
compressed_data = File.read(compressed_fn)
|
|
145
|
+
if data != unzip(compressed_data)
|
|
146
|
+
fail "Compressed file #{compressed_fn} does not match uncompressed file #{fn}"
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
######################################################################
|
|
152
|
+
# Construct a quick index file and all of the individual specs to
|
|
153
|
+
# support incremental loading.
|
|
154
|
+
#
|
|
155
|
+
class QuickIndexBuilder < AbstractIndexBuilder
|
|
156
|
+
def initialize(filename, options)
|
|
157
|
+
@filename = filename
|
|
158
|
+
@options = options
|
|
159
|
+
@directory = options[:quick_directory]
|
|
160
|
+
@enabled = options[:quick]
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
def cleanup
|
|
164
|
+
compress(File.join(@directory, @filename))
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
def add(spec)
|
|
168
|
+
return unless @enabled
|
|
169
|
+
@file.puts spec.full_name
|
|
170
|
+
fn = File.join(@directory, "#{spec.full_name}.gemspec.rz")
|
|
171
|
+
File.open(fn, "w") do |gsfile|
|
|
172
|
+
gsfile.write(zip(spec.to_yaml))
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
######################################################################
|
|
178
|
+
# Top level class for building the repository index. Initialize with
|
|
179
|
+
# an options hash and call +build_index+.
|
|
180
|
+
#
|
|
181
|
+
class Indexer
|
|
182
|
+
include Compressor
|
|
183
|
+
include Announcer
|
|
184
|
+
|
|
185
|
+
# Create an indexer with the options specified by the options hash.
|
|
186
|
+
def initialize(options)
|
|
187
|
+
@options = options.dup
|
|
188
|
+
@directory = @options[:directory]
|
|
189
|
+
@options[:quick_directory] = File.join(@directory, "quick")
|
|
190
|
+
@master_index = MasterIndexBuilder.new("yaml", @options)
|
|
191
|
+
@quick_index = QuickIndexBuilder.new("index", @options)
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
# Build the index.
|
|
195
|
+
def build_index
|
|
196
|
+
announce "Building Server Index"
|
|
197
|
+
FileUtils.rm_r(@options[:quick_directory]) rescue nil
|
|
198
|
+
@master_index.build do
|
|
199
|
+
@quick_index.build do
|
|
200
|
+
gem_file_list.each do |gemfile|
|
|
201
|
+
spec = Gem::Format.from_file_by_path(gemfile).spec
|
|
202
|
+
abbreviate(spec)
|
|
203
|
+
sanitize(spec)
|
|
204
|
+
announce " ... adding #{spec.full_name}"
|
|
205
|
+
@master_index.add(spec)
|
|
206
|
+
@quick_index.add(spec)
|
|
207
|
+
end
|
|
208
|
+
end
|
|
209
|
+
end
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
# List of gem file names to index.
|
|
213
|
+
def gem_file_list
|
|
214
|
+
Dir.glob(File.join(@directory, "gems", "*.gem"))
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
# Abbreviate the spec for downloading. Abbreviated specs are only
|
|
218
|
+
# used for searching, downloading and related activities and do not
|
|
219
|
+
# need deployment specific information (e.g. list of files). So we
|
|
220
|
+
# abbreviate the spec, making it much smaller for quicker downloads.
|
|
221
|
+
def abbreviate(spec)
|
|
222
|
+
spec.files = []
|
|
223
|
+
spec.test_files = []
|
|
224
|
+
spec.rdoc_options = []
|
|
225
|
+
spec.extra_rdoc_files = []
|
|
226
|
+
spec.cert_chain = []
|
|
227
|
+
spec
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
# Sanitize the descriptive fields in the spec. Sometimes non-ASCII
|
|
231
|
+
# characters will garble the site index. Non-ASCII characters will
|
|
232
|
+
# be replaced by their XML entity equivalent.
|
|
233
|
+
def sanitize(spec)
|
|
234
|
+
spec.summary = sanitize_string(spec.summary)
|
|
235
|
+
spec.description = sanitize_string(spec.description)
|
|
236
|
+
spec.post_install_message = sanitize_string(spec.post_install_message)
|
|
237
|
+
spec.authors = spec.authors.collect { |a| sanitize_string(a) }
|
|
238
|
+
spec
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
# Sanitize a single string.
|
|
242
|
+
def sanitize_string(string)
|
|
243
|
+
string ? string.to_xs : string
|
|
244
|
+
end
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
######################################################################
|
|
248
|
+
# Top Level Functions
|
|
249
|
+
######################################################################
|
|
250
|
+
|
|
251
|
+
def handle_options(args)
|
|
252
|
+
# default options
|
|
253
|
+
options = {
|
|
254
|
+
:directory => '.',
|
|
255
|
+
:verbose => false,
|
|
256
|
+
:quick => true,
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
args.options do |opts|
|
|
260
|
+
opts.on_tail("--help", "show this message") do
|
|
261
|
+
puts opts
|
|
262
|
+
exit
|
|
263
|
+
end
|
|
264
|
+
opts.on(
|
|
265
|
+
'-d', '--dir=DIRNAME', '--directory=DIRNAME',
|
|
266
|
+
"repository base dir containing gems subdir",
|
|
267
|
+
String) do |value|
|
|
268
|
+
options[:directory] = value
|
|
269
|
+
end
|
|
270
|
+
opts.on('--[no-]quick', "include quick index") do |value|
|
|
271
|
+
options[:quick] = value
|
|
272
|
+
end
|
|
273
|
+
opts.on('-v', '--verbose', "show verbose output") do |value|
|
|
274
|
+
options[:verbose] = value
|
|
275
|
+
end
|
|
276
|
+
opts.on('-V', '--version',
|
|
277
|
+
"show version") do |value|
|
|
278
|
+
puts Gem::RubyGemsVersion
|
|
279
|
+
exit
|
|
280
|
+
end
|
|
281
|
+
opts.parse!
|
|
282
|
+
end
|
|
283
|
+
|
|
284
|
+
if options[:directory].nil?
|
|
285
|
+
puts "Error, must specify directory name. Use --help"
|
|
286
|
+
exit
|
|
287
|
+
elsif ! File.exist?(options[:directory]) ||
|
|
288
|
+
! File.directory?(options[:directory])
|
|
289
|
+
puts "Error, unknown directory name #{directory}."
|
|
290
|
+
exit
|
|
291
|
+
end
|
|
292
|
+
options
|
|
293
|
+
end
|
|
294
|
+
|
|
295
|
+
# Main program.
|
|
296
|
+
def main_index(args)
|
|
297
|
+
options = handle_options(args)
|
|
298
|
+
Indexer.new(options).build_index
|
|
299
|
+
end
|
|
300
|
+
|
|
301
|
+
if __FILE__ == $0 then
|
|
302
|
+
main_index(ARGV)
|
|
303
|
+
end
|
data/misc/setup_egg.rb
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
#!/usr/bin/env automateit
|
|
2
|
+
|
|
3
|
+
# Install Python's easy_install package manager for 'egg' files
|
|
4
|
+
|
|
5
|
+
SOURCE = 'http://peak.telecommunity.com/dist/ez_setup.py'
|
|
6
|
+
|
|
7
|
+
require 'open-uri'
|
|
8
|
+
|
|
9
|
+
mktemp do |t|
|
|
10
|
+
File.open(t, "w+") {|h| h.write(open(SOURCE).read)}
|
|
11
|
+
sh "python #{t}"
|
|
12
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
|
|
3
|
+
# RELEASES: http://rubyforge.org/frs/?group_id=126
|
|
4
|
+
|
|
5
|
+
PACKAGE="rubygems-0.9.3"
|
|
6
|
+
URL="http://rubyforge.org/frs/download.php/20585/rubygems-0.9.3.tgz"
|
|
7
|
+
|
|
8
|
+
pushd "/tmp"
|
|
9
|
+
|
|
10
|
+
CACHE=`mktemp -d install_rubygems.XXXXXXXXXX`
|
|
11
|
+
pushd "$CACHE"
|
|
12
|
+
|
|
13
|
+
wget -c -T20 -q "$URL"
|
|
14
|
+
tar xfz "$PACKAGE.tgz"
|
|
15
|
+
cd "$PACKAGE"
|
|
16
|
+
sudo ruby setup.rb
|
|
17
|
+
|
|
18
|
+
popd
|
|
19
|
+
rm -rf "$CACHE"
|
|
20
|
+
|
|
21
|
+
popd
|
data/misc/which.cmd
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
@ rem "which" workalike for Windows. Searches current directory and PATH for all extensions, stops after first match, and returns meaningful exit value for "system" or "ERRORLEVEL" checks.
|
|
2
|
+
@setlocal
|
|
3
|
+
@set P2=.;%PATH%
|
|
4
|
+
@for %%e in (%PATHEXT%) do @for %%i in (%1%%e) do @if NOT "%%~$P2:i"=="" echo %%~$P2:i && goto end
|
|
5
|
+
@exit 1
|
|
6
|
+
:end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
#!/bin/bash -e
|
|
2
|
+
set -e
|
|
3
|
+
|
|
4
|
+
### BEGIN INIT INFO
|
|
5
|
+
# Provides: automateit_service_test
|
|
6
|
+
# Default-Start: 5
|
|
7
|
+
# Default-Stop: 6
|
|
8
|
+
# Short-Description: automateit_service_test
|
|
9
|
+
# Description: automateit_service_test
|
|
10
|
+
### END INIT INFO
|
|
11
|
+
|
|
12
|
+
STATE="/tmp/automateit_service_test.state"
|
|
13
|
+
status() {
|
|
14
|
+
test -f $STATE;
|
|
15
|
+
}
|
|
16
|
+
case $1 in
|
|
17
|
+
start)
|
|
18
|
+
if status; then
|
|
19
|
+
echo "ERROR: already running"
|
|
20
|
+
exit 1
|
|
21
|
+
else
|
|
22
|
+
echo "started"
|
|
23
|
+
touch $STATE
|
|
24
|
+
exit 0
|
|
25
|
+
fi
|
|
26
|
+
;;
|
|
27
|
+
stop)
|
|
28
|
+
if status; then
|
|
29
|
+
echo "stopping"
|
|
30
|
+
rm $STATE
|
|
31
|
+
exit 0
|
|
32
|
+
else
|
|
33
|
+
echo "ERROR: not running"
|
|
34
|
+
exit 1
|
|
35
|
+
fi
|
|
36
|
+
;;
|
|
37
|
+
status)
|
|
38
|
+
if status; then
|
|
39
|
+
echo "running"
|
|
40
|
+
exit 0
|
|
41
|
+
else
|
|
42
|
+
echo "not running"
|
|
43
|
+
exit 1
|
|
44
|
+
fi
|
|
45
|
+
;;
|
|
46
|
+
*)
|
|
47
|
+
echo "ERROR: unknown command"
|
|
48
|
+
exit 1
|
|
49
|
+
;;
|
|
50
|
+
esac
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
$LOAD_PATH << "lib"
|
|
4
|
+
|
|
5
|
+
require "automateit"
|
|
6
|
+
|
|
7
|
+
puts "==0"
|
|
8
|
+
ai = AutomateIt.new
|
|
9
|
+
#puts "==1"
|
|
10
|
+
#ai.sh "ls"
|
|
11
|
+
#puts "==2"
|
|
12
|
+
#ai.platform_manager.setup(:default => :struct)
|
|
13
|
+
ai.shell_manager.sh "id"
|
|
14
|
+
ai.sh "id"
|
|
15
|
+
ai.eval{sh "id"}
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
require File.join(File.dirname(File.expand_path(__FILE__)), "/../spec_helper.rb")
|
|
2
|
+
|
|
3
|
+
if not INTERPRETER.euid?
|
|
4
|
+
puts "NOTE: Can't check 'euid' on this platform, #{__FILE__}"
|
|
5
|
+
elsif not INTERPRETER.superuser?
|
|
6
|
+
puts "NOTE: Must be root to check #{__FILE__}"
|
|
7
|
+
elsif not INTERPRETER.account_manager.available?(:add_user)
|
|
8
|
+
puts "NOTE: Can't find AccountManager for this platform, #{__FILE__}"
|
|
9
|
+
else
|
|
10
|
+
describe "AutomateIt::AccountManager" do
|
|
11
|
+
before(:all) do
|
|
12
|
+
@a = AutomateIt.new(:verbosity => Logger::WARN)
|
|
13
|
+
@m = @a.account_manager
|
|
14
|
+
|
|
15
|
+
@username = "automateit_testuser"
|
|
16
|
+
@groupname = "automateit_testgroup"
|
|
17
|
+
|
|
18
|
+
raise "User named '#{@username}' found. If this isn't a real user, delete it so that the test can contineu. If this is a real user, change the spec to test with a user that shouldn't exist." if @m.users[@username]
|
|
19
|
+
raise "Group named '#{@groupname}' found. If this isn't a real group, delete it so that the test can contineu. If this is a real group, change the spec to test with a group that shouldn't exist." if @m.groups[@groupname]
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
after(:all) do
|
|
23
|
+
@m.remove_user(@username, :quiet => true)
|
|
24
|
+
@m.remove_group(@username, :quiet => true)
|
|
25
|
+
@m.remove_group(@groupname, :quiet => true)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it "should find root user" do
|
|
29
|
+
entry = @m.users["root"]
|
|
30
|
+
entry.should_not be_nil
|
|
31
|
+
entry.uid.should == 0
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it "should not have a user before one is created" do
|
|
35
|
+
@m.has_user?(@username).should be_false
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it "should create a user" do
|
|
39
|
+
entry = @m.add_user(@username, :passwd => "asdf", :shell => "/bin/false")
|
|
40
|
+
|
|
41
|
+
entry.should_not be_nil
|
|
42
|
+
entry.name.should == @username
|
|
43
|
+
# Leaves behind user for further tests
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
it "should have a user after one is created" do
|
|
47
|
+
# Depends on user to be created by previous tests
|
|
48
|
+
@m.has_user?(@username).should be_true
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
it "should query user data by name" do
|
|
52
|
+
# Depends on user to be created by previous tests
|
|
53
|
+
entry = @m.users[@username]
|
|
54
|
+
entry.should_not be_nil
|
|
55
|
+
entry.name.should == @username
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
it "should query user data by id" do
|
|
59
|
+
# Depends on user to be created by previous tests
|
|
60
|
+
uid = @m.users[@username].uid
|
|
61
|
+
|
|
62
|
+
entry = @m.users[uid]
|
|
63
|
+
entry.should_not be_nil
|
|
64
|
+
entry.name.should == @username
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
it "should not query user data by invalid type" do
|
|
68
|
+
lambda{ @m.users[false] }.should raise_error(TypeError)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
it "should create user group" do
|
|
72
|
+
# Depends on user to be created by previous tests
|
|
73
|
+
@m.groups[@username].should_not be_nil
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
it "should not re-add an existing user" do
|
|
77
|
+
# Depends on user to be created by previous tests
|
|
78
|
+
@m.add_user(@username).should be_false
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
it "should not have a non-existent group" do
|
|
82
|
+
@m.has_group?(@groupname).should be_false
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
it "should add a group" do
|
|
86
|
+
entry = @m.add_group(@groupname)
|
|
87
|
+
entry.should_not be_nil
|
|
88
|
+
entry.name.should == @groupname
|
|
89
|
+
# Leaves behind group for further tests
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
it "should not re-add a group" do
|
|
93
|
+
@m.add_group(@groupname).should be_false
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
it "should query group data by name" do
|
|
97
|
+
entry = @m.groups[@groupname]
|
|
98
|
+
entry.should_not be_nil
|
|
99
|
+
entry.name.should == @groupname
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
it "should query group data by id" do
|
|
103
|
+
gid = @m.groups[@groupname].gid
|
|
104
|
+
|
|
105
|
+
entry = @m.groups[gid]
|
|
106
|
+
entry.should_not be_nil
|
|
107
|
+
entry.name.should == @groupname
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
it "should not query group data by invalid type" do
|
|
111
|
+
lambda{ @m.groups[false] }.should raise_error(TypeError)
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
it "should remove a group" do
|
|
115
|
+
# Depends on group to be created by previous tests
|
|
116
|
+
@m.remove_group(@groupname).should be_true
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
it "should not remove a non-existent group" do
|
|
120
|
+
@m.remove_group(@groupname).should be_false
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
it "should not have members for a non-existent group" do
|
|
124
|
+
@m.users_for_group(@groupname).should == []
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
it "should add a group with members" do
|
|
128
|
+
# Depends on user to be created by previous tests
|
|
129
|
+
@m.add_group(@groupname, :members => @username)
|
|
130
|
+
# Leaves behind group for further tests
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
it "should query users in a group" do
|
|
134
|
+
# Depends on group to be created by previous tests
|
|
135
|
+
@m.users_for_group(@groupname).should == [@username]
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
it "should query groups for a user" do
|
|
139
|
+
# Depends on user to be created by previous tests
|
|
140
|
+
# Depends on group to be created by previous tests
|
|
141
|
+
@m.groups_for_user(@username).should include(@groupname)
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
it "should remove users from a group" do
|
|
145
|
+
# Depends on user to be created by previous tests
|
|
146
|
+
# Depends on group to be created by previous tests
|
|
147
|
+
@m.remove_users_from_group(@username, @groupname).should == [@username]
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
it "should add groups to a user" do
|
|
151
|
+
# Depends on user to be created by previous tests
|
|
152
|
+
@m.add_groups_to_user(@groupname, @username).should == [@groupname]
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
it "should remove groups from user" do
|
|
156
|
+
# Depends on user to be created by previous tests
|
|
157
|
+
@m.remove_groups_from_user(@groupname, @username).should == [@groupname]
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
it "should remove a group with members" do
|
|
161
|
+
# Depends on group to be created by previous tests
|
|
162
|
+
@m.remove_group(@groupname).should be_true
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
it "should not add users to non-existent group" do
|
|
166
|
+
lambda{ @m.add_users_to_group(@username, @groupname) }.should raise_error(ArgumentError)
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
it "should pretend to add users to non-existent group in preview mode" do
|
|
170
|
+
begin
|
|
171
|
+
@a.preview = true
|
|
172
|
+
@m.add_users_to_group(@username, @groupname).should == [@username]
|
|
173
|
+
ensure
|
|
174
|
+
@a.preview = false
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
it "should not remove users from non-existent group" do
|
|
179
|
+
lambda{ @m.remove_users_from_group(@username, @groupname) }.should raise_error(ArgumentError)
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
it "should pretend to remove users from non-existent group in preview mode" do
|
|
183
|
+
begin
|
|
184
|
+
@a.preview = true
|
|
185
|
+
@m.remove_users_from_group(@username, @groupname).should == [@username]
|
|
186
|
+
ensure
|
|
187
|
+
@a.preview = false
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
it "should change password" do
|
|
192
|
+
# Depends on user to be created by previous tests
|
|
193
|
+
pass = "automateit"
|
|
194
|
+
|
|
195
|
+
# TODO This isn't portable
|
|
196
|
+
def extract_pwent(username)
|
|
197
|
+
for filename in %w(/etc/shadow /etc/passwd)
|
|
198
|
+
next unless File.exist?(filename)
|
|
199
|
+
return File.read(filename).split(/\n/).grep(/^#{username}\b/)
|
|
200
|
+
end
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
before = extract_pwent(@username)
|
|
204
|
+
@m.passwd(@username, pass).should be_true
|
|
205
|
+
after = extract_pwent(@username)
|
|
206
|
+
before.should_not eql(after)
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
it "should remove a user" do
|
|
210
|
+
# Depends on user to be created by previous tests
|
|
211
|
+
@m.remove_user(@username, :quiet => true).should be_true
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
it "should not remove a non-existent user" do
|
|
215
|
+
@m.remove_user(@username).should be_false
|
|
216
|
+
end
|
|
217
|
+
end
|
|
218
|
+
end
|