loom-core 0.0.1
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.
- checksums.yaml +7 -0
- data/.gitignore +1 -0
- data/.rspec +2 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +99 -0
- data/Guardfile +54 -0
- data/Rakefile +6 -0
- data/bin/loom +185 -0
- data/lib/env/development.rb +1 -0
- data/lib/loom.rb +44 -0
- data/lib/loom/all.rb +20 -0
- data/lib/loom/config.rb +106 -0
- data/lib/loom/core_ext.rb +37 -0
- data/lib/loom/dsl.rb +60 -0
- data/lib/loom/facts.rb +13 -0
- data/lib/loom/facts/all.rb +2 -0
- data/lib/loom/facts/fact_file_provider.rb +86 -0
- data/lib/loom/facts/fact_set.rb +138 -0
- data/lib/loom/host_spec.rb +32 -0
- data/lib/loom/inventory.rb +124 -0
- data/lib/loom/logger.rb +141 -0
- data/lib/loom/method_signature.rb +174 -0
- data/lib/loom/mods.rb +4 -0
- data/lib/loom/mods/action_proxy.rb +105 -0
- data/lib/loom/mods/all.rb +3 -0
- data/lib/loom/mods/mod_loader.rb +80 -0
- data/lib/loom/mods/module.rb +113 -0
- data/lib/loom/pattern.rb +15 -0
- data/lib/loom/pattern/all.rb +7 -0
- data/lib/loom/pattern/definition_context.rb +74 -0
- data/lib/loom/pattern/dsl.rb +176 -0
- data/lib/loom/pattern/hook.rb +28 -0
- data/lib/loom/pattern/loader.rb +48 -0
- data/lib/loom/pattern/reference.rb +71 -0
- data/lib/loom/pattern/reference_set.rb +169 -0
- data/lib/loom/pattern/result_reporter.rb +77 -0
- data/lib/loom/runner.rb +209 -0
- data/lib/loom/shell.rb +12 -0
- data/lib/loom/shell/all.rb +10 -0
- data/lib/loom/shell/api.rb +48 -0
- data/lib/loom/shell/cmd_result.rb +33 -0
- data/lib/loom/shell/cmd_wrapper.rb +164 -0
- data/lib/loom/shell/core.rb +226 -0
- data/lib/loom/shell/harness_blob.rb +26 -0
- data/lib/loom/shell/harness_command_builder.rb +50 -0
- data/lib/loom/shell/session.rb +25 -0
- data/lib/loom/trap.rb +44 -0
- data/lib/loom/version.rb +3 -0
- data/lib/loomext/all.rb +4 -0
- data/lib/loomext/corefacts.rb +6 -0
- data/lib/loomext/corefacts/all.rb +8 -0
- data/lib/loomext/corefacts/facter_provider.rb +24 -0
- data/lib/loomext/coremods.rb +5 -0
- data/lib/loomext/coremods/all.rb +13 -0
- data/lib/loomext/coremods/exec.rb +50 -0
- data/lib/loomext/coremods/files.rb +104 -0
- data/lib/loomext/coremods/net.rb +33 -0
- data/lib/loomext/coremods/package/adapter.rb +100 -0
- data/lib/loomext/coremods/package/package.rb +62 -0
- data/lib/loomext/coremods/user.rb +82 -0
- data/lib/loomext/coremods/vm.rb +0 -0
- data/lib/loomext/coremods/vm/all.rb +6 -0
- data/lib/loomext/coremods/vm/vbox.rb +84 -0
- data/loom.gemspec +39 -0
- data/loom/inventory.yml +13 -0
- data/scripts/harness.sh +242 -0
- data/spec/loom/host_spec_spec.rb +101 -0
- data/spec/loom/inventory_spec.rb +154 -0
- data/spec/loom/method_signature_spec.rb +275 -0
- data/spec/loom/pattern/dsl_spec.rb +207 -0
- data/spec/loom/shell/cmd_wrapper_spec.rb +239 -0
- data/spec/loom/shell/harness_blob_spec.rb +42 -0
- data/spec/loom/shell/harness_command_builder_spec.rb +36 -0
- data/spec/runloom.sh +35 -0
- data/spec/scripts/harness_spec.rb +385 -0
- data/spec/spec_helper.rb +94 -0
- data/spec/test.loom +370 -0
- data/spec/test_loom_spec.rb +57 -0
- metadata +287 -0
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,94 @@
|
|
1
|
+
Dir.glob('./spec/shared/**/*.rb').each { |f| require f }
|
2
|
+
require './lib/loom'
|
3
|
+
|
4
|
+
# This file was generated by the `rspec --init` command. Conventionally, all
|
5
|
+
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
6
|
+
# The generated `.rspec` file contains `--require spec_helper` which will cause
|
7
|
+
# this file to always be loaded, without a need to explicitly require it in any
|
8
|
+
# files.
|
9
|
+
#
|
10
|
+
# Given that it is always loaded, you are encouraged to keep this file as
|
11
|
+
# light-weight as possible. Requiring heavyweight dependencies from this file
|
12
|
+
# will add to the boot time of your test suite on EVERY test run, even for an
|
13
|
+
# individual file that may not need all of that loaded. Instead, consider making
|
14
|
+
# a separate helper file that requires the additional dependencies and performs
|
15
|
+
# the additional setup, and require it from the spec files that actually need
|
16
|
+
# it.
|
17
|
+
#
|
18
|
+
# The `.rspec` file also contains a few flags that are not defaults but that
|
19
|
+
# users commonly want.
|
20
|
+
#
|
21
|
+
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
22
|
+
RSpec.configure do |config|
|
23
|
+
# rspec-expectations config goes here. You can use an alternate
|
24
|
+
# assertion/expectation library such as wrong or the stdlib/minitest
|
25
|
+
# assertions if you prefer.
|
26
|
+
config.expect_with :rspec do |expectations|
|
27
|
+
# This option will default to `true` in RSpec 4. It makes the `description`
|
28
|
+
# and `failure_message` of custom matchers include text for helper methods
|
29
|
+
# defined using `chain`, e.g.:
|
30
|
+
# be_bigger_than(2).and_smaller_than(4).description
|
31
|
+
# # => "be bigger than 2 and smaller than 4"
|
32
|
+
# ...rather than:
|
33
|
+
# # => "be bigger than 2"
|
34
|
+
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
|
35
|
+
end
|
36
|
+
|
37
|
+
# rspec-mocks config goes here. You can use an alternate test double
|
38
|
+
# library (such as bogus or mocha) by changing the `mock_with` option here.
|
39
|
+
config.mock_with :rspec do |mocks|
|
40
|
+
# Prevents you from mocking or stubbing a method that does not exist on
|
41
|
+
# a real object. This is generally recommended, and will default to
|
42
|
+
# `true` in RSpec 4.
|
43
|
+
mocks.verify_partial_doubles = true
|
44
|
+
end
|
45
|
+
|
46
|
+
# The settings below are suggested to provide a good initial experience
|
47
|
+
# with RSpec, but feel free to customize to your heart's content.
|
48
|
+
=begin
|
49
|
+
# These two settings work together to allow you to limit a spec run
|
50
|
+
# to individual examples or groups you care about by tagging them with
|
51
|
+
# `:focus` metadata. When nothing is tagged with `:focus`, all examples
|
52
|
+
# get run.
|
53
|
+
config.filter_run :focus
|
54
|
+
config.run_all_when_everything_filtered = true
|
55
|
+
|
56
|
+
# Limits the available syntax to the non-monkey patched syntax that is
|
57
|
+
# recommended. For more details, see:
|
58
|
+
# - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax
|
59
|
+
# - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
|
60
|
+
# - http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3#new__config_option_to_disable_rspeccore_monkey_patching
|
61
|
+
config.disable_monkey_patching!
|
62
|
+
|
63
|
+
# This setting enables warnings. It's recommended, but in some cases may
|
64
|
+
# be too noisy due to issues in dependencies.
|
65
|
+
config.warnings = true
|
66
|
+
|
67
|
+
# Many RSpec users commonly either run the entire suite or an individual
|
68
|
+
# file, and it's useful to allow more verbose output when running an
|
69
|
+
# individual spec file.
|
70
|
+
if config.files_to_run.one?
|
71
|
+
# Use the documentation formatter for detailed output,
|
72
|
+
# unless a formatter has already been configured
|
73
|
+
# (e.g. via a command-line flag).
|
74
|
+
config.default_formatter = 'doc'
|
75
|
+
end
|
76
|
+
|
77
|
+
# Print the 10 slowest examples and example groups at the
|
78
|
+
# end of the spec run, to help surface which specs are running
|
79
|
+
# particularly slow.
|
80
|
+
config.profile_examples = 10
|
81
|
+
|
82
|
+
# Run specs in random order to surface order dependencies. If you find an
|
83
|
+
# order dependency and want to debug it, you can fix the order by providing
|
84
|
+
# the seed, which is printed after each run.
|
85
|
+
# --seed 1234
|
86
|
+
config.order = :random
|
87
|
+
|
88
|
+
# Seed global randomization in this process using the `--seed` CLI option.
|
89
|
+
# Setting this allows you to use `--seed` to deterministically reproduce
|
90
|
+
# test failures related to randomization by passing the same `--seed` value
|
91
|
+
# as the one that triggered the failure.
|
92
|
+
Kernel.srand config.seed
|
93
|
+
=end
|
94
|
+
end
|
data/spec/test.loom
ADDED
@@ -0,0 +1,370 @@
|
|
1
|
+
require "loomext/all"
|
2
|
+
|
3
|
+
desc "Prints some known facts"
|
4
|
+
pattern :three_facts do |loom, facts|
|
5
|
+
puts "first 3 facts..."
|
6
|
+
puts facts.facts.to_a.slice(0, 3).map { |tuple| tuple.join "=" }.join("\n")
|
7
|
+
end
|
8
|
+
|
9
|
+
|
10
|
+
desc "Reports `uptime` status"
|
11
|
+
pattern :uptime do |loom, facts|
|
12
|
+
loom << :uptime
|
13
|
+
loom << :hostname
|
14
|
+
loom.local << :hostname
|
15
|
+
end
|
16
|
+
#produces { pkg.installed? :httpd }
|
17
|
+
|
18
|
+
desc "cd's to the /etc directory and runs `pwd`"
|
19
|
+
pattern :cd do |loom, facts|
|
20
|
+
loom.cd "/etc" do
|
21
|
+
loom << :pwd
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
desc "tests return codes from wrapped commands"
|
26
|
+
pattern :wrap_returns do |loom, facts|
|
27
|
+
# using loom.time as a proxy for Shell::Core#wrap here
|
28
|
+
loom.time do
|
29
|
+
raise "wrapped true is not true" unless loom.test :true
|
30
|
+
raise "wrapped false is not false" if loom.test :false
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
desc "Tests a condition."
|
35
|
+
pattern :test do |loom, facts|
|
36
|
+
unless loom.test :false
|
37
|
+
loom.x :echo, "i tested false"
|
38
|
+
end
|
39
|
+
|
40
|
+
if loom.test :true
|
41
|
+
loom.x :echo, "i tested true"
|
42
|
+
end
|
43
|
+
|
44
|
+
if loom.test :which, "bash"
|
45
|
+
loom.x :echo, "has bash"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
desc "Tests a grep condition."
|
50
|
+
pattern :match do |loom, facts|
|
51
|
+
if loom.files("/etc/hosts").match? :pattern => "aldsfja;ldjf"
|
52
|
+
loom.fail "should not match garbage"
|
53
|
+
else
|
54
|
+
loom.x :echo, "I didnt match garbage"
|
55
|
+
end
|
56
|
+
|
57
|
+
unless loom.files("/etc/hosts").match? :pattern => "localhost"
|
58
|
+
loom.fail "should match localhost"
|
59
|
+
else
|
60
|
+
loom.x :echo, "I did match my target"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
desc "Always fails due to return code."
|
65
|
+
pattern :fail_soft do |loom, facts|
|
66
|
+
unless loom << :false
|
67
|
+
loom.x :echo, "i am false"
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
desc "Always fails due to a hard failure"
|
72
|
+
pattern :fail_hard do |loom, facts|
|
73
|
+
loom.fail "Fail big or not at all"
|
74
|
+
end
|
75
|
+
|
76
|
+
desc "Check timeout commands"
|
77
|
+
pattern :timeout_fail do |loom, facts|
|
78
|
+
loom.timeout(:timeout => 1) do
|
79
|
+
loom.x :sleep, 2
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
desc "Wrapped time commands"
|
84
|
+
pattern :time do |loom, facts|
|
85
|
+
loom.time do
|
86
|
+
loom.x :echo, :hi
|
87
|
+
loom.x :sleep, 2
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
module Net
|
92
|
+
include Loom::Pattern
|
93
|
+
|
94
|
+
desc "tests the net package, with_net check"
|
95
|
+
pattern :check_net do |loom, facts|
|
96
|
+
unless loom.net(check_host: '127.0.0.1').has_net?
|
97
|
+
loom.fail 'can not ping localhost'
|
98
|
+
end
|
99
|
+
|
100
|
+
has_local_net = false
|
101
|
+
loom.net(check_host: '127.0.0.1').with_net do
|
102
|
+
has_local_net = true
|
103
|
+
end
|
104
|
+
loom.fail "should have local net" unless has_local_net
|
105
|
+
end
|
106
|
+
|
107
|
+
desc "expected check_net failures"
|
108
|
+
pattern :check_net_fail do |loom, facts|
|
109
|
+
loom.net(timeout: 2, check_host: '1.1.1.1').check_net
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
module Files
|
114
|
+
include Loom::Pattern
|
115
|
+
|
116
|
+
desc "Reads a file"
|
117
|
+
pattern :read do |loom, facts|
|
118
|
+
loom.files("/etc/hosts").cat
|
119
|
+
end
|
120
|
+
|
121
|
+
desc "Gsubs file text"
|
122
|
+
pattern :gsub do |loom, facts|
|
123
|
+
loom.files("/tmp/garbage").write <<EOS
|
124
|
+
This is a bunch of junk
|
125
|
+
192.123.456.0\t\thostname.xyz
|
126
|
+
EOS
|
127
|
+
|
128
|
+
loom.files("/tmp/garbage")
|
129
|
+
.cat
|
130
|
+
.gsub(pattern: /[\d]{3}/, replace: "xxx")
|
131
|
+
.append("this is something new")
|
132
|
+
.cat
|
133
|
+
end
|
134
|
+
|
135
|
+
desc "Chowns a file"
|
136
|
+
pattern :chown do |loom, facts|
|
137
|
+
loom.files("/tmp/chown.me")
|
138
|
+
.touch
|
139
|
+
.append("this file will be owned by root")
|
140
|
+
|
141
|
+
loom.sudo do
|
142
|
+
loom.files("/tmp/chown.me").chown user: :root
|
143
|
+
loom.x :ls, "-lZ", "/tmp/chown.me"
|
144
|
+
|
145
|
+
loom.files("/tmp/chown.me").chown user: :root, group: :root
|
146
|
+
end
|
147
|
+
|
148
|
+
loom.sudo { loom.exec :rm, "/tmp/chown.me" }
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
module Shell
|
153
|
+
include Loom::Pattern
|
154
|
+
|
155
|
+
desc "Executes some commands in a subshell"
|
156
|
+
pattern :subshell do |loom, facts|
|
157
|
+
loom << :"(echo $$; echo $BASHPID; whoami)"
|
158
|
+
loom << :"(sudo -i -u root whoami)"
|
159
|
+
|
160
|
+
loom.local << :"(echo $$; echo $BASHPID; whoami)"
|
161
|
+
# loom.local << "(sudo -i -u root whoami)"
|
162
|
+
end
|
163
|
+
|
164
|
+
desc "Tests nested sudo scenarios"
|
165
|
+
pattern :sudo do |loom, facts|
|
166
|
+
loom.sudo user: "root" do
|
167
|
+
loom << :pwd
|
168
|
+
loom << :whoami
|
169
|
+
loom.exec :touch, "loom.file"
|
170
|
+
|
171
|
+
loom.sudo do
|
172
|
+
loom << :whoami
|
173
|
+
loom << :pwd
|
174
|
+
loom.x :touch, "root.file"
|
175
|
+
|
176
|
+
loom.user.add_system_user :postgres, uid: 999
|
177
|
+
loom.sudo user: :postgres do
|
178
|
+
loom << :whoami
|
179
|
+
loom.cd "/tmp" do
|
180
|
+
loom << :pwd
|
181
|
+
loom.x :touch, "postgres.file"
|
182
|
+
end
|
183
|
+
end
|
184
|
+
loom.user.remove :postgres
|
185
|
+
|
186
|
+
loom.x :touch, "root.file2"
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
loom.cd "/tmp" do
|
191
|
+
loom << :pwd
|
192
|
+
loom.sudo user: :root, cmd: :pwd do loom << :pwd end
|
193
|
+
loom << :pwd
|
194
|
+
end
|
195
|
+
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
module Parent
|
200
|
+
include Loom::Pattern
|
201
|
+
|
202
|
+
with_facts :outer_fact => :outer, :replaced => :original
|
203
|
+
|
204
|
+
before do
|
205
|
+
puts "Test::Parent => before"
|
206
|
+
end
|
207
|
+
|
208
|
+
after do
|
209
|
+
puts "Test::Parent => after"
|
210
|
+
end
|
211
|
+
|
212
|
+
desc "Checks facts on a parent pattern"
|
213
|
+
pattern :check_facts do |loom, facts|
|
214
|
+
unless facts[:outer_fact] == :outer
|
215
|
+
raise "expected outer fact => #{facts[:outer_fact]}"
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
let(:a_let_key) { "the value" }
|
220
|
+
let(:a_fact_based_let) { |facts| facts[:outer_fact].to_s + "/let" }
|
221
|
+
let(:a_referencing_let) { a_let_key + " referenced" }
|
222
|
+
|
223
|
+
desc "Checks let defines"
|
224
|
+
pattern :check_lets do |loom, facts|
|
225
|
+
raise "bad let :a_let_key" unless a_let_key == "the value"
|
226
|
+
raise "bad let :a_fact_based_let" unless a_fact_based_let == "outer/let"
|
227
|
+
|
228
|
+
unless a_referencing_let == "the value referenced"
|
229
|
+
raise "bad let :a_referencing_let => #{a_referencing_let}"
|
230
|
+
end
|
231
|
+
|
232
|
+
puts "a_let_key: %s" % a_let_key
|
233
|
+
puts "a_fact_based_let: %s" % a_fact_based_let
|
234
|
+
end
|
235
|
+
|
236
|
+
module Child
|
237
|
+
include Loom::Pattern
|
238
|
+
|
239
|
+
with_facts :inner_fact => :inner, :replaced => :override
|
240
|
+
let(:a_let_key) { |facts| facts[:inner_fact].to_s + " overrides parent" }
|
241
|
+
|
242
|
+
before do
|
243
|
+
puts "Test::Parent::Child => before"
|
244
|
+
end
|
245
|
+
|
246
|
+
after do
|
247
|
+
puts "Test::Parent::Child => after"
|
248
|
+
end
|
249
|
+
|
250
|
+
desc "Check let overrides"
|
251
|
+
pattern :check_let_overrides do |loom, facts|
|
252
|
+
raise "bad let :a_let_key" unless a_let_key == "inner overrides parent"
|
253
|
+
raise "bad let :a_fact_based_let" unless a_fact_based_let == "outer/let"
|
254
|
+
|
255
|
+
puts "child a_let_key: %s" % a_let_key
|
256
|
+
puts "child a_fact_based_let: %s" % a_fact_based_let
|
257
|
+
end
|
258
|
+
|
259
|
+
desc "Checks inherited facts on a cihld pattern"
|
260
|
+
pattern :check_facts do |loom, facts|
|
261
|
+
unless facts[:inner_fact] == :inner
|
262
|
+
raise "expected inner fact => #{facts[:inner_fact]}"
|
263
|
+
end
|
264
|
+
unless facts[:outer_fact] == :outer
|
265
|
+
raise "expected outer fact => #{facts[:outer_fact]}"
|
266
|
+
end
|
267
|
+
unless facts[:replaced] == :override
|
268
|
+
raise "expected replaced fact => #{facts[:replaced_fact]}"
|
269
|
+
end
|
270
|
+
end
|
271
|
+
end
|
272
|
+
end
|
273
|
+
|
274
|
+
module User
|
275
|
+
include Loom::Pattern
|
276
|
+
|
277
|
+
desc "Adds a bunch of users and then removes them right away"
|
278
|
+
pattern :add_users do |loom, facts|
|
279
|
+
loom.sudo do
|
280
|
+
loom.user.add :nara, uid: 1001, home_dir: "/home/nara"
|
281
|
+
loom.user.add :marrian, home_dir: "/home/marrian"
|
282
|
+
|
283
|
+
loom.user.add_system_user :app, uid: 900
|
284
|
+
loom.user.add_system_user :batch
|
285
|
+
|
286
|
+
loom.user.remove :nara
|
287
|
+
loom.user.remove :marrian
|
288
|
+
loom.user.remove :app
|
289
|
+
loom.user.remove :batch
|
290
|
+
end
|
291
|
+
end
|
292
|
+
|
293
|
+
desc "Makes the postgres user a sudoer"
|
294
|
+
pattern :sudoers do |loom, facts|
|
295
|
+
loom.sudo do
|
296
|
+
loom.user.add_system_user :postgres, uid: 999
|
297
|
+
loom.user.make_sudoer :postgres
|
298
|
+
loom.user.remove :postgres
|
299
|
+
end
|
300
|
+
end
|
301
|
+
end
|
302
|
+
|
303
|
+
module Package
|
304
|
+
include Loom::Pattern
|
305
|
+
|
306
|
+
namespace :pkg
|
307
|
+
|
308
|
+
before do |loom, facts|
|
309
|
+
puts "#{self} in before"
|
310
|
+
end
|
311
|
+
|
312
|
+
after do
|
313
|
+
puts "#{self} in after"
|
314
|
+
end
|
315
|
+
|
316
|
+
desc "Updates the default package manager cache"
|
317
|
+
pattern :update_cache do |loom, facts|
|
318
|
+
loom.sudo { loom.pkg.update_cache }
|
319
|
+
end
|
320
|
+
|
321
|
+
desc "Installs Apache HTTP server"
|
322
|
+
pattern :install_httpd do |loom, facts|
|
323
|
+
loom.sudo do
|
324
|
+
loom.pkg.install 'apache2' unless loom.pkg.installed? 'apache2'
|
325
|
+
end
|
326
|
+
end
|
327
|
+
|
328
|
+
desc "Installs Facter GEM"
|
329
|
+
pattern :install_facter do |loom, facts|
|
330
|
+
loom.sudo do
|
331
|
+
loom.pkg[:gem].ensure_installed :facter
|
332
|
+
end
|
333
|
+
end
|
334
|
+
end
|
335
|
+
|
336
|
+
module ErrorHandling
|
337
|
+
include Loom::Pattern
|
338
|
+
|
339
|
+
namespace :err
|
340
|
+
|
341
|
+
desc "Handle SSH disconnection errors"
|
342
|
+
pattern :ssh_disconnect do |loom, facts|
|
343
|
+
if facts[:really_really_reboot]
|
344
|
+
loom.sudo cmd: :reboot
|
345
|
+
else
|
346
|
+
puts "to REALLY reboot set fact[:really_really_reboot] = true"
|
347
|
+
end
|
348
|
+
end
|
349
|
+
end
|
350
|
+
|
351
|
+
module VMs
|
352
|
+
include Loom::Pattern
|
353
|
+
|
354
|
+
desc "Check if some virtualbox vms exist"
|
355
|
+
pattern :vm_exists? do |loom, facts|
|
356
|
+
vm0_exists = loom.local.vbox.check_exists "vm0.local"
|
357
|
+
puts "Virtualbox VM 'vm0.local' exists: #{vm0_exists}"
|
358
|
+
end
|
359
|
+
|
360
|
+
desc "Check if some virtualbox vms exist"
|
361
|
+
pattern :list do |loom, facts|
|
362
|
+
loom.local.vbox.list
|
363
|
+
end
|
364
|
+
|
365
|
+
desc "Takes a snapshot of a VM"
|
366
|
+
pattern :snap do |loom, facts|
|
367
|
+
loom.local.vbox.snapshot "vm0.local", snapshot_name: "test:snap"
|
368
|
+
loom.local.vbox.snapshot "vm0.local", action: :delete, snapshot_name: "test:snap"
|
369
|
+
end
|
370
|
+
end
|