ansible-powerplay 0.2.4 → 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/RELEASE_NOTES.org CHANGED
@@ -7,39 +7,48 @@
7
7
  major number. Of course, you can read all about it here.
8
8
 
9
9
  ** Release Notes
10
- | Release | Feature / Bug | Description | Date |
11
- |---------+----------------------------------+------------------------------------------------------------------------------------+------------|
12
- | v0.2.3 | --verbose | Will display Ansible commands on a --verbosity=1 or higher. | 2016-03-17 |
13
- | v0.2.2 | --tags, --skip-tags | Ansible tag support | 2016-03-07 |
14
- | v0.2.1 | --extra-vars | A way of passing extra vars to the Ansible playbooks. Please see the documentation | 2016-03-01 |
15
- | v0.2.0 | powerplay play (behavior change) | If script is not given, now defaults to 'stack.play' in the current directory. | 2016-02-29 |
16
- | v0.1.3 | --tmux | Better handling at distributing the panes. | 2016-02-26 |
17
- | v0.1.2 | --tmux. --no-tmux | Default output now goes to current tty | 2016-02-23 |
18
- | v0.1.1 | --book, --group, --play | Minor bug with the array handling | 2016-02-22 |
19
- | v0.1.0 | --book, --group, --play | Now each can take multiple specifications | 2016-02-22 |
20
- | v0.0.8 | Creation of these Release Notes | About bloody time. The prior releases were all mostly bug fixes, and so... | 2016-02-20 |
21
- | | --tmux | Now you can optionally specify the window number | |
22
- | | --tmux | Now checks to ensure it does not dump to its own pane | |
23
- | | --book | You can select an individual playbook to run | |
24
- | | --group | You can select an individual group to run | |
25
-
10
+ | Release | Feature / Bug | Description | Date |
11
+ |---------+----------------------------------------+-----------------------------------------------------------------------------------------------+------------|
12
+ | v1.0.0 | version | Prints version | 2061-06-04 |
13
+ | | powerplay / pp shorthand command | Play task defaults if you use the shorthand 'pp' on the commandline | 2061-06-04 |
14
+ | | DSL incompatible changes | Nestable groups, naked books. older DSL not gauranteed to be compatable. | |
15
+ | | Internal rewrite of the execution flow | Logic for execution flow rewritten to allow fine-grained control over what is sync and async. | |
16
+ | | Internal NOOP books | We need to demarcate groups executing synchronously that they themselves have async members. | |
17
+ | v0.2.3 | --verbose | Will display Ansible commands on a --verbosity=1 or higher. | 2016-03-17 |
18
+ | v0.2.2 | --tags, --skip-tags | Ansible tag support | 2016-03-07 |
19
+ | v0.2.1 | --extra-vars | A way of passing extra vars to the Ansible playbooks. Please see the documentation | 2016-03-01 |
20
+ | v0.2.0 | powerplay play (behavior change) | If script is not given, now defaults to 'stack.play' in the current directory. | 2016-02-29 |
21
+ | v0.1.3 | --tmux | Better handling at distributing the panes. | 2016-02-26 |
22
+ | v0.1.2 | --tmux. --no-tmux | Default output now goes to current tty | 2016-02-23 |
23
+ | v0.1.1 | --book, --group, --play | Minor bug with the array handling | 2016-02-22 |
24
+ | v0.1.0 | --book, --group, --play | Now each can take multiple specifications | 2016-02-22 |
25
+ | v0.0.8 | Creation of these Release Notes | About bloody time. The prior releases were all mostly bug fixes, and so... | 2016-02-20 |
26
+ | | --tmux | Now you can optionally specify the window number | |
27
+ | | --tmux | Now checks to ensure it does not dump to its own pane | |
28
+ | | --book | You can select an individual playbook to run | |
29
+ | | --group | You can select an individual group to run | |
26
30
 
27
31
  ** Known Outstanding Issues
28
32
  Bugs and missing features that needs to be addressed. As they are,
29
33
  we'll remove them from this list.
30
34
  | Date | Issue | Description |
31
35
  |------------+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------|
36
+ | 2016-06-05 | version | Command does not work properly. It hangs. |
37
+ | 2016-04-07 | --extra-vars | Powerplay duplicates keys on extra vars if already specified in the Powerplay. |
38
+ | 2016-03-11 | Grouping | Groups executes in parallel instead of serially. |
39
+ | | Core | Core process flow needs to be redone. |
32
40
  | 2016-03-03 | Status dump out of order | Currently a bit out of order due to the fact that the output are being run in different threads and so the text is being printed nondeterministically. |
33
41
  | 2016-02-20 | Platforms other than Linux | We need to test on Mac OSX and Windows. Should work fine on Macs. I do not plan to support Windows in general, but may accept pull requests to that end. |
34
42
 
35
43
  ** Wish List
36
- Well, we can always wish upon a star...
37
- | Date | Wish | Description |
38
- |------------+---------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
39
- | 2016-02-20 | Integration with Jenkins | I have no idea what form this will take |
40
- | | Curses integration | Basically, the tmux integration is used because it was quick to do. But what I really want to do is full Curses support, similar with what you see with htop and other tools. |
41
- | 2016-02-26 | Better and Error handling | When there's a failure in the underlying Ansible playbook, we want to handle that better in Powerplay. This would be a part of the Curses upgrade to come later. |
42
- | 2016-02-29 | Configuration file | Add a (presumably yaml format) configuration file in a few key locations. |
43
- | | Name Completion | Shell integration with name completion features of bash. |
44
- | 2016-03-03 | DSL subgroup | We need to subgroup books within a group to make it easier to launch them specifically. |
45
- | | | |
44
+ Well, we can always wish upon a star... but it will take
45
+ my time and dedication to make stars happen. :p
46
+
47
+ | Date | Wish | Description | |
48
+ |------------+-------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---|
49
+ | 2016-06-04 | Verbosity to ansible-playbook | Being able to pass in the -v flag to ansible. From pp, a -v2, for example, would be the equivalent of -vv to ansible-playbook. | |
50
+ | 2016-02-20 | Integration with Jenkins | I have no idea what form this will take | |
51
+ | | Curses integration | Basically, the tmux integration is used because it was quick to do. But what I really want to do is full Curses support, similar with what you see with htop and other tools. | |
52
+ | 2016-02-26 | Better and Error handling | When there's a failure in the underlying Ansible playbook, we want to handle that better in Powerplay. This would be a part of the Curses upgrade to come later. | |
53
+ | 2016-02-29 | Configuration file | Add a (presumably yaml format) configuration file in a few key locations. | |
54
+ | | Name Completion | Shell integration with name completion features of bash. | |
data/SCRATCHPAD.org CHANGED
@@ -10,3 +10,9 @@
10
10
  tmux list-panes -F '#{pane_id} #{pane_tty} #{pane_right} #{pane_left} #{pane_top} #{pane_bottom}'
11
11
  #+END_SRC
12
12
 
13
+ ** PowerPlay command for testing
14
+ #+BEGIN_SRC bash
15
+ cd examples/
16
+ ../bin/powerplay play -p development -v1 -u
17
+ #+END_SRC
18
+
@@ -2,19 +2,19 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Juwelier::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: ansible-powerplay 0.2.4 ruby lib
5
+ # stub: ansible-powerplay 1.0.2 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "ansible-powerplay"
9
- s.version = "0.2.4"
9
+ s.version = "1.0.2"
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
12
  s.require_paths = ["lib"]
13
13
  s.authors = ["Fred Mitchell"]
14
- s.date = "2016-03-25"
14
+ s.date = "2016-06-05"
15
15
  s.description = "Ansible Powerplay, by way of its DSL, allows you to\n specify your Ansible playbooks and their vars, and common\n vars to all, so that you can run your\n indeoendent playbooks in full parallel."
16
16
  s.email = "fred.mitchell@gmx.de"
17
- s.executables = ["powerplay"]
17
+ s.executables = ["powerplay", "pp"]
18
18
  s.extra_rdoc_files = [
19
19
  "LICENSE.txt",
20
20
  "README.org"
@@ -33,6 +33,14 @@ Gem::Specification.new do |s|
33
33
  "SCRATCHPAD.org",
34
34
  "ansible-powerplay.gemspec",
35
35
  "bin/powerplay",
36
+ "bin/pp",
37
+ "examples/playbooks/dat.yml",
38
+ "examples/playbooks/elasticseach.yml",
39
+ "examples/playbooks/first.yml",
40
+ "examples/playbooks/nat.yml",
41
+ "examples/playbooks/rabbitmq.yml",
42
+ "examples/playbooks/rat.yml",
43
+ "examples/playbooks/second.yml",
36
44
  "lib/ansible-powerplay.rb",
37
45
  "lib/ansible-powerplay/cli.rb",
38
46
  "lib/ansible-powerplay/dsl.rb",
@@ -51,10 +59,11 @@ Gem::Specification.new do |s|
51
59
 
52
60
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
53
61
  s.add_runtime_dependency(%q<thor>, ["~> 0"])
54
- s.add_runtime_dependency(%q<concurrent-ruby>, [">= 0"])
55
- s.add_runtime_dependency(%q<term-ansicolor>, [">= 0"])
62
+ s.add_runtime_dependency(%q<term-ansicolor>, ["~> 1"])
56
63
  s.add_runtime_dependency(%q<colorize>, ["~> 0"])
57
64
  s.add_runtime_dependency(%q<semver>, ["~> 1"])
65
+ s.add_runtime_dependency(%q<queue_ding>, ["~> 0"])
66
+ s.add_runtime_dependency(%q<concurrent-ruby>, ["~> 1"])
58
67
  s.add_development_dependency(%q<rspec>, ["~> 2"])
59
68
  s.add_development_dependency(%q<yard>, ["~> 0"])
60
69
  s.add_development_dependency(%q<rdoc>, ["~> 3"])
@@ -71,10 +80,11 @@ Gem::Specification.new do |s|
71
80
  s.add_development_dependency(%q<pry-stack_explorer>, ["~> 0"])
72
81
  else
73
82
  s.add_dependency(%q<thor>, ["~> 0"])
74
- s.add_dependency(%q<concurrent-ruby>, [">= 0"])
75
- s.add_dependency(%q<term-ansicolor>, [">= 0"])
83
+ s.add_dependency(%q<term-ansicolor>, ["~> 1"])
76
84
  s.add_dependency(%q<colorize>, ["~> 0"])
77
85
  s.add_dependency(%q<semver>, ["~> 1"])
86
+ s.add_dependency(%q<queue_ding>, ["~> 0"])
87
+ s.add_dependency(%q<concurrent-ruby>, ["~> 1"])
78
88
  s.add_dependency(%q<rspec>, ["~> 2"])
79
89
  s.add_dependency(%q<yard>, ["~> 0"])
80
90
  s.add_dependency(%q<rdoc>, ["~> 3"])
@@ -92,10 +102,11 @@ Gem::Specification.new do |s|
92
102
  end
93
103
  else
94
104
  s.add_dependency(%q<thor>, ["~> 0"])
95
- s.add_dependency(%q<concurrent-ruby>, [">= 0"])
96
- s.add_dependency(%q<term-ansicolor>, [">= 0"])
105
+ s.add_dependency(%q<term-ansicolor>, ["~> 1"])
97
106
  s.add_dependency(%q<colorize>, ["~> 0"])
98
107
  s.add_dependency(%q<semver>, ["~> 1"])
108
+ s.add_dependency(%q<queue_ding>, ["~> 0"])
109
+ s.add_dependency(%q<concurrent-ruby>, ["~> 1"])
99
110
  s.add_dependency(%q<rspec>, ["~> 2"])
100
111
  s.add_dependency(%q<yard>, ["~> 0"])
101
112
  s.add_dependency(%q<rdoc>, ["~> 3"])
data/bin/powerplay CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  PP_PATH = File.expand_path '..', File.dirname(__FILE__)
4
4
  PP_EXECUTABLE = File.expand_path 'bin/powerplay', Dir.pwd
5
+ $PP_BASENAME = File.basename(__FILE__)
5
6
 
6
7
  $:.unshift File.join([PP_PATH, 'lib'])
7
8
 
data/bin/pp ADDED
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ PP_PATH = File.expand_path '..', File.dirname(__FILE__)
4
+ PP_EXECUTABLE = File.expand_path 'bin/powerplay', Dir.pwd
5
+ $PP_BASENAME = File.basename(__FILE__)
6
+
7
+ $:.unshift File.join([PP_PATH, 'lib'])
8
+
9
+ require 'ansible-powerplay/cli'
10
+
11
+ Powerplay::Cli::Main.start
@@ -0,0 +1,15 @@
1
+ ---
2
+ - hosts: local
3
+ connection: local
4
+ gather_facts: False
5
+ tasks:
6
+ - name: setting a fact
7
+ set_fact:
8
+ nat:
9
+ - { 00 : dat, 01 : hello, 02 : world }
10
+ - name: test fact and passed in variables
11
+ debug:
12
+ msg: "DAT test {{nat}} stack {{stack}} AWS instance type {{aws_type}} AWS disk size {{aws_disk_size}}"
13
+ - name: wait 5 seconds
14
+ pause:
15
+ seconds: 5
@@ -0,0 +1,15 @@
1
+ ---
2
+ - hosts: local
3
+ connection: local
4
+ gather_facts: False
5
+ tasks:
6
+ - name: setting a fact
7
+ set_fact:
8
+ nat:
9
+ - { 00 : elasticsearch, 01 : hello, 02 : world }
10
+ - name: test fact and passed in variables
11
+ debug:
12
+ msg: "elasticsearch test {{nat}} stack {{stack}} AWS instance type {{aws_type}} AWS disk size {{aws_disk_size}}"
13
+ - name: wait 5 seconds
14
+ pause:
15
+ seconds: 5
@@ -0,0 +1,15 @@
1
+ ---
2
+ - hosts: local
3
+ connection: local
4
+ gather_facts: False
5
+ tasks:
6
+ - name: setting a fact
7
+ set_fact:
8
+ nat:
9
+ - { 00 : first, 01 : hello, 02 : world }
10
+ - name: test fact and passed in variables
11
+ debug:
12
+ msg: "first test {{nat}} stack {{stack}} AWS instance type {{aws_type}} AWS disk size {{aws_disk_size}}"
13
+ - name: wait 5 seconds
14
+ pause:
15
+ seconds: 5
@@ -0,0 +1,15 @@
1
+ ---
2
+ - hosts: local
3
+ connection: local
4
+ gather_facts: False
5
+ tasks:
6
+ - name: setting a fact
7
+ set_fact:
8
+ nat:
9
+ - { 00 : nat, 01 : hello, 02 : world }
10
+ - name: test fact and passed in variables
11
+ debug:
12
+ msg: "NAT test {{nat}} stack {{stack}} AWS instance type {{aws_type}} AWS disk size {{aws_disk_size}}"
13
+ - name: wait 5 seconds
14
+ pause:
15
+ seconds: 5
@@ -0,0 +1,15 @@
1
+ ---
2
+ - hosts: local
3
+ connection: local
4
+ gather_facts: False
5
+ tasks:
6
+ - name: setting a fact
7
+ set_fact:
8
+ nat:
9
+ - { 00 : rabbitmq, 01 : hello, 02 : world }
10
+ - name: test fact and passed in variables
11
+ debug:
12
+ msg: "rabbitmq test {{nat}} stack {{stack}} AWS instance type {{aws_type}} AWS disk size {{aws_disk_size}}"
13
+ - name: wait 5 seconds
14
+ pause:
15
+ seconds: 5
@@ -0,0 +1,15 @@
1
+ ---
2
+ - hosts: local
3
+ connection: local
4
+ gather_facts: False
5
+ tasks:
6
+ - name: setting a fact
7
+ set_fact:
8
+ nat:
9
+ - { 00 : rat, 01 : hello, 02 : world }
10
+ - name: test fact and passed in variables
11
+ debug:
12
+ msg: "RAT test {{nat}} stack {{stack}} AWS instance type {{aws_type}} AWS disk size {{aws_disk_size}}"
13
+ - name: wait 5 seconds
14
+ pause:
15
+ seconds: 5
@@ -0,0 +1,15 @@
1
+ ---
2
+ - hosts: local
3
+ connection: local
4
+ gather_facts: False
5
+ tasks:
6
+ - name: setting a fact
7
+ set_fact:
8
+ nat:
9
+ - { 00 : second, 01 : hello, 02 : world }
10
+ - name: test fact and passed in variables
11
+ debug:
12
+ msg: "second test {{nat}} stack {{stack}} AWS instance type {{aws_type}} AWS disk size {{aws_disk_size}}"
13
+ - name: wait 5 seconds
14
+ pause:
15
+ seconds: 5
@@ -4,5 +4,15 @@ require 'pp'
4
4
  require 'open3'
5
5
  require 'thread'
6
6
  require 'colorize'
7
+ require 'queue_ding'
8
+
9
+ def s_version
10
+ SemVer.find.format "v%M.%m.%p%s"
11
+ end
12
+
13
+ include QueueDing
14
+
7
15
  require_relative 'ansible-powerplay/powerplay'
8
16
  require_relative 'ansible-powerplay/dsl'
17
+ require_relative 'ansible-powerplay/cli'
18
+
@@ -23,7 +23,6 @@ module Powerplay
23
23
  desc: 'Which PowerPlay playbooks (as opposed to Ansible playbooks) to specifically execute.'
24
24
  option :group, type: :array, aliases: '-g', banner: "[NAME[ NAME2...]|all]", default: [:all],
25
25
  desc: ' Which groups to execute.'
26
- option :congroups, type: :boolean, aliases: '-c', desc: "Run the groups themselves concurrently"
27
26
  option :book, type: :array, aliases: '-b', banner: "[NAME[ NAME2...]|all]", default: [:all],
28
27
  desc: 'Which books to execute.'
29
28
  option :dryrun, type: :boolean, aliases: '-u', desc: "Dry run, do not actually execute."
@@ -40,9 +39,44 @@ module Powerplay
40
39
  DSL::_global[:options] = massage options
41
40
  puts "script %s " % [script] if DSL::_global[:options][:verbose] >= 1
42
41
  load script, true
43
- pp DSL::_global if DSL::_verbosity >= 3
42
+
43
+ if DSL::_verbosity >= 3
44
+ puts "\n*** PLANNING FIFO QUEUE:".green
45
+ puts DSL::_planning.map{ |book|
46
+ [book.type, book.plan, book.yaml, book.family.map{|g| ":#{g}" }.join(' < ')]
47
+ }.map{ |t,p,y,f|
48
+ unless t == :noop
49
+ ":#{t}".light_yellow
50
+ else
51
+ ":#{t}".red
52
+ end +
53
+ unless p == :async
54
+ "\t :#{p}".light_cyan
55
+ else
56
+ "\t :#{p}".light_red
57
+ end +
58
+ "\t #{y}".magenta +
59
+ "\t #{f}".light_black
60
+ }
61
+ puts
62
+ end
63
+
64
+ if DSL::_verbosity >= 4
65
+ puts "\n**** PARSE TREE & GLOBAL OBJECTS:".green
66
+ pp DSL::_global
67
+
68
+ puts "\n**** PLANNING FIFO QUEUE DETAILS:".green
69
+ pp DSL::_planning
70
+ end
71
+
44
72
  Play::Ansible::power_run
45
73
  end
74
+ default_task :play if $PP_BASENAME == 'pp'
75
+
76
+ desc 'version', 'display the version of this PowerPlay install'
77
+ def version
78
+ puts s_version
79
+ end
46
80
 
47
81
  desc 'ttys', 'list all the TMUX ptys on the current window.'
48
82
  def ttys
@@ -3,16 +3,21 @@ module Powerplay
3
3
  module DSL
4
4
  @@config_stack = [{}]
5
5
  @@global_config = {}
6
+ @@planning_queue = []
7
+
6
8
  SPECIAL_PARAMS = [:playbook_directory, :inventory]
7
9
 
10
+ # bump the config stack because we are in a child node context
8
11
  def _bump
9
12
  @@config_stack.push @@config_stack.last.clone
10
13
  end
11
14
 
15
+ # pop the config stack, as we have left the child node context
12
16
  def _dip
13
17
  @@config_stack.pop
14
18
  end
15
19
 
20
+ # Get the current config
16
21
  def _config
17
22
  @@config_stack.last
18
23
  end
@@ -25,6 +30,27 @@ module Powerplay
25
30
  _global[:options][:verbose]
26
31
  end
27
32
 
33
+ def _enqueue book
34
+ @@planning_queue << book
35
+ end
36
+
37
+ def _dequeue
38
+ @@planning_queue.shift
39
+ end
40
+
41
+ def _peek
42
+ @@planning_queue.first
43
+ end
44
+
45
+ def _sneak
46
+ @@planning_queue.last
47
+ end
48
+
49
+ # do NOT modify this directly. use the API above.
50
+ def _planning
51
+ @@planning_queue
52
+ end
53
+
28
54
  class Dsl
29
55
  attr :config, :type, :desc
30
56
 
@@ -40,6 +66,11 @@ module Powerplay
40
66
  @config[type] = DslConfiguration.new(type, desc, &block).config
41
67
  end
42
68
 
69
+ def book(type, yaml, desc: nil, plan: :sync, &block)
70
+ @books ||= []
71
+ _enqueue DslBook.new(type, yaml, desc: desc, plan: plan, &block)
72
+ end
73
+
43
74
  def initialize(type, desc, &ignore)
44
75
  @type = type
45
76
  @desc = desc
@@ -55,12 +86,15 @@ module Powerplay
55
86
  end
56
87
  end
57
88
 
89
+ # we do allow for noop books
58
90
  class DslBook < Dsl
59
- attr :yaml
91
+ attr :yaml, :plan, :group
60
92
 
61
- def initialize(type, yaml, desc=nil, &block)
93
+ def initialize(type, yaml, desc: nil, plan: nil, group: nil, &block)
62
94
  super(type, desc, &block)
63
95
  @yaml = yaml
96
+ @plan = plan
97
+ @group = group
64
98
  _bump
65
99
  instance_eval(&block) if block_given?
66
100
  @config = _dip
@@ -72,30 +106,60 @@ module Powerplay
72
106
  "#{k}=#{v.first}" unless DSL::SPECIAL_PARAMS.member?(k)
73
107
  }.compact.join(' ')
74
108
  end
109
+
110
+ def family
111
+ unless @group.nil?
112
+ @group.family
113
+ else
114
+ []
115
+ end
116
+ end
75
117
  end
76
118
 
77
119
  class DslGroup < Dsl
78
- attr :books
120
+ # The entries here may either be books or groups.
121
+ attr_reader :exec, :parent
79
122
 
80
- def book(type, yaml, desc=nil, &block)
81
- @books ||= []
82
- books << DslBook.new(type, yaml, desc, &block)
123
+ def group name, desc = nil, plan = :async, &block
124
+ DslGroup.new(name, desc, plan, self, &block)
125
+ _enqueue DslBook.new(:noop, nil, plan: @exec) unless @exec == :async or _sneak.type == :sync
83
126
  end
84
127
 
85
- def initialize(type, desc, &block)
86
- super
128
+ def book(type, yaml, desc: nil, plan: @exec, &block)
129
+ raise ":noop is a reserved book type and cannot be used." if type == :noop
130
+ _enqueue DslBook.new(type, yaml,
131
+ desc: desc,
132
+ plan: plan,
133
+ group: self, &block)
134
+ end
135
+
136
+ def initialize(type, desc, plan, parent=nil, &block)
137
+ super(type, desc, &block)
138
+ @exec = plan
139
+ @parent = parent
87
140
  _bump
88
- instance_eval &block
141
+ instance_eval( &block )
89
142
  @config = _dip
90
143
  end
144
+
145
+ # return a list including ourselves and our parents
146
+ def family
147
+ fam = []
148
+ g = self
149
+ while g
150
+ fam << g.type
151
+ g = g.parent
152
+ end
153
+ fam
154
+ end
91
155
  end
92
156
 
93
157
  class DslPlaybook < Dsl
94
158
  attr :groups
95
159
 
96
- def group name, desc=nil, &block
160
+ def group name, desc = nil, plan = :async, &block
97
161
  @groups ||= []
98
- groups << DslGroup.new(name, desc, &block)
162
+ groups << DslGroup.new(name, desc, plan, &block)
99
163
  end
100
164
 
101
165
  def initialize (type, desc, &block)