org-converge 0.0.6 → 0.0.7

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/TODO CHANGED
@@ -2,19 +2,28 @@
2
2
  #+TODO: TODO | DONE CANCELED
3
3
  #+startup: showeverything
4
4
 
5
- * [0/8] > 0.0.9 version
5
+ * [0/7] > 0.0.9 version
6
6
 
7
7
  - [ ] Macros can be loaded and applied to the configuration
8
8
  - [ ] Actually support converging and idempotency
9
9
  + Do not do an operation unless it is required
10
10
  + Abort in case there was a failure in executing the script.
11
- - [ ] Support SETUPFILE
11
+ + This would work by using the ~:cache true~ to a block header argument
12
+ - [ ] Support for ~#+SETUPFILE~
12
13
  - [ ] Heuristics for determining which binary to use for running the script
13
14
  - [ ] Display how the run would look like without making changes
14
15
  : org-converge setupfile.org --dry-run
15
16
  - [ ] Use :eval for evaling blocks (off by default)
16
17
  - [ ] Can use :dir for running a process relative to that directory
17
- - [ ] Use rake task manager
18
+
19
+ * [0/1] 0.0.8 version
20
+
21
+ - [ ] ~org-spec~ exploration
22
+
23
+ * [2/2] 0.0.7 version
24
+
25
+ - [X] Add ~org-run~ and ~org-tangle~ aliases
26
+ - [X] Use rake task manager
18
27
 
19
28
  * [3/3] 0.0.6 version
20
29
 
@@ -55,37 +64,36 @@ Need some basic functionality of what Org babel offers first.
55
64
  - [X] ~--tangle~ flag
56
65
  - [X] Support a root dir for when not running relative to the directory
57
66
 
58
- * [3/20] Ideas
59
- ** CANCELED How to set the permissions from the directory from the file that is being tangled when it does not exists?
67
+ * [6/21] Ideas
68
+ ** TODO Chaining resources with ~#+NAME:~ directives and ~:notify~ argument
60
69
 
61
- By default, this would be 0644, but we also need to specify the
62
- user:group of it so the syntax would have to be:
70
+ One idea is to be able to notify resources by naming the code blocks.
63
71
 
64
- #+begin_src conf :tangle etc/something/config/path :chmod 0664 :user td-agent :group
65
- hmm dont't like this syntax for folders
72
+ Example: Here first the td-agent service would try to start,
73
+ and if it succeeds, then it would execute the script defined in the
74
+ ~announce-availability~ resource.
75
+
76
+ #+name: td-agent-start
77
+ #+begin_src sh :notify announce-availability
78
+ sudo service td-agent start
66
79
  #+end_src
67
80
 
68
- Let's keep it simple and just use a babel block that shells out to create the directories
69
- until I can think of something better.
81
+ #+name: announce-availability
82
+ #+begin_src sh
83
+ sudo /etc/register-to-balancer
84
+ #+end_src
85
+
86
+ - Support for ~:before all~ and ~:after all~ added
87
+ ** TODO Add namespace dynamically to the tasks using an in buffer setting
88
+
89
+ When including files there can be some potential scoping issues.
90
+
70
91
  ** TODO Inject macros within the environment variables from a runnable process
71
92
  ** TODO Clarify which ones of the header arguments to implement
72
93
 
73
94
  http://orgmode.org/manual/Specific-header-arguments.html#Specific-header-arguments
74
95
 
75
96
  ** TODO Use sshkit for running remote processes
76
- ** TODO We don't need to create the directories in most cases (:mkdirp yes)
77
-
78
- Something like this is not required because the ~:tangle~ blocks
79
- would create the necessary directories behind the scenes.
80
-
81
- #+begin_src org
82
- ,We need to prepare some directories for the configuration:
83
-
84
- ,#+begin_src converge
85
- ,mkdir -p etc/fluentd/config
86
- ,#+end_src
87
- #+end_src
88
-
89
97
  ** TODO By default, it should use current dir for tangling
90
98
  ** TODO Converging: Only do an operation when it didn't finish
91
99
 
@@ -130,24 +138,26 @@ fluentd:
130
138
 
131
139
  But need to
132
140
 
133
- ** TODO Using the :tags: to setup the things to run right away
141
+ ** TODO Choosing a templating language: default for now is mustache
134
142
 
135
- Kind of like the chef-solo runlist, a headline like this...
143
+ We could implement the macro systems, but it seems that it may not be
144
+ strong enough for providing with all the cases we may run into.
145
+ ** TODO Support caching?
136
146
 
137
- #+begin_src org
138
- ,* Everything in its right place :config:
139
-
140
- ,#+begin_src conf :tangle etc/this.yml
141
- ,hello: "world"
142
- ,#+end_src
147
+ #+begin_src emacs-lisp :cache yes :exports results
148
+ (random)
143
149
  #+end_src
144
150
 
145
- ...could be called like this
151
+ #+RESULTS[db54597aed193d861d01bf92110e10f28f8f40d4]:
152
+ : 842438499349743708
146
153
 
147
- #+begin_src sh
148
- org-converge fluentd.org -t config
154
+ ** TODO Support :eval ?
155
+
156
+ #+begin_src sh :eval (print "Really doing this...")
157
+ echo "Going ahead with operation X!"
149
158
  #+end_src
150
159
 
160
+ ** DONE ~#+NAME:~ could be used in the logger for identifying the process
151
161
  ** DONE Managing dependencies: could be handled with ~#+include~ directives
152
162
 
153
163
  One idea is that it would be useful to compile different manuals
@@ -167,52 +177,58 @@ We should be able to express that dependency somehow:
167
177
 
168
178
  # But one problem, is that once I have included something, sometimes we
169
179
  # will want "reopen" the previous manuals?
180
+ ** DONE We don't need to create the directories in most cases (:mkdirp yes)
170
181
 
171
- ** TODO Loading all the Org mode files first and then setup only one part
182
+ Something like this is not required because the ~:tangle~ blocks
183
+ would create the necessary directories behind the scenes.
172
184
 
173
- So maybe, each one of these tags would have to be namespaces under the
174
- name of the file:
185
+ #+begin_src org
186
+ ,We need to prepare some directories for the configuration:
187
+
188
+ ,#+begin_src converge
189
+ ,mkdir -p etc/fluentd/config
190
+ ,#+end_src
191
+ #+end_src
192
+ ** CANCELED How to set the permissions from the directory from the file that is being tangled when it does not exists?
175
193
 
176
- : org-converge logserver.org -t "fluentd::setup, fluentd::config, logserver::setup"
194
+ By default, this would be 0644, but we also need to specify the
195
+ user:group of it so the syntax would have to be:
177
196
 
178
- ** TODO Choosing a templating language: default for now is mustache
197
+ #+begin_src conf :tangle etc/something/config/path :chmod 0664 :user td-agent :group
198
+ hmm dont't like this syntax for folders
199
+ #+end_src
179
200
 
180
- We could implement the macro systems, but it seems that it may not be
181
- strong enough for providing with all the cases we may run into.
201
+ Let's keep it simple and just use a babel block that shells out to create the directories
202
+ until I can think of something better.
182
203
 
183
- ** TODO Chaining resources with ~#+NAME:~ directives and ~:notify~ argument
204
+ ** CANCELED Using the :tags: to setup the things to run right away
184
205
 
185
- One idea is to be able to notify resources by naming the code blocks.
206
+ Using the block ~#+name~ instead.
186
207
 
187
- Example: Here first the td-agent service would try to start,
188
- and if it succeeds, then it would execute the script defined in the
189
- ~announce-availability~ resource.
208
+ Kind of like the chef-solo runlist, a headline like this...
190
209
 
191
- #+name: td-agent-start
192
- #+begin_src sh :notify announce-availability
193
- sudo service td-agent start
210
+ #+begin_src org
211
+ ,* Everything in its right place :config:
212
+
213
+ ,#+begin_src conf :tangle etc/this.yml
214
+ ,hello: "world"
215
+ ,#+end_src
194
216
  #+end_src
195
217
 
196
- #+name: announce-availability
218
+ ...could be called like this
219
+
197
220
  #+begin_src sh
198
- sudo /etc/register-to-balancer
221
+ org-converge fluentd.org -t config
199
222
  #+end_src
200
223
 
201
- ** DONE ~#+NAME:~ could be used in the logger for identifying the process
202
- ** TODO Support caching?
203
-
204
- #+begin_src emacs-lisp :cache yes :exports results
205
- (random)
206
- #+end_src
224
+ ** CANCELED Loading all the Org mode files first and then setup only one part
207
225
 
208
- #+RESULTS[db54597aed193d861d01bf92110e10f28f8f40d4]:
209
- : 842438499349743708
226
+ Used ~#+name~ from blocks instead.
210
227
 
211
- ** TODO Support :eval ?
228
+ So maybe, each one of these tags would have to be namespaces under the
229
+ name of the file:
212
230
 
213
- #+begin_src sh :eval (print "Really doing this...")
214
- echo "Going ahead with operation X!"
215
- #+end_src
231
+ : org-converge logserver.org -t "fluentd::setup, fluentd::config, logserver::setup"
216
232
 
217
233
  * Links
218
234
 
data/bin/org-converge CHANGED
@@ -8,7 +8,7 @@ doc = <<OPTIONS
8
8
  org-converge: A light configuration management tool for Org mode
9
9
 
10
10
  Usage:
11
- org-converge <org_file> [--tangle] [--showfiles] [--log=<logfile>] [--root-dir=<root_dir>] [--runmode=<runmode>] [--name=<block_name>]
11
+ org-converge <org_file> [--showfiles] [--log=<logfile>] [--root-dir=<root_dir>] [--runmode=<runmode>] [--name=<block_name>]
12
12
 
13
13
  Options:
14
14
 
data/bin/org-run ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+ # -*- mode: ruby -*-
3
+
4
+ # alias for org-converge
5
+ load File.expand_path('../org-converge', __FILE__)
data/bin/org-tangle ADDED
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env ruby
2
+ # -*- mode: ruby -*-
3
+ require 'docopt'
4
+ require 'org-converge'
5
+
6
+ doc = <<OPTIONS
7
+
8
+ org-tangle: Org babel tangling feature using the Org mode Ruby parser
9
+
10
+ Usage:
11
+ org-tangle <org_file> [--showfiles] [--log=<logfile>] [--root-dir=<root_dir>]
12
+
13
+ Options:
14
+
15
+ -h --help Show this screen.
16
+
17
+ OPTIONS
18
+
19
+ begin
20
+ require "pp"
21
+ cmd = Docopt::docopt(doc)
22
+ rescue Docopt::Exit => e
23
+ puts e.message
24
+ end
25
+
26
+ exit 1 unless cmd
27
+
28
+ o = OrgConverge::Command.new(cmd.merge({'--tangle' => true }))
29
+ o.execute!
@@ -1,3 +1,5 @@
1
+ require 'rake'
2
+
1
3
  module Orgmode
2
4
  class BabelOutputBuffer < OutputBuffer
3
5
  attr_reader :tangle
@@ -11,11 +13,21 @@ module Orgmode
11
13
 
12
14
  # ~@tangle~ files are put in the right path
13
15
  # : @tangle['/path'] = [Lines]
14
- @tangle = Hash.new {|h,k| h[k] = {:lines => '', :header => {}, :lang => ''}}
16
+ @tangle = Hash.new {|h,k| h[k] = {
17
+ :lines => '',
18
+ :header => {},
19
+ :lang => ''
20
+ }
21
+ }
15
22
 
16
23
  # ~@scripts~ are tangled in order and ran
17
24
  # : @scripts = [text, text, ...]
18
- @scripts = Hash.new {|h,k| h[k] = {:lines => '', :header => {}, :lang => ''}}
25
+ @scripts = Hash.new {|h,k| h[k] = {
26
+ :lines => '',
27
+ :header => {},
28
+ :lang => ''
29
+ }
30
+ }
19
31
  @scripts_counter = 0
20
32
  @buffer = ''
21
33
  end
@@ -50,7 +62,9 @@ module Orgmode
50
62
  @scripts[@scripts_counter][:header] = {
51
63
  :shebang => line.block_header_arguments[':shebang'],
52
64
  :mkdirp => line.block_header_arguments[':mkdirp'],
53
- :name => line.properties['block_name']
65
+ :name => line.properties['block_name'],
66
+ :before => line.block_header_arguments[':before'],
67
+ :after => line.block_header_arguments[':after']
54
68
  }
55
69
  @scripts[@scripts_counter][:lang] = line.block_lang
56
70
  # TODO: have a way to specify which are the default binaries to be used per language
@@ -58,8 +58,8 @@ module OrgConverge
58
58
  run_blocks_in_parallel!
59
59
  when 'sequential'
60
60
  run_blocks_sequentially!
61
- when 'runlist'
62
- # TODO
61
+ when 'chained', 'chain', 'tasks'
62
+ run_blocks_chain!
63
63
  else # parallel by default
64
64
  run_blocks_in_parallel!
65
65
  end
@@ -71,6 +71,53 @@ module OrgConverge
71
71
  logger.error "Cannot converge because there were errors during tangle step".fg 'red'
72
72
  end
73
73
 
74
+ def run_blocks_chain!
75
+ # Chain the blocks by defining them as Rake::Tasks dynamically
76
+ tasks = { }
77
+
78
+ babel.tangle_runnable_blocks!(@run_dir)
79
+ babel.ob.scripts.each do |key, script|
80
+ task_name = script[:header][:name]
81
+ next unless task_name
82
+
83
+ task = Rake::Task.define_task task_name do
84
+ with_running_engine do |engine|
85
+ file = File.expand_path("#{@run_dir}/#{key}")
86
+ cmd = "#{script[:lang]} #{file}"
87
+ engine.register task_name, cmd, { :cwd => @root_dir, :logger => logger }
88
+ end
89
+ end
90
+ tasks[task_name] = {
91
+ :task => task,
92
+ :script => script
93
+ }
94
+ end
95
+
96
+ # Now onto define the prerequisites and actions
97
+ tasks.each_pair do |task_name, task_definition|
98
+ prerequisite_task = task_definition[:script][:header][:after]
99
+ if prerequisite_task and tasks[prerequisite_task]
100
+ task_definition[:task].prerequisites << tasks[prerequisite_task][:task]
101
+ end
102
+
103
+ postrequisite_task = task_definition[:script][:header][:before]
104
+ if postrequisite_task and tasks[postrequisite_task]
105
+ tasks[postrequisite_task][:task].prerequisites << task_definition[:task]
106
+ end
107
+ end
108
+
109
+ # The task that marks the run as done needs to be defined explicitly
110
+ # otherwise a block named default will tried to be run
111
+ final_task = babel.ob.in_buffer_settings['FINAL_TASK'] || 'default'
112
+
113
+ if tasks[final_task]
114
+ logger.info "Running final task: #{tasks[final_task][:task]}"
115
+ tasks[final_task][:task].invoke
116
+ else
117
+ logger.error "Could not find a final task to run!"
118
+ end
119
+ end
120
+
74
121
  def run_blocks_sequentially!
75
122
  @engine = OrgConverge::Engine.new(:logger => @logger, :babel => @babel)
76
123
  babel.tangle_runnable_blocks!(@run_dir)
@@ -96,8 +143,6 @@ module OrgConverge
96
143
  logger.info "Run has completed successfully.".fg 'green'
97
144
  end
98
145
 
99
- # TODO: Too much foreman has made this running blocks in parallel the default behavior.
100
- # We should actually be supporting run lists instead, but liking this experiment so far.
101
146
  def run_blocks_in_parallel!
102
147
  @engine = OrgConverge::Engine.new(:logger => @logger, :babel => @babel)
103
148
  babel.tangle_runnable_blocks!(@run_dir)
@@ -1,3 +1,3 @@
1
1
  module OrgConverge
2
- VERSION = "0.0.6"
2
+ VERSION = "0.0.7"
3
3
  end
data/org-converge.gemspec CHANGED
@@ -14,8 +14,9 @@ Gem::Specification.new do |gem|
14
14
  gem.name = "org-converge"
15
15
  gem.require_paths = ["lib"]
16
16
  gem.version = OrgConverge::VERSION
17
- gem.add_runtime_dependency('docopt', '0.5.0')
18
- gem.add_runtime_dependency('org-ruby', '~> 0.9.4')
19
- gem.add_runtime_dependency('foreman', '~> 0.63.0')
20
- gem.add_runtime_dependency('tco', '~> 0.1.0')
17
+ gem.add_runtime_dependency('docopt', '~> 0.5.0')
18
+ gem.add_runtime_dependency('org-ruby', '~> 0.9.5')
19
+ gem.add_runtime_dependency('foreman', '~> 0.63.0')
20
+ gem.add_runtime_dependency('tco', '~> 0.1.0')
21
+ gem.add_runtime_dependency('rake', '~> 10.3')
21
22
  end
@@ -0,0 +1,43 @@
1
+ #+TITLE: Linked tasks example
2
+ #+runmode: tasks
3
+ #+final_task: final
4
+
5
+ The goal here is to be able to define dependencies
6
+ among blocks and run the correctly in that order.
7
+
8
+ With ~:after first~, the ~second~ block becomes
9
+ a prerequisite of the ~first~ block.
10
+
11
+ #+name: second
12
+ #+begin_src sh :after first
13
+ for i in `seq 5 10`; do
14
+ echo $i >> out.log
15
+ done
16
+ #+end_src
17
+
18
+ #+name: first
19
+ #+begin_src ruby
20
+ 5.times { |n| File.open("out.log", "a") {|f| f.puts n } }
21
+ #+end_src
22
+
23
+ Using ~:after all~ is special, since it means that the task
24
+ depends on everything else having run already.
25
+
26
+ #+name: final
27
+ #+begin_src python :after second :results output
28
+ print "Wrapping up with Python in the end"
29
+ f = open('out.log', 'a')
30
+ f.write('11')
31
+ f.close()
32
+ #+end_src
33
+
34
+ The same with ~:before all~, this would be executed
35
+ at the beginning.
36
+
37
+ #+name: prologue
38
+ #+begin_src sh :before first :results output
39
+ echo "init" > out.log
40
+ #+end_src
41
+
42
+ Note: Both ~:before all~ and ~:after all~ get accumulated
43
+ and are run sequentially after that.
@@ -85,4 +85,24 @@ describe OrgConverge::Command do
85
85
  expected_contents = "first\nsecond\n"
86
86
  File.read(File.join(example_dir, 'out.log')).should == expected_contents
87
87
  end
88
+
89
+ it "should run 'linked_tasks' in order" do
90
+ example_dir = File.join(EXAMPLES_DIR, 'linked_tasks')
91
+ setup_file = File.join(example_dir, 'tasks.org')
92
+
93
+ o = OrgConverge::Command.new({
94
+ '<org_file>' => setup_file,
95
+ '--root-dir' => example_dir
96
+ })
97
+ success = o.execute!
98
+ success.should == true
99
+
100
+ File.executable?(File.join(example_dir, 'run/0')).should == true
101
+ File.executable?(File.join(example_dir, 'run/1')).should == true
102
+ File.executable?(File.join(example_dir, 'run/2')).should == true
103
+ File.executable?(File.join(example_dir, 'run/3')).should == true
104
+
105
+ expected_contents = "init\n0\n1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11"
106
+ File.read(File.join(example_dir, 'out.log')).should == expected_contents
107
+ end
88
108
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: org-converge
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.6
4
+ version: 0.0.7
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,33 +9,33 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-05-03 00:00:00.000000000 Z
12
+ date: 2014-05-04 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: docopt
16
- requirement: &70130002051260 !ruby/object:Gem::Requirement
16
+ requirement: &70254668243000 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
- - - =
19
+ - - ~>
20
20
  - !ruby/object:Gem::Version
21
21
  version: 0.5.0
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70130002051260
24
+ version_requirements: *70254668243000
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: org-ruby
27
- requirement: &70130002050780 !ruby/object:Gem::Requirement
27
+ requirement: &70254668242520 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ~>
31
31
  - !ruby/object:Gem::Version
32
- version: 0.9.4
32
+ version: 0.9.5
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *70130002050780
35
+ version_requirements: *70254668242520
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: foreman
38
- requirement: &70130002050320 !ruby/object:Gem::Requirement
38
+ requirement: &70254664800460 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ~>
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: 0.63.0
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *70130002050320
46
+ version_requirements: *70254664800460
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: tco
49
- requirement: &70130002049860 !ruby/object:Gem::Requirement
49
+ requirement: &70254664799380 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ~>
@@ -54,12 +54,25 @@ dependencies:
54
54
  version: 0.1.0
55
55
  type: :runtime
56
56
  prerelease: false
57
- version_requirements: *70130002049860
57
+ version_requirements: *70254664799380
58
+ - !ruby/object:Gem::Dependency
59
+ name: rake
60
+ requirement: &70254664798160 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ~>
64
+ - !ruby/object:Gem::Version
65
+ version: '10.3'
66
+ type: :runtime
67
+ prerelease: false
68
+ version_requirements: *70254664798160
58
69
  description: A light configuration management tool for Org mode
59
70
  email:
60
71
  - waldemar.quevedo@gmail.com
61
72
  executables:
62
73
  - org-converge
74
+ - org-run
75
+ - org-tangle
63
76
  extensions: []
64
77
  extra_rdoc_files: []
65
78
  files:
@@ -71,6 +84,8 @@ files:
71
84
  - Rakefile
72
85
  - TODO
73
86
  - bin/org-converge
87
+ - bin/org-run
88
+ - bin/org-tangle
74
89
  - examples/apt-get-install/setup.org
75
90
  - examples/fluentd/setup.org
76
91
  - examples/macro-config/setup.org
@@ -86,6 +101,7 @@ files:
86
101
  - spec/converge_examples/basic_tangle/conf.yml.expected
87
102
  - spec/converge_examples/basic_tangle/setup.org
88
103
  - spec/converge_examples/commented_block/run.org
104
+ - spec/converge_examples/linked_tasks/tasks.org
89
105
  - spec/converge_examples/runlist_example/setup.org
90
106
  - spec/converge_examples/specified_block/run.org
91
107
  - spec/converge_spec.rb
@@ -120,6 +136,7 @@ test_files:
120
136
  - spec/converge_examples/basic_tangle/conf.yml.expected
121
137
  - spec/converge_examples/basic_tangle/setup.org
122
138
  - spec/converge_examples/commented_block/run.org
139
+ - spec/converge_examples/linked_tasks/tasks.org
123
140
  - spec/converge_examples/runlist_example/setup.org
124
141
  - spec/converge_examples/specified_block/run.org
125
142
  - spec/converge_spec.rb