org-converge 0.0.13 → 0.0.14
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +1 -0
- data/TODO +21 -10
- data/bin/org-converge +1 -1
- data/lib/org-converge/command.rb +30 -7
- data/lib/org-converge/engine.rb +61 -21
- data/lib/org-converge/version.rb +1 -1
- data/spec/converge_examples/block_modifiers/run.org +2 -1
- data/spec/converge_examples/chdir/local-run.org +42 -0
- data/spec/converge_examples/idempotency/conditions.org +158 -0
- data/spec/converge_spec.rb +29 -0
- data/vagrant.org +104 -0
- metadata +7 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b8f7e90bad105cff350dbb911fe70a553646caa6
|
4
|
+
data.tar.gz: da367c09faae2f51ad7b0efd34c57f5a27ab8057
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2b099f71b36b2504a9ae922ea1956d2a23eb224478c332fc230a747079105db9214b604d397ab43f0fa8dfd8d29b2349384a00ca4dfcf7f9e2fd72809e0885b8
|
7
|
+
data.tar.gz: 8768bddc3b3273d54164c7325e2f1f5e22b1364ed91ceaecf31f6edd1ee426274500ebd45eec6ed8329e1a048a4041de85f9614a9e443086d5fe83a52f5ef466
|
data/Gemfile
CHANGED
data/TODO
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
#+TODO: TODO | DONE CANCELED
|
3
3
|
#+startup: showeverything
|
4
4
|
|
5
|
-
* [0/
|
5
|
+
* [0/16] 0.1.0 version
|
6
6
|
|
7
7
|
- [ ] Macros can be loaded and applied to the configuration
|
8
8
|
- [ ] Actually support converging and idempotency (~--runmode=idempotent~)
|
@@ -13,25 +13,36 @@
|
|
13
13
|
- [ ] Heuristics for determining which binary to use for running the script
|
14
14
|
- [ ] Display how the run would look like without making changes
|
15
15
|
: org-converge setupfile.org --dry-run
|
16
|
-
- [ ] Use
|
17
|
-
- [ ] Can use ~:dir~ for running a process relative to that directory
|
16
|
+
- [ ] Use =:eval= for evaling blocks (off by default)
|
18
17
|
- [ ] Bugfix for when results blocks have only inline examples or images
|
19
18
|
- [ ] Bugfix for when the result from a ~org-spec~ run has non-zero exit status
|
20
19
|
- [ ] Bugfixes for spec run
|
21
|
-
|
22
|
-
* [0/5] 0.0.14
|
23
|
-
|
24
20
|
- [ ] Distributed run helpers for the header arguments
|
25
|
-
|
21
|
+
Like remote =:dir= for example.
|
22
|
+
- [ ] =:onerror=
|
23
|
+
aborteverything, restart, runhandler
|
24
|
+
- [ ] =:asserts=
|
26
25
|
- [ ] =:waits:=
|
27
26
|
Wait for other processes to start before starting.
|
28
27
|
The process does not start until the alive signal to the following
|
29
28
|
list of processes succeeds.
|
30
29
|
- [ ] =:awaits:=
|
31
30
|
Wait for other processes to finish before starting.
|
32
|
-
- [ ] =:
|
33
|
-
|
34
|
-
- [ ] =:
|
31
|
+
- [ ] =:file=
|
32
|
+
For storing the output from the evaluation (already done in spec mode)a
|
33
|
+
- [ ] Can use =:dir= for running a process remotely via ssh
|
34
|
+
This needs the credentials to be readily available
|
35
|
+
|
36
|
+
* [2/2] 0.0.14
|
37
|
+
|
38
|
+
All of the following makes it required to
|
39
|
+
track the result from the runs.
|
40
|
+
|
41
|
+
- [X] Can use =:dir= for running a process relative to that directory
|
42
|
+
- [X] =:if= and =:unless= checks
|
43
|
+
First step at achieving idempotency.
|
44
|
+
This tracks the result from another block.
|
45
|
+
In case the block results in exit 0, then true. Otherwise false.
|
35
46
|
|
36
47
|
* [2/2] 0.0.13
|
37
48
|
|
data/bin/org-converge
CHANGED
data/lib/org-converge/command.rb
CHANGED
@@ -4,6 +4,7 @@ module OrgConverge
|
|
4
4
|
attr_reader :logger
|
5
5
|
attr_reader :ob
|
6
6
|
attr_reader :engine
|
7
|
+
attr_reader :runmode
|
7
8
|
|
8
9
|
def initialize(options)
|
9
10
|
@options = options
|
@@ -27,6 +28,9 @@ module OrgConverge
|
|
27
28
|
logger.formatter = proc do |severity, datetime, progname, msg|
|
28
29
|
"[#{datetime.strftime('%Y-%m-%dT%H:%M:%S %z')}] #{msg}\n"
|
29
30
|
end
|
31
|
+
|
32
|
+
# Keep track of the exit status from the process for idempotency checks
|
33
|
+
@procs_exit_status = Hash.new { |h,k| h[k] = { } }
|
30
34
|
end
|
31
35
|
|
32
36
|
def execute!
|
@@ -48,7 +52,7 @@ module OrgConverge
|
|
48
52
|
|
49
53
|
def converge!
|
50
54
|
tangle!
|
51
|
-
runmode = @options['--runmode'] || ob.in_buffer_settings['RUNMODE']
|
55
|
+
@runmode = @options['--runmode'] || ob.in_buffer_settings['RUNMODE']
|
52
56
|
case
|
53
57
|
when @options['--name']
|
54
58
|
if runmode == 'sequentially'
|
@@ -65,7 +69,7 @@ module OrgConverge
|
|
65
69
|
case runmode
|
66
70
|
when 'parallel'
|
67
71
|
run_blocks_in_parallel!
|
68
|
-
when 'sequential'
|
72
|
+
when 'sequential', 'idempotent'
|
69
73
|
run_blocks_sequentially!
|
70
74
|
when 'chained', 'chain', 'tasks'
|
71
75
|
run_blocks_chain!
|
@@ -131,7 +135,6 @@ module OrgConverge
|
|
131
135
|
end
|
132
136
|
|
133
137
|
def run_blocks_sequentially!
|
134
|
-
@engine = OrgConverge::Engine.new(:logger => @logger, :babel => @babel)
|
135
138
|
babel.tangle_runnable_blocks!(@run_dir)
|
136
139
|
|
137
140
|
runlist_stack = []
|
@@ -141,17 +144,17 @@ module OrgConverge
|
|
141
144
|
|
142
145
|
while not runlist_stack.empty?
|
143
146
|
key, script = runlist_stack.shift
|
144
|
-
|
145
147
|
# Decision: Only run blocks which have a name
|
146
148
|
next unless script[:header][:name]
|
147
|
-
|
148
149
|
display_name = script[:header][:name]
|
149
|
-
with_running_engine
|
150
|
+
exit_status_list = with_running_engine(:runmode => @runmode) \
|
151
|
+
do |engine|
|
150
152
|
file = File.expand_path("#{@run_dir}/#{key}")
|
151
153
|
bin = determine_lang_bin(script)
|
152
154
|
cmd = "#{bin} #{file}"
|
153
155
|
run_procs(script, cmd, engine)
|
154
156
|
end
|
157
|
+
@procs_exit_status.merge!(exit_status_list)
|
155
158
|
end
|
156
159
|
logger.info "Run has completed successfully.".fg 'green'
|
157
160
|
end
|
@@ -209,7 +212,7 @@ module OrgConverge
|
|
209
212
|
file = File.expand_path("#{@run_dir}/#{key}")
|
210
213
|
bin = determine_lang_bin(script)
|
211
214
|
cmd = "#{bin} #{file}"
|
212
|
-
|
215
|
+
run_procs(script, cmd, engine)
|
213
216
|
end
|
214
217
|
end
|
215
218
|
logger.info "Run has completed successfully.".fg 'green'
|
@@ -344,6 +347,26 @@ module OrgConverge
|
|
344
347
|
def run_procs(script, cmd, engine=nil)
|
345
348
|
engine ||= @engine
|
346
349
|
display_name = script[:header][:name]
|
350
|
+
|
351
|
+
if @runmode == 'idempotent'
|
352
|
+
case
|
353
|
+
when script[:header][:if]
|
354
|
+
block_name = script[:header][:if]
|
355
|
+
exit_status = @procs_exit_status[block_name]
|
356
|
+
unless exit_status == 0
|
357
|
+
logger.info "#{display_name.fg 'green'} -- Skipped since :if clause matches check from '#{block_name.fg 'yellow'}'"
|
358
|
+
return
|
359
|
+
end
|
360
|
+
when script[:header][:unless]
|
361
|
+
block_name = script[:header][:unless]
|
362
|
+
exit_status = @procs_exit_status[block_name]
|
363
|
+
if exit_status == 0
|
364
|
+
logger.info "#{display_name.fg 'green'} -- Skipped since :unless clause matches check from '#{block_name.fg 'yellow'}'"
|
365
|
+
return
|
366
|
+
end
|
367
|
+
end
|
368
|
+
end
|
369
|
+
|
347
370
|
if script[:header][:procs]
|
348
371
|
procs = script[:header][:procs].to_i
|
349
372
|
1.upto(procs) do |i|
|
data/lib/org-converge/engine.rb
CHANGED
@@ -5,6 +5,7 @@
|
|
5
5
|
require 'foreman/engine'
|
6
6
|
require 'foreman/process'
|
7
7
|
require 'tco'
|
8
|
+
require 'fileutils'
|
8
9
|
|
9
10
|
module OrgConverge
|
10
11
|
class Engine < Foreman::Engine
|
@@ -23,6 +24,10 @@ module OrgConverge
|
|
23
24
|
# Code blocks whose start invocation is manipulated run inside a thread
|
24
25
|
@threads = []
|
25
26
|
@running_threads = { }
|
27
|
+
|
28
|
+
# Returns a list in the end with the exit status code from the code blocks
|
29
|
+
# that were run in parallel
|
30
|
+
@procs_exit_status = { }
|
26
31
|
end
|
27
32
|
|
28
33
|
# We allow other processes to exit with 0 status
|
@@ -33,7 +38,7 @@ module OrgConverge
|
|
33
38
|
watch_for_output
|
34
39
|
sleep 0.1
|
35
40
|
begin
|
36
|
-
status = watch_for_termination do
|
41
|
+
status = watch_for_termination do
|
37
42
|
@threads.each do |t|
|
38
43
|
unless t.alive?
|
39
44
|
t.exit
|
@@ -42,6 +47,8 @@ module OrgConverge
|
|
42
47
|
end
|
43
48
|
end
|
44
49
|
end while (@running.count > 0 or @running_threads.count > 0)
|
50
|
+
|
51
|
+
@procs_exit_status
|
45
52
|
end
|
46
53
|
|
47
54
|
# Overriden: we do not consider process formations
|
@@ -78,6 +85,7 @@ module OrgConverge
|
|
78
85
|
def register(name, command, options={})
|
79
86
|
options[:env] ||= env
|
80
87
|
options[:cwd] ||= File.dirname(command.split(" ").first)
|
88
|
+
|
81
89
|
process = OrgConverge::CodeBlockProcess.new(command, options)
|
82
90
|
@names[process] = name
|
83
91
|
@processes << process
|
@@ -125,6 +133,20 @@ module OrgConverge
|
|
125
133
|
rescue Errno::ECHILD
|
126
134
|
end
|
127
135
|
|
136
|
+
def termination_message_for(status)
|
137
|
+
n = name_for(status.pid).split('.').first
|
138
|
+
|
139
|
+
if status.exited?
|
140
|
+
@procs_exit_status[n] = status.exitstatus
|
141
|
+
"exited with code #{status.exitstatus}"
|
142
|
+
elsif status.signaled?
|
143
|
+
# TODO: How to handle exit by signals? Non-zero exit status so idempotency check fails?
|
144
|
+
"terminated by SIG#{Signal.list.invert[status.termsig]}"
|
145
|
+
else
|
146
|
+
"died a mysterious death"
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
128
150
|
def name_for(pid)
|
129
151
|
process = nil
|
130
152
|
index = nil
|
@@ -144,46 +166,64 @@ module OrgConverge
|
|
144
166
|
# Need to expose the options to make the process be aware
|
145
167
|
# of the possible running mode (specially spec mode)
|
146
168
|
# and where to put the results output
|
147
|
-
require 'timeout'
|
148
169
|
class CodeBlockProcess < Foreman::Process
|
149
170
|
attr_reader :options
|
150
171
|
|
151
172
|
def run(options={})
|
152
173
|
env = @options[:env].merge(options[:env] || {})
|
153
174
|
output = options[:output] || $stdout
|
154
|
-
runner = "#{Foreman.runner}".shellescape
|
175
|
+
runner = "#{Foreman.runner}".shellescape
|
155
176
|
|
156
177
|
# whitelist the modifiers which manipulate how to the block is started
|
157
178
|
block_modifiers = { }
|
158
179
|
if options[:header]
|
159
180
|
block_modifiers[:waitfor] = options[:header][:waitsfor] || options[:header][:waitfor] || options[:header][:sleep]
|
160
181
|
block_modifiers[:timeout] = options[:header][:timeoutin] || options[:header][:timeout] || options[:header][:timeoutafter]
|
182
|
+
if options[:header][:dir]
|
183
|
+
block_modifiers[:cwd] = File.expand_path(File.join(self.options[:cwd], options[:header][:dir]))
|
184
|
+
end
|
161
185
|
end
|
162
186
|
|
163
187
|
pid = nil
|
164
188
|
thread = nil
|
165
|
-
process = nil
|
166
189
|
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
end
|
178
|
-
else
|
179
|
-
if Foreman.windows?
|
180
|
-
Dir.chdir(cwd) do
|
181
|
-
pid = Process.spawn env, expanded_command(env), :out => output, :err => output
|
182
|
-
end
|
190
|
+
process = proc do
|
191
|
+
wrapped_command = ''
|
192
|
+
if block_modifiers[:cwd]
|
193
|
+
@options[:cwd] = block_modifiers[:cwd]
|
194
|
+
# Need to adjust the path by having the run file at the same place
|
195
|
+
bin, original_script = command.split(' ')
|
196
|
+
new_script = File.join(block_modifiers[:cwd], ".#{options[:header][:name]}")
|
197
|
+
FileUtils.cp(original_script, new_script)
|
198
|
+
cmd = [bin, new_script].join(' ')
|
199
|
+
wrapped_command = "exec #{runner} -d '#{cwd}' -p -- #{cmd}"
|
183
200
|
else
|
184
201
|
wrapped_command = "exec #{runner} -d '#{cwd}' -p -- #{command}"
|
185
|
-
pid = Process.spawn env, wrapped_command, :out => output, :err => output
|
186
202
|
end
|
203
|
+
opts = { :out => output, :err => output }
|
204
|
+
pid = Process.spawn env, wrapped_command, opts
|
205
|
+
end
|
206
|
+
|
207
|
+
# In case we modify the run block, we run it in a Thread
|
208
|
+
# otherwise we continue treating it as a forked process.
|
209
|
+
if block_modifiers and (block_modifiers[:waitfor] || block_modifiers[:timeout] || block_modifiers[:dir])
|
210
|
+
waitfor = block_modifiers[:waitfor].to_i
|
211
|
+
timeout = block_modifiers[:timeout].to_i
|
212
|
+
|
213
|
+
thread = Thread.new do
|
214
|
+
sleep waitfor if waitfor > 0
|
215
|
+
pid = process.call
|
216
|
+
if timeout > 0
|
217
|
+
sleep timeout
|
218
|
+
# FIXME: Kill children properly
|
219
|
+
o = `ps -ef | awk '$3 == #{pid} { print $2 }'`
|
220
|
+
o.each_line { |cpid| Process.kill(:TERM, cpid.to_i) }
|
221
|
+
Process.kill(:TERM, pid)
|
222
|
+
Thread.current.kill
|
223
|
+
end
|
224
|
+
end
|
225
|
+
else
|
226
|
+
pid = process.call
|
187
227
|
end
|
188
228
|
|
189
229
|
# In case of thread, pid will be nil
|
data/lib/org-converge/version.rb
CHANGED
@@ -7,6 +7,7 @@ We have the following process, but it will take 5 seconds to start...
|
|
7
7
|
echo "Wait..."
|
8
8
|
for i in `seq 1 4`;
|
9
9
|
do
|
10
|
+
echo $i
|
10
11
|
echo $i >> out.log
|
11
12
|
sleep 1
|
12
13
|
done
|
@@ -21,7 +22,7 @@ echo "whoosh" > out.log
|
|
21
22
|
#+end_src
|
22
23
|
|
23
24
|
#+name: timeout-in-3-seconds
|
24
|
-
#+begin_src sh :timeout
|
25
|
+
#+begin_src sh :timeout 5
|
25
26
|
while true; do
|
26
27
|
echo "Eventually will timeout..."
|
27
28
|
sleep 1
|
@@ -0,0 +1,42 @@
|
|
1
|
+
#+TITLE: Changing directories locally
|
2
|
+
#+runmode: sequential
|
3
|
+
|
4
|
+
Like in the original Org babel from Emacs, it should be possible
|
5
|
+
to run the block with a different root. This avoids having to implement
|
6
|
+
changing dir within the language as well.
|
7
|
+
|
8
|
+
#+begin_src python :tangle subdir/greetings/greetings.py :mkdirp true
|
9
|
+
def hello():
|
10
|
+
f = open('out.log', 'w')
|
11
|
+
f.write("Hi\n")
|
12
|
+
print "Finished writing."
|
13
|
+
#+end_src
|
14
|
+
|
15
|
+
#+begin_src python :tangle subdir/greetings/__init__.py :mkdirp true
|
16
|
+
# greetings module
|
17
|
+
#+end_src
|
18
|
+
|
19
|
+
#+name: load-and-greet-test
|
20
|
+
#+begin_src python :results output code :dir subdir
|
21
|
+
from greetings import greetings
|
22
|
+
|
23
|
+
print dir(greetings)
|
24
|
+
|
25
|
+
for i in range(0, 10):
|
26
|
+
greetings.hello()
|
27
|
+
#+end_src
|
28
|
+
|
29
|
+
#+name: path-test
|
30
|
+
#+begin_src python :results output code :dir subdir
|
31
|
+
import os
|
32
|
+
|
33
|
+
print os.getcwd()
|
34
|
+
print os.path.realpath(__file__)
|
35
|
+
print os.path.dirname(os.path.realpath(__file__))
|
36
|
+
#+end_src
|
37
|
+
|
38
|
+
#+name: bash-cwd-text
|
39
|
+
#+begin_src sh :results output :dir subdir
|
40
|
+
echo "within subdir" > out.log
|
41
|
+
cat out.log
|
42
|
+
#+end_src
|
@@ -0,0 +1,158 @@
|
|
1
|
+
#+TITLE: Idempotency examples
|
2
|
+
#+runmode: sequential
|
3
|
+
|
4
|
+
First steps towards achieving idempotency.
|
5
|
+
All of these are identified when tangling and during execution.
|
6
|
+
|
7
|
+
- Example resources
|
8
|
+
+ command
|
9
|
+
exit status 1 means that the block should be run
|
10
|
+
exit status 0 means that it should not be run
|
11
|
+
+ directory
|
12
|
+
Can be covered by :mkdirp
|
13
|
+
+ package
|
14
|
+
If package is in the dpkg -l output, don't install
|
15
|
+
+ template
|
16
|
+
Makes sense only when tangling.
|
17
|
+
If there was a diff in the template, then apply and notify another block
|
18
|
+
+ file
|
19
|
+
if it exists then run
|
20
|
+
else do not run it
|
21
|
+
|
22
|
+
*** DONE When =:if <block>= is used, it will execute the block unless conditional block returns 0
|
23
|
+
|
24
|
+
The most general case is when we link 2 different code blocks
|
25
|
+
so that one can define whether the second one should be executed.
|
26
|
+
|
27
|
+
In order to achieve this, the blocks need to be defined sequentially
|
28
|
+
this way it will be checked whether sinatra is installed or not first,
|
29
|
+
and use the exit status when considering to start the application.
|
30
|
+
|
31
|
+
*NOTE*: Because of this constraint, parallel runs cannot run in converge mode.
|
32
|
+
Only sequential runs supported.
|
33
|
+
|
34
|
+
#+name: install-package
|
35
|
+
#+begin_src sh
|
36
|
+
echo "brew install something..."
|
37
|
+
echo "package is installed" > installed
|
38
|
+
#+end_src
|
39
|
+
|
40
|
+
#+name: package-already-installed
|
41
|
+
#+begin_src sh
|
42
|
+
if [ -e installed ]; then
|
43
|
+
echo "Already installed"
|
44
|
+
exit 0
|
45
|
+
else
|
46
|
+
echo "Needs install"
|
47
|
+
exit 1
|
48
|
+
fi
|
49
|
+
#+end_src
|
50
|
+
|
51
|
+
#+name: install-package-once-again
|
52
|
+
#+begin_src sh :unless package-already-installed
|
53
|
+
echo "Installing the package once again..."
|
54
|
+
echo "not run" >> installed
|
55
|
+
#+end_src
|
56
|
+
|
57
|
+
#+name: do-everything-even-if-package-installed
|
58
|
+
#+begin_src sh :if package-already-installed
|
59
|
+
echo "Doing this even if installed already..."
|
60
|
+
echo "eof" >> installed
|
61
|
+
#+end_src
|
62
|
+
|
63
|
+
*** COMMENT When it has a results block, then it will be executed unless it matches the spec
|
64
|
+
|
65
|
+
Here they would be run sequentially, but it would be better if the =:assert= block
|
66
|
+
can be lazily invoked when deploy-app is about to run, not during the preparation step
|
67
|
+
which happens sequentially.
|
68
|
+
|
69
|
+
#+name: ruby-version-installed
|
70
|
+
#+begin_src sh :results output code :exports none
|
71
|
+
ruby --version | awk '{ print $2 }'
|
72
|
+
#+end_src
|
73
|
+
|
74
|
+
#+RESULTS: ruby-version-installed
|
75
|
+
#+BEGIN_SRC sh
|
76
|
+
1.8.7
|
77
|
+
#+END_SRC
|
78
|
+
|
79
|
+
#+name: deploy-app
|
80
|
+
#+begin_src sh :assert ruby-version-installed
|
81
|
+
echo "Can deploy app because correct Ruby is installed"
|
82
|
+
#+end_src
|
83
|
+
|
84
|
+
*** COMMENT When =:if file-exists :at <path>= is used, it will execute the block unless the file exists
|
85
|
+
|
86
|
+
#+name: execute-if-file-exists
|
87
|
+
#+begin_src sh :if file-exists :at /var/run/ntpd.pid
|
88
|
+
echo "Starting process because ntpd file exists exists.."
|
89
|
+
#+end_src
|
90
|
+
|
91
|
+
These =file-exists= kind of checks can be pluggable.
|
92
|
+
|
93
|
+
*** COMMENT Ideas
|
94
|
+
**** TODO How to support gated checks in parallel runs?
|
95
|
+
|
96
|
+
Let's say that we have a run which makes a healthcheck in the end.
|
97
|
+
In this case, it would mean that a healthcheck would be run
|
98
|
+
once run-web-app is alive.
|
99
|
+
|
100
|
+
Run a healthcheck for the application in the end
|
101
|
+
to confirm that it boot up correctly:
|
102
|
+
|
103
|
+
#+begin_src ruby :tangle sinatra/app.rb :mkdirp true
|
104
|
+
require 'sinatra'
|
105
|
+
|
106
|
+
get '/' do
|
107
|
+
"OK\n"
|
108
|
+
end
|
109
|
+
#+end_src
|
110
|
+
|
111
|
+
***** Check if Sinatra is installed at least
|
112
|
+
:PROPERTIES:
|
113
|
+
:SRC_ORDER: sequential
|
114
|
+
:END:
|
115
|
+
|
116
|
+
One idea is to accumulate them in case they are under
|
117
|
+
the same headline, meaning that runlists can be grouped.
|
118
|
+
|
119
|
+
#+name: sinatra-is-installed
|
120
|
+
#+begin_src sh
|
121
|
+
echo "Checking if sinatra is installed"
|
122
|
+
gem list | grep sinatra
|
123
|
+
#+end_src
|
124
|
+
|
125
|
+
...then run it as follows:
|
126
|
+
|
127
|
+
#+name: install-sinatra
|
128
|
+
#+begin_src sh :unless sinatra-is-installed
|
129
|
+
gem install sinatra
|
130
|
+
#+end_src
|
131
|
+
|
132
|
+
A block which is not executed due to an idempotency check
|
133
|
+
is equivalent to another one that ended with exit status 0.
|
134
|
+
|
135
|
+
#+name: server-start
|
136
|
+
#+begin_src sh :timeout 5 :if install-sinatra
|
137
|
+
ruby sinatra/app.rb
|
138
|
+
#+end_src
|
139
|
+
|
140
|
+
***** Run a healthcheck for the sinatra application
|
141
|
+
:PROPERTIES:
|
142
|
+
:SRC_ORDER: sequential
|
143
|
+
:END:
|
144
|
+
|
145
|
+
#+name: healthcheck-sinatra-app
|
146
|
+
#+begin_src sh :sleep 3 :timeout 10 :awaits server-start
|
147
|
+
while true; do
|
148
|
+
curl 127.0.0.1:4567 2> /dev/null
|
149
|
+
if [ $? != 0 ]; then
|
150
|
+
echo "NOT OK"
|
151
|
+
fi
|
152
|
+
sleep 1
|
153
|
+
done
|
154
|
+
#+end_src
|
155
|
+
|
156
|
+
#+begin_src sh
|
157
|
+
echo "Run"
|
158
|
+
#+end_src
|
data/spec/converge_spec.rb
CHANGED
@@ -159,4 +159,33 @@ describe OrgConverge::Command do
|
|
159
159
|
result = File.open("#{example_dir}/out.log").read
|
160
160
|
result.should == "whoosh\n1\n2\n3\n4\n"
|
161
161
|
end
|
162
|
+
|
163
|
+
it "should be able to chdir the process directory" do
|
164
|
+
example_dir = File.join(EXAMPLES_DIR, 'chdir')
|
165
|
+
setup_file = File.join(example_dir, 'local-run.org')
|
166
|
+
|
167
|
+
o = OrgConverge::Command.new({
|
168
|
+
'<org_file>' => setup_file,
|
169
|
+
'--root-dir' => example_dir
|
170
|
+
})
|
171
|
+
success = o.execute!
|
172
|
+
success.should == true
|
173
|
+
result = File.open("#{example_dir}/subdir/out.log").read
|
174
|
+
result.should == "within subdir\n"
|
175
|
+
end
|
176
|
+
|
177
|
+
it "should support idempotency checks via :if and :unless conditional clauses" do
|
178
|
+
example_dir = File.join(EXAMPLES_DIR, 'idempotency')
|
179
|
+
setup_file = File.join(example_dir, 'conditions.org')
|
180
|
+
|
181
|
+
o = OrgConverge::Command.new({
|
182
|
+
'<org_file>' => setup_file,
|
183
|
+
'--root-dir' => example_dir,
|
184
|
+
'--runmode' => 'idempotent'
|
185
|
+
})
|
186
|
+
success = o.execute!
|
187
|
+
success.should == true
|
188
|
+
result = File.open("#{example_dir}/installed").read
|
189
|
+
result.should == "package is installed\neof\n"
|
190
|
+
end
|
162
191
|
end
|
data/vagrant.org
ADDED
@@ -0,0 +1,104 @@
|
|
1
|
+
#+TITLE: Vagrant environment setup
|
2
|
+
#+startup: showeverything
|
3
|
+
|
4
|
+
**** Importing the Vagrant keys first
|
5
|
+
|
6
|
+
#+begin_src text :tangle vagrant/.git/info/sparse-checkout :mkdirp true
|
7
|
+
keys
|
8
|
+
#+end_src
|
9
|
+
|
10
|
+
#+name: import-vagrant-keys-done
|
11
|
+
#+begin_src sh :results output
|
12
|
+
[ -e vagrant/keys/vagrant ] && echo "Already cloned"
|
13
|
+
#+end_src
|
14
|
+
|
15
|
+
#+name: import-vagrant-keys
|
16
|
+
#+begin_src sh :unless import-vagrant-keys-done
|
17
|
+
cd vagrant
|
18
|
+
git init
|
19
|
+
git remote add origin https://github.com/mitchellh/vagrant.git
|
20
|
+
git config core.sparsecheckout true
|
21
|
+
git pull origin master
|
22
|
+
git checkout master
|
23
|
+
chmod 0600 keys/vagrant
|
24
|
+
#+end_src
|
25
|
+
|
26
|
+
**** Vagrantfile for Ubuntu 14.04
|
27
|
+
|
28
|
+
#+begin_src ruby :tangle Vagrantfile
|
29
|
+
# -*- mode: ruby -*-
|
30
|
+
# vi: set ft=ruby :
|
31
|
+
|
32
|
+
# Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
|
33
|
+
VAGRANTFILE_API_VERSION = "2"
|
34
|
+
|
35
|
+
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
|
36
|
+
config.vm.box = "ubuntu-14.04-amd64-vbox.box"
|
37
|
+
config.vm.box_url = "https://oss-binaries.phusionpassenger.com/vagrant/boxes/latest/ubuntu-14.04-amd64-vbox.box"
|
38
|
+
|
39
|
+
# config.vm.network :forwarded_port, guest: 80, host: 8080
|
40
|
+
# config.vm.network :private_network, ip: "192.168.33.10"
|
41
|
+
# config.vm.network :public_network
|
42
|
+
# config.ssh.forward_agent = true
|
43
|
+
|
44
|
+
config.vm.provider :virtualbox do |vb|
|
45
|
+
vb.gui = true
|
46
|
+
vb.customize ["modifyvm", :id, "--memory", "1024"]
|
47
|
+
end
|
48
|
+
end
|
49
|
+
#+end_src
|
50
|
+
|
51
|
+
***** Import
|
52
|
+
|
53
|
+
#+name: vagrant-running
|
54
|
+
#+begin_src sh
|
55
|
+
vagrant status
|
56
|
+
#+end_src
|
57
|
+
|
58
|
+
#+name: start_vagrant
|
59
|
+
#+begin_src sh :unless vagrant-running
|
60
|
+
vagrant up
|
61
|
+
#+end_src
|
62
|
+
|
63
|
+
***** Configure
|
64
|
+
|
65
|
+
Install Emacs, Org mode and Org Converge in the VM.
|
66
|
+
|
67
|
+
#+name: running-in-ubuntu
|
68
|
+
#+begin_src sh :results output
|
69
|
+
platform=`uname -a | awk '{print $2}'`
|
70
|
+
if [ $platform == "ubuntu-14" ]; then
|
71
|
+
echo "OK"
|
72
|
+
exit 0
|
73
|
+
else
|
74
|
+
echo "Only works in Ubuntu"
|
75
|
+
exit 1
|
76
|
+
fi
|
77
|
+
#+end_src
|
78
|
+
|
79
|
+
#+name: apt-get-install
|
80
|
+
#+begin_src sh :dir vagrant@localhost:2222/ :if running-in-ubuntu
|
81
|
+
sudo apt-get update
|
82
|
+
sudo apt-get install build-essentials emacs24-nox org-mode -y
|
83
|
+
#+end_src
|
84
|
+
|
85
|
+
**** Vagrantfile :: Docker provider
|
86
|
+
|
87
|
+
#+begin_src ruby :tangle docker/Vagrantfile :mkdirp true
|
88
|
+
Vagrant.configure("2") do |config|
|
89
|
+
config.vm.provider "docker" do |d|
|
90
|
+
d.build_dir = "."
|
91
|
+
end
|
92
|
+
end
|
93
|
+
#+end_src
|
94
|
+
|
95
|
+
#+begin_src conf :tangle docker/Dockerfile
|
96
|
+
FROM ubuntu
|
97
|
+
RUN apt-get -y update
|
98
|
+
RUN apt-get -y install emacs24-nox org-mode
|
99
|
+
#+end_src
|
100
|
+
|
101
|
+
#+name: vagrant-docker-provider
|
102
|
+
#+begin_src sh :dir docker
|
103
|
+
vagrant up --provider=docker
|
104
|
+
#+end_src
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: org-converge
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.14
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Waldemar Quevedo
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-06-
|
11
|
+
date: 2014-06-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: docopt
|
@@ -131,9 +131,11 @@ files:
|
|
131
131
|
- spec/converge_examples/basic_tangle/conf.yml.expected
|
132
132
|
- spec/converge_examples/basic_tangle/setup.org
|
133
133
|
- spec/converge_examples/block_modifiers/run.org
|
134
|
+
- spec/converge_examples/chdir/local-run.org
|
134
135
|
- spec/converge_examples/commented_block/run.org
|
135
136
|
- spec/converge_examples/expected_results/spec.org
|
136
137
|
- spec/converge_examples/expected_results/spec2.org
|
138
|
+
- spec/converge_examples/idempotency/conditions.org
|
137
139
|
- spec/converge_examples/linked_tasks/tasks.org
|
138
140
|
- spec/converge_examples/multi_proc/run.org
|
139
141
|
- spec/converge_examples/runlist_example/setup.org
|
@@ -141,6 +143,7 @@ files:
|
|
141
143
|
- spec/converge_examples/specified_block/run.org
|
142
144
|
- spec/converge_spec.rb
|
143
145
|
- spec/spec_helper.rb
|
146
|
+
- vagrant.org
|
144
147
|
homepage: https://github.com/wallyqs/org-converge
|
145
148
|
licenses: []
|
146
149
|
metadata: {}
|
@@ -170,9 +173,11 @@ test_files:
|
|
170
173
|
- spec/converge_examples/basic_tangle/conf.yml.expected
|
171
174
|
- spec/converge_examples/basic_tangle/setup.org
|
172
175
|
- spec/converge_examples/block_modifiers/run.org
|
176
|
+
- spec/converge_examples/chdir/local-run.org
|
173
177
|
- spec/converge_examples/commented_block/run.org
|
174
178
|
- spec/converge_examples/expected_results/spec.org
|
175
179
|
- spec/converge_examples/expected_results/spec2.org
|
180
|
+
- spec/converge_examples/idempotency/conditions.org
|
176
181
|
- spec/converge_examples/linked_tasks/tasks.org
|
177
182
|
- spec/converge_examples/multi_proc/run.org
|
178
183
|
- spec/converge_examples/runlist_example/setup.org
|