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
data/bin/ai
ADDED
data/bin/aifield
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
# XXX What can go wrong with this loading approach?
|
|
4
|
+
libdir = File.expand_path(File.join(File.dirname(__FILE__), "..", "lib"))
|
|
5
|
+
if File.directory?(libdir) and File.exists?(File.join(libdir, "automateit.rb"))
|
|
6
|
+
$LOAD_PATH.unshift(libdir)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
require 'rubygems'
|
|
10
|
+
require 'optparse'
|
|
11
|
+
require 'automateit'
|
|
12
|
+
|
|
13
|
+
OptionParser.new do |parser|
|
|
14
|
+
PROG = File.basename($0)
|
|
15
|
+
opts = {}
|
|
16
|
+
parser.banner = <<EOB
|
|
17
|
+
#{PROG} - tool for querying AutomateIt fields
|
|
18
|
+
|
|
19
|
+
Usage: #{PROG} [options] query
|
|
20
|
+
|
|
21
|
+
Examples:
|
|
22
|
+
# Load 'myproject' and get value of 'user' field in 'myapp' hash:
|
|
23
|
+
#{PROG} -p myproject myapp#user
|
|
24
|
+
|
|
25
|
+
# Same but using environmental variable to specify project:
|
|
26
|
+
AUTOMATEIT_PROJECT=myproject
|
|
27
|
+
#{PROG} myapp#user
|
|
28
|
+
|
|
29
|
+
# Dump the 'myapp' hash contents as YAML
|
|
30
|
+
#{PROG} -y myapp#user
|
|
31
|
+
|
|
32
|
+
# Dump the 'myapp' hash contents as XML
|
|
33
|
+
#{PROG} -x myapp#user
|
|
34
|
+
|
|
35
|
+
Options:
|
|
36
|
+
EOB
|
|
37
|
+
parser.on("-p", "--project PATH", "Set project path") do |v|
|
|
38
|
+
opts[:project] = v
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
parser.on("-Y", "--yaml", "Dump as YAML") do |v|
|
|
42
|
+
opts[:yaml] = v
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
parser.on("-X", "--xml", "Dump as XML") do |v|
|
|
46
|
+
opts[:xml] = v
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
parser.on("-h", "--help", "Display this help message") do |v|
|
|
50
|
+
puts parser
|
|
51
|
+
exit
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
parser.on("-v", "--version", "Display version") do |v|
|
|
55
|
+
puts AutomateIt::VERSION
|
|
56
|
+
exit 0
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
args = parser.parse!.dup
|
|
60
|
+
|
|
61
|
+
# Clear ARGV so that IRB doesn't try to parse our options
|
|
62
|
+
opts[:args] = args
|
|
63
|
+
ARGV.clear
|
|
64
|
+
|
|
65
|
+
query = args.first unless args.empty?
|
|
66
|
+
|
|
67
|
+
interpreter = AutomateIt.new(:project => opts[:project])
|
|
68
|
+
result = interpreter.lookup(query)
|
|
69
|
+
if result.nil?
|
|
70
|
+
puts result.inspect
|
|
71
|
+
exit 1
|
|
72
|
+
elsif opts[:yaml]
|
|
73
|
+
puts result.to_yaml
|
|
74
|
+
elsif opts[:xml]
|
|
75
|
+
require 'active_support/core_ext/hash'
|
|
76
|
+
require 'active_support/core_ext/array'
|
|
77
|
+
puts result.to_xml
|
|
78
|
+
else
|
|
79
|
+
puts result.is_a?(String) ? result : result.inspect
|
|
80
|
+
end
|
|
81
|
+
exit 0
|
|
82
|
+
end
|
data/bin/aitag
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
# XXX What can go wrong with this loading approach?
|
|
4
|
+
libdir = File.expand_path(File.join(File.dirname(__FILE__), "..", "lib"))
|
|
5
|
+
if File.directory?(libdir) and File.exists?(File.join(libdir, "automateit.rb"))
|
|
6
|
+
$LOAD_PATH.unshift(libdir)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
require 'rubygems'
|
|
10
|
+
require 'optparse'
|
|
11
|
+
require 'automateit'
|
|
12
|
+
|
|
13
|
+
OptionParser.new do |parser|
|
|
14
|
+
PROG = File.basename($0)
|
|
15
|
+
opts = {}
|
|
16
|
+
parser.banner = <<EOB
|
|
17
|
+
#{PROG} - tool for querying AutomateIt tags
|
|
18
|
+
|
|
19
|
+
Usage: #{PROG} [options] [arguments...]
|
|
20
|
+
|
|
21
|
+
Examples:
|
|
22
|
+
# Load 'myproject' and see if it's tagged with 'apache' or 'svn':
|
|
23
|
+
#{PROG} -p myproject 'apache || svn'
|
|
24
|
+
echo $?
|
|
25
|
+
|
|
26
|
+
# Same but using environmental variable to specify project:
|
|
27
|
+
AUTOMATEIT_PROJECT=myproject
|
|
28
|
+
#{PROG} 'apache || svn'
|
|
29
|
+
echo $?
|
|
30
|
+
|
|
31
|
+
# Dump the results of a query as YAML
|
|
32
|
+
#{PROG} -Y myapp#user
|
|
33
|
+
|
|
34
|
+
# Dump the results of a query as XML
|
|
35
|
+
#{PROG} -X myapp#user
|
|
36
|
+
|
|
37
|
+
Options:
|
|
38
|
+
EOB
|
|
39
|
+
parser.on("-s", "--tags", "List tags for this host") do |v|
|
|
40
|
+
opts[:tags] = v
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
parser.on("-f", "--tags_for HOST", "List tags for a specific host") do |v|
|
|
44
|
+
opts[:tags_for] = v
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
parser.on("-t", "--tagged? QUERY", "Is this host tagged with the query?") do |v|
|
|
48
|
+
opts[:tagged?] = v
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
parser.on("-w", "--hosts_tagged_with QUERY", "List hosts tagged with query") do |v|
|
|
52
|
+
opts[:hosts_tagged_with] = v
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
parser.on("-p", "--project PATH", "Set project path") do |v|
|
|
56
|
+
opts[:project] = v
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
parser.on("-Y", "--yaml", "Dump as YAML") do |v|
|
|
60
|
+
opts[:yaml] = v
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
parser.on("-X", "--xml", "Dump as XML") do |v|
|
|
64
|
+
opts[:xml] = v
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
parser.on("-h", "--help", "Display this help message") do |v|
|
|
68
|
+
puts parser
|
|
69
|
+
exit
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
parser.on("-v", "--version", "Display version") do |v|
|
|
73
|
+
puts AutomateIt::VERSION
|
|
74
|
+
exit 0
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
args = parser.parse!.dup
|
|
78
|
+
|
|
79
|
+
# Clear ARGV so that IRB doesn't try to parse our options
|
|
80
|
+
opts[:args] = args
|
|
81
|
+
ARGV.clear
|
|
82
|
+
|
|
83
|
+
interpreter = AutomateIt.new(:project => opts[:project])
|
|
84
|
+
result = nil
|
|
85
|
+
|
|
86
|
+
unless opts[:tags] or opts[:tags_for] or opts[:tagged?] or opts[:hosts_tagged_with]
|
|
87
|
+
if args.first
|
|
88
|
+
opts[:tagged?] = args.first
|
|
89
|
+
else
|
|
90
|
+
puts parser
|
|
91
|
+
puts "\nERROR: insufficient arguments"
|
|
92
|
+
exit 1
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
result = \
|
|
97
|
+
if opts[:tags]
|
|
98
|
+
interpreter.tags
|
|
99
|
+
elsif opts[:tags_for]
|
|
100
|
+
interpreter.tags_for(opts[:tags_for])
|
|
101
|
+
elsif opts[:tagged?]
|
|
102
|
+
exit(interpreter.tagged?(opts[:tagged?]) ? 0 : 1)
|
|
103
|
+
elsif opts[:hosts_tagged_with]
|
|
104
|
+
interpreter.hosts_tagged_with(opts[:hosts_tagged_with])
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
puts(
|
|
108
|
+
if result.nil?
|
|
109
|
+
result.inspect
|
|
110
|
+
elsif opts[:yaml]
|
|
111
|
+
result.to_yaml
|
|
112
|
+
elsif opts[:xml]
|
|
113
|
+
require 'active_support/core_ext/hash'
|
|
114
|
+
require 'active_support/core_ext/array'
|
|
115
|
+
result.to_xml
|
|
116
|
+
else
|
|
117
|
+
case result
|
|
118
|
+
when String: result
|
|
119
|
+
when Set: result.sort.to_a.join(' ')
|
|
120
|
+
when Array: result.sort.join(' ')
|
|
121
|
+
else result.inspect
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
exit 0
|
|
127
|
+
end
|
|
128
|
+
|
data/bin/automateit
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
# XXX What can go wrong with this loading approach?
|
|
4
|
+
libdir = File.expand_path(File.join(File.dirname(__FILE__), "..", "lib"))
|
|
5
|
+
if File.directory?(libdir) and File.exists?(File.join(libdir, "automateit.rb"))
|
|
6
|
+
$LOAD_PATH.unshift(libdir)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
require 'rubygems'
|
|
10
|
+
require 'logger'
|
|
11
|
+
require 'optparse'
|
|
12
|
+
require 'automateit'
|
|
13
|
+
|
|
14
|
+
include AutomateIt::Constants
|
|
15
|
+
|
|
16
|
+
OptionParser.new do |parser|
|
|
17
|
+
PROG = File.basename($0)
|
|
18
|
+
opts = {}
|
|
19
|
+
parser.banner = <<EOB
|
|
20
|
+
#{PROG} - tool for automating the setup and maintenance of servers
|
|
21
|
+
|
|
22
|
+
Usage: #{PROG} [options] [recipe]
|
|
23
|
+
|
|
24
|
+
Examples:
|
|
25
|
+
# Start an interactive shell session
|
|
26
|
+
#{PROG}
|
|
27
|
+
|
|
28
|
+
# Execute a recipe
|
|
29
|
+
#{PROG} myrecipe.rb
|
|
30
|
+
|
|
31
|
+
# Preview the commands a recipe will run without running them
|
|
32
|
+
#{PROG} -n myrecipe.rb
|
|
33
|
+
|
|
34
|
+
# Eval a string
|
|
35
|
+
#{PROG} -e "puts tags.to_a.inspect"
|
|
36
|
+
|
|
37
|
+
Options:
|
|
38
|
+
EOB
|
|
39
|
+
parser.on("-c", "--create PATH", "Create project at path") do |v|
|
|
40
|
+
opts[:create] = v
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
parser.on("-p", "--project PATH", "Set project path") do |v|
|
|
44
|
+
opts[:project] = v
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
parser.on("-n", "--preview", "Preview without executing commands") do |v|
|
|
48
|
+
opts[:preview] = v
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
parser.on("-e", "--eval STRING", "Evaluate string") do |v|
|
|
52
|
+
opts[:eval] = v
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
parser.on("-q", "--quiet", "Print only errors") do |v|
|
|
56
|
+
opts[:verbosity] = Logger::ERROR
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
parser.on("-d", "--debug", "Print debugging information") do |v|
|
|
60
|
+
opts[:verbosity] = Logger::DEBUG
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
parser.on("-T", "--trace", "Display raw exception traces") do |v|
|
|
64
|
+
opts[:friendly_exceptions] = ! v
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
parser.on("-h", "--help", "Display this help message") do |v|
|
|
68
|
+
puts parser
|
|
69
|
+
exit
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
parser.on("-v", "--version", "Display version") do |v|
|
|
73
|
+
puts AutomateIt::VERSION
|
|
74
|
+
exit 0
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
args = parser.parse!.dup
|
|
78
|
+
|
|
79
|
+
# Clear ARGV so that IRB doesn't try to parse our options
|
|
80
|
+
opts[:args] = args
|
|
81
|
+
ARGV.clear
|
|
82
|
+
|
|
83
|
+
opts[:recipe] = args.first unless args.empty?
|
|
84
|
+
|
|
85
|
+
# Save vars because +run+ will delete opts
|
|
86
|
+
argscopy = args.clone
|
|
87
|
+
optscopy = opts.clone
|
|
88
|
+
|
|
89
|
+
begin
|
|
90
|
+
rv = AutomateIt::CLI.run(opts)
|
|
91
|
+
rescue Exception => e
|
|
92
|
+
msg = nil
|
|
93
|
+
if opts[:friendly_exceptions] != false and e.is_a?(AutomateIt::Error)
|
|
94
|
+
# Friendly message
|
|
95
|
+
msg = PERROR+e.message
|
|
96
|
+
msg << "\n\n"+PNOTE+"Use 'automateit --trace' to see complete backtrace"
|
|
97
|
+
else
|
|
98
|
+
# Raw backtrace
|
|
99
|
+
puts PERROR+"AutomateIt error trace:"
|
|
100
|
+
stack = e.backtrace.clone
|
|
101
|
+
msg = "#{stack.shift}: #{e.message} (#{e.exception.class})}";
|
|
102
|
+
for line in stack
|
|
103
|
+
msg << "\n "+line
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
puts msg
|
|
107
|
+
exit 1
|
|
108
|
+
rescue SysExit => e
|
|
109
|
+
# Don't display errors when exit gets called
|
|
110
|
+
end
|
|
111
|
+
if optscopy[:create] or optscopy[:eval] or argscopy.size > 0
|
|
112
|
+
exit rv ? 0 :1
|
|
113
|
+
else
|
|
114
|
+
# CTRL-D ends the line prematurely, so add a newline
|
|
115
|
+
puts
|
|
116
|
+
end
|
|
117
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
== User-friendly error messages
|
|
2
|
+
|
|
3
|
+
AutomateIt provides user-friendly error messages that make it easier to fix
|
|
4
|
+
problems in recipes and templates. These pinpoint the cause and show code
|
|
5
|
+
snippets.
|
|
6
|
+
|
|
7
|
+
For example, one of the sample recipes is executed -- but there's a problem and
|
|
8
|
+
the output is shown below.
|
|
9
|
+
|
|
10
|
+
The message is telling us the error happened in the
|
|
11
|
+
'examples/basic/recipes/install.rb' recipe at line 47. The first snippet shows
|
|
12
|
+
the end of a failed TemplateManager +render+ call.
|
|
13
|
+
|
|
14
|
+
In the second code snippet, we see there was a problem with the ERB template
|
|
15
|
+
'dist/myapp_server.erb'. This template failed at line 5 because it couldn't
|
|
16
|
+
find a variable called +pat+.
|
|
17
|
+
|
|
18
|
+
With the help of the second snippet, we quickly see that there's a typo -- that
|
|
19
|
+
bad variable should have been +path+. Problem solved!
|
|
20
|
+
|
|
21
|
+
root@kagami> automateit -n examples/basic/recipes/install.rb
|
|
22
|
+
!! Problem with recipe 'examples/basic/recipes/install.rb' at line 47
|
|
23
|
+
|
|
24
|
+
41 :to => "/etc/init.d/myapp_server",
|
|
25
|
+
42 :mode => 0555,
|
|
26
|
+
43 :locals => {
|
|
27
|
+
44 :path => lookup(:path),
|
|
28
|
+
45 :user => lookup(:user),
|
|
29
|
+
46 :port => lookup(:port),
|
|
30
|
+
* 47 }
|
|
31
|
+
48 )
|
|
32
|
+
49
|
|
33
|
+
|
|
34
|
+
(NestedError) Problem with template 'dist/myapp_server.erb' at line 5:
|
|
35
|
+
|
|
36
|
+
1 #!/usr/bin/env ruby
|
|
37
|
+
2
|
|
38
|
+
3 user = "<%=user%>"
|
|
39
|
+
4 port = "<%=port%>"
|
|
40
|
+
* 5 path = "<%=pat%>"
|
|
41
|
+
6 pid = "mongrel.pid"
|
|
42
|
+
7
|
|
43
|
+
|
|
44
|
+
(NameError) undefined local variable or method `pat' for #<AutomateIt::TemplateManager::ERB:0xb78a4e8c>
|
|
45
|
+
/home/igal/workspace/automateit/app/lib/helpful_erb.rb:60:in `result'
|
|
46
|
+
/home/igal/workspace/automateit/app/lib/automateit/template_manager/erb.rb:105:in `render'
|
|
47
|
+
(eval):2:in `render'
|
|
48
|
+
examples/basic/recipes/install.rb:47:in `invoke'
|
|
49
|
+
|
|
50
|
+
=> Use 'automateit --trace' to see complete backtrace
|
data/docs/previews.txt
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
== Previews
|
|
2
|
+
|
|
3
|
+
AutomateIt provides a way to preview commands without actually running them.
|
|
4
|
+
Read the TUTORIAL.txt[link:files/TUTORIAL_txt.html] to learn the basic previewing concepts and commands.
|
|
5
|
+
|
|
6
|
+
=== WARNING: Previewing code can be dangerous!
|
|
7
|
+
|
|
8
|
+
AutomateIt only provides logic for previewing its own commands. Recipe authors
|
|
9
|
+
are responsible for providing previewing logic for their own custom code.
|
|
10
|
+
|
|
11
|
+
Here's what *not* to do with previews:
|
|
12
|
+
|
|
13
|
+
puts "Hello!"
|
|
14
|
+
|
|
15
|
+
The above +puts+ method will execute in both preview and non-preview modes.
|
|
16
|
+
To execute custom code only in a specific mode, wrap it with conditionals.
|
|
17
|
+
|
|
18
|
+
For example:
|
|
19
|
+
|
|
20
|
+
if preview?
|
|
21
|
+
puts "This is a preview"
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
preview_for("PREVIEW: Will run custom commands") do
|
|
25
|
+
puts "Custom commands"
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
When in preview mode, the above recipe will display:
|
|
29
|
+
|
|
30
|
+
This is a preview
|
|
31
|
+
=> PREVIEW: Will run custom commands
|
|
32
|
+
|
|
33
|
+
When run normally without preview mode:
|
|
34
|
+
|
|
35
|
+
Custom commands
|
|
36
|
+
|
|
37
|
+
Therefore, wrap all non-AutomateIt commands (e.g. +system+) that shouldn't be
|
|
38
|
+
executed during the preview with conditionals.
|
|
39
|
+
|
|
40
|
+
=== WARNING: Changing directories during preview can be dangerous!
|
|
41
|
+
|
|
42
|
+
AutomateIt will only *pretend* to make directories in preview mode. In
|
|
43
|
+
preview mode, it will also only *pretend* to change into non-existent
|
|
44
|
+
directories when using commands like #cd, #mkdir and #mktempdircd.
|
|
45
|
+
|
|
46
|
+
This can be *disastrous* if you're executing non-AutomateIt commands (e.g.
|
|
47
|
+
+system+) that use *relative* *paths* and expect to be run inside the
|
|
48
|
+
newly-created temporary directory because the +chdir+ didn't actually happen.
|
|
49
|
+
|
|
50
|
+
For example:
|
|
51
|
+
|
|
52
|
+
# DON'T EVER DO THIS!!!
|
|
53
|
+
mkdir_p "/tmp/foo/bar" do
|
|
54
|
+
system "echo 'I'm going to do: rm -rf *'"
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
If that directory didn't already exist, then running the above code in
|
|
58
|
+
preview mode would cause the +system+ command to actually run! If that wasn't
|
|
59
|
+
an +echo+ command, it would have deleted the contents of your *current*
|
|
60
|
+
directory -- not the <tt>/tmp/foo/bar</tt> directory -- because that
|
|
61
|
+
directory wasn't actually created due to the preview mode!
|
|
62
|
+
|
|
63
|
+
The correct way to write the above example is:
|
|
64
|
+
|
|
65
|
+
mkdir_p "/tmp/foo/bar" do
|
|
66
|
+
preview_for("PREVIEW: Deleting all files in directory /tmp/foo/bar") do
|
|
67
|
+
system "echo 'I'm going to do: rm -rf *'"
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
The Interpreter#preview_for method provides conditional execution of blocks.
|
|
72
|
+
When running in preview mode, it will display the supplied message and not
|
|
73
|
+
execute the block containing the +system+ command:
|
|
74
|
+
|
|
75
|
+
=> PREVIEW: Deleting all files in directory /tmp/foo/bar
|
|
76
|
+
|
|
77
|
+
When running without preview mode, the method will not display the message
|
|
78
|
+
but will call block, generating the following output:
|
|
79
|
+
|
|
80
|
+
** echo 'I'm going to do: rm -rf *'"
|
|
81
|
+
I'm going to do: rm -rf *
|
|
82
|
+
|
|
83
|
+
=== Conclusion
|
|
84
|
+
|
|
85
|
+
Keeping the preview issues in mind and wrapping custom code with conditionals
|
|
86
|
+
will help you write code that can be safely previewed.
|