producer-core 0.6.1 → 0.6.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: d7bc530fe1a40249353bc078f336fc6a6493a435
4
- data.tar.gz: 611e80867c62642c75e94dcb8d518a318d650b8a
2
+ SHA256:
3
+ metadata.gz: 2cad65cc103070c2e168b124dec1d018d3a133cae0a6d8135766c321b1e62898
4
+ data.tar.gz: a1d7a87ac02475c992a3c448ddd0a1ca6c7b750d2a7d568bd846ec94911390e9
5
5
  SHA512:
6
- metadata.gz: 50a8759567928ec409e2e230f0a4d35e6e24c11cefa5a15206357d11332c3420e9f06b93adbc1ca4a943defb076eaa10e6bd77f03e52e8ae092fa4f3c0ab284f
7
- data.tar.gz: b9812110329c7946c76059cfe61487d7fc384f7eae13a9beab56362a438c941b92b9601390f478f57dba98d12b487c1f6f202f46cd688baceb24c386ee078e6d
6
+ metadata.gz: 786dbe20ba244351fd32a7f05f2cba1ea947515cf090ea1d9274f55d28ca6bf92e3a8f1e45c091dc75ac69e461303e65c24fb39cc0612652edfc7a6822fcc3e0
7
+ data.tar.gz: 0c220841cab6fe26cb7261598a945d9b21d99fdb8469c1e3710533421347726d74b22e28c7262b1795393c186a82a980f8760d448fef6f1f5474e603d3a351bf
data/README.md CHANGED
@@ -1,47 +1,23 @@
1
1
  producer
2
2
  ========
3
3
 
4
- Software provisioning and configuration management tool, providing a
5
- DSL to write "recipes".
6
-
7
- [![Version ][badge-version-img]][badge-version-uri]
8
- [![Build status ][badge-build-img]][badge-build-uri]
9
- [![Code Climate ][badge-cclimate-img]][badge-cclimate-uri]
4
+ producer-core is a software configuration management tool providing
5
+ a DSL to describe infrastructure as code. It helps automating software
6
+ deployment, configuration and management.
10
7
 
11
8
 
12
9
  Getting started
13
10
  ---------------
14
11
 
15
- ### Installation (requires ruby ~> 2.1 and rubygems)
16
-
17
- $ gem install producer-core
12
+ ### Installation (requires ruby and rubygems)
18
13
 
19
-
20
- ### Simple recipe
21
-
22
- Recipes are composed by tasks and a task includes actions. Here we
23
- use the `echo` action, which output the given string to standard
24
- output. All the power of the Ruby language is available.
25
-
26
- ```ruby
27
- hello_message = 'hello world!'
28
-
29
- task :hello_world do
30
- echo hello_message
31
- echo hello_message.upcase
32
- end
33
- ```
34
-
35
- $ producer simple_recipe.rb
36
- hello world!
37
- HELLO WORLD!
14
+ gem install producer-core
38
15
 
39
16
 
40
17
  ### Shell command execution on remote host
41
18
 
42
- The `sh` action will execute a shell command given as a string on
43
- the targeted remote host. The remote host can be specified with the
44
- CLI option `-t`.
19
+ The `sh` action will execute a shell command on the targeted remote
20
+ host. The remote host can be specified with the CLI option `-t`.
45
21
 
46
22
  ```ruby
47
23
  task :show_zsh_pkg do
@@ -49,7 +25,7 @@ task :show_zsh_pkg do
49
25
  end
50
26
  ```
51
27
 
52
- $ producer -t localhost show_zsh_pkg.rb
28
+ % producer -t localhost show_zsh_pkg.rb
53
29
  zsh-5.0.7 The Z shell
54
30
 
55
31
  When execution fails, recipe processing is stopped and the action
@@ -62,9 +38,9 @@ task :sh_fail do
62
38
  end
63
39
  ```
64
40
 
65
- $ producer -t localhost sh_fail.rb
41
+ % producer -t localhost sh_fail.rb
66
42
  RemoteCommandExecutionError: false
67
- $
43
+ %
68
44
 
69
45
  Only the first action is applied.
70
46
 
@@ -74,8 +50,6 @@ end
74
50
  A task can be bound to a condition: when the condition fails actions
75
51
  are skipped, otherwise actions are applied as usual.
76
52
 
77
- This condition can be a simple ruby expression :
78
-
79
53
  ```ruby
80
54
  task :condition_pass do
81
55
  condition { true }
@@ -88,16 +62,13 @@ task :condition_fail do
88
62
  end
89
63
  ```
90
64
 
65
+
91
66
  #### Built-in tests
92
67
 
93
68
  Specific test keywords are also available in the condition block
94
69
  context, `producer-core` ships with a few common tests,
95
70
  `producer-stdlib` provides more, and custom tests can be defined.
96
71
 
97
- Here we use the `sh` condition keyword which will pass when the
98
- execution of the given shell command succeed, and fail when the
99
- execution fails.
100
-
101
72
  ```ruby
102
73
  task :condition_sh_pass do
103
74
  condition { sh 'true' }
@@ -128,105 +99,11 @@ task :main_task do
128
99
  end
129
100
  end
130
101
  ```
131
- $ producer nested_tasks.rb
102
+ % producer nested_tasks.rb
132
103
  do foo
133
104
  do bar
134
105
 
135
106
 
136
- Usage
137
- -----
138
-
139
- Usage: producer [options] [recipes] [-- recipe_arguments...]
140
-
141
- options:
142
- -v, --verbose enable verbose mode
143
- -d, --debug enable debug mode
144
- -n, --dry-run enable dry run mode
145
- -t, --target HOST target host
146
-
147
-
148
- Actions
149
- -------
150
-
151
- See:
152
- https://github.com/tjouan/producer-core/tree/master/features/actions
153
-
154
-
155
- Tests
156
- -----
157
-
158
- See:
159
- https://github.com/tjouan/producer-core/tree/master/features/tests
160
-
161
-
162
- Templates
163
- ---------
164
-
165
- The following example can setup jails on a FreeBSD host.
166
-
167
- In `templates/freebsd/jail.conf.erb`:
168
-
169
- ```erb
170
- exec.start = "/bin/sh /etc/rc";
171
- exec.stop = "/bin/sh /etc/rc.shutdown";
172
- exec.clean;
173
- mount.devfs;
174
- allow.chflags;
175
-
176
- path = "/var/jails/$name";
177
-
178
- <% @jails.each do |jail| -%>
179
- <%= jail[:name] %> {
180
- interface "<%= @if %>";
181
- ip4.addr = <%= jail[:addr4] %>;
182
- }
183
- <% end -%>
184
- ```
185
-
186
- Simple usage:
187
-
188
- ```ruby
189
- INTERFACE = 're0'.freeze
190
- JAILS = [{
191
- name: 'freebsd-10r1',
192
- src: true,
193
- addr4: '10.0.0.1'
194
- }].freeze
195
-
196
- task :jails_conf do
197
- conf = template 'freebsd/jail.conf', if: INTERFACE, jails: JAILS
198
- file_write_once '/etc/jail.conf', conf
199
- end
200
- ```
201
-
202
-
203
- Macros
204
- ------
205
-
206
- FIXME
207
-
208
-
209
- Test macros
210
- -----------
211
-
212
- FIXME
213
-
214
-
215
- Macro composition
216
- -----------------
217
-
218
- FIXME
219
-
220
-
221
- Background
222
- ----------
223
-
224
- producer started as a collection of heterogeneous scripts (Ruby,
225
- POSIX shell, Perl…) in the late '90s. I wanted to experiment with the
226
- design and usage of Domain Specific Languages in Ruby, and refactor
227
- all my scripts as "recipes" in a common language.
228
-
229
-
230
107
  Similar or related code and tools
231
108
  ---------------------------------
232
109
 
@@ -272,12 +149,3 @@ Similar or related code and tools
272
149
  * https://github.com/auxesis/cucumber-nagios (Cucumber, Net::SSH,
273
150
  Webrat)
274
151
  * http://larsyencken.github.io/marelle/ (Prolog, babushka inspired)
275
-
276
-
277
-
278
- [badge-version-img]: https://img.shields.io/gem/v/producer-core.svg?style=flat-square
279
- [badge-version-uri]: https://rubygems.org/gems/producer-core
280
- [badge-build-img]: https://img.shields.io/travis/tjouan/producer-core/master.svg?style=flat-square
281
- [badge-build-uri]: https://travis-ci.org/tjouan/producer-core
282
- [badge-cclimate-img]: https://img.shields.io/codeclimate/github/tjouan/producer-core.svg?style=flat-square
283
- [badge-cclimate-uri]: https://codeclimate.com/github/tjouan/producer-core
data/bin/producer CHANGED
@@ -2,4 +2,4 @@
2
2
 
3
3
  require 'producer/core'
4
4
 
5
- Producer::Core::CLI.run!(ARGV)
5
+ Producer::Core::CLI.run ARGV
@@ -4,15 +4,16 @@ module Producer
4
4
  INSPECT_ARGUMENTS_SUM_LEN = 68
5
5
 
6
6
  extend Forwardable
7
- def_delegators :@env, :input, :output, :error_output, :remote
7
+ def_delegators :@env, :input, :output, :remote
8
+ def_delegator :@env, :output_error, :error_output
8
9
  def_delegators :remote, :fs
9
10
 
10
11
  attr_reader :env, :arguments, :options
11
12
 
12
- def initialize env, *args, **options
13
+ def initialize env, *args
13
14
  @env = env
14
15
  @arguments = args
15
- @options = options
16
+ @options = @arguments[-1].kind_of?(Hash) ? @arguments.pop : {}
16
17
  setup if respond_to? :setup
17
18
  end
18
19
 
@@ -3,7 +3,7 @@ module Producer
3
3
  module Actions
4
4
  class FileWriter < Action
5
5
  def setup
6
- check_arguments_size! arguments_size
6
+ check_arguments_size! 2
7
7
  @path, @content = arguments
8
8
  convert_options mode: :permissions, user: :owner
9
9
  end
@@ -16,12 +16,6 @@ module Producer
16
16
  fs.file_write @path, @content
17
17
  fs.setstat @path, options unless options.empty?
18
18
  end
19
-
20
- private
21
-
22
- def arguments_size
23
- 2
24
- end
25
19
  end
26
20
  end
27
21
  end
@@ -1,106 +1,54 @@
1
1
  module Producer
2
2
  module Core
3
- class CLI
3
+ class CLI < Baf::CLI
4
4
  ArgumentError = Class.new(ArgumentError)
5
5
 
6
6
  USAGE =
7
7
  "Usage: #{File.basename $0} [options] [recipes] [-- recipe_argument...]"
8
8
  .freeze
9
9
 
10
- EX_USAGE = 64
11
- EX_SOFTWARE = 70
12
-
13
10
  ARGUMENTS_SEPARATOR = '--'.freeze
14
11
 
15
- ENV_VERBOSE_KEY = 'PRODUCER_VERBOSE'.freeze
16
- ENV_DEBUG_KEY = 'PRODUCER_DEBUG'.freeze
17
- ENV_DRYRUN_KEY = 'PRODUCER_DRYRUN'.freeze
18
-
19
12
  class << self
20
- def run! arguments, stdin: $stdin, stdout: $stdout, stderr: $stderr
21
- cli = new arguments, ENV, stdin: stdin, stdout: stdout, stderr: stderr
22
- cli.parse_arguments!
23
- cli.run
24
- rescue ArgumentError => e
25
- stderr.puts e.message
26
- exit EX_USAGE
27
- rescue StandardError => e
28
- stderr.puts ErrorFormatter.new(debug: cli.env.debug?).format e
29
- exit EX_SOFTWARE
13
+ def handle_error env, ex
14
+ env.puts_error ErrorFormatter.new(debug: env.debug?).format ex
30
15
  end
31
16
  end
32
17
 
33
- attr_reader :arguments, :stdin, :stdout, :stderr, :env
18
+ def setup
19
+ banner USAGE
34
20
 
35
- def initialize args, environment, stdin: $stdin, stdout: $stdout,
36
- stderr: $stderr
37
- @arguments = args
38
- @stdin = stdin
39
- @stdout = stdout
40
- @stderr = stderr
41
- @env = build_env
21
+ flag_verbose
22
+ flag_debug
23
+ flag_version Producer::Core::VERSION
42
24
 
43
- configure_environment! environment
25
+ flag :n, :dry_run, 'enable dry run mode'
26
+ option :t, :target, 'HOST', 'target host'
44
27
  end
45
28
 
46
29
  def parse_arguments!
47
- if @arguments.include? ARGUMENTS_SEPARATOR
48
- @arguments, @env.recipe_argv = split_arguments_lists @arguments
30
+ if arguments.include? ARGUMENTS_SEPARATOR
31
+ @arguments, env.recipe_argv = split_arguments_lists arguments
49
32
  end
50
- option_parser.parse! @arguments
51
- fail ArgumentError, option_parser if @arguments.empty?
52
- rescue OptionParser::InvalidOption
53
- raise ArgumentError, option_parser
33
+ super
34
+ usage! if arguments.empty?
54
35
  end
55
36
 
56
- def run worker: Worker.new(@env)
37
+ def run worker: Worker.new(env)
57
38
  evaluate_recipes.each { |recipe| worker.process recipe.tasks }
58
39
  ensure
59
- @env.cleanup
40
+ env.cleanup
60
41
  end
61
42
 
62
43
  def evaluate_recipes
63
- @arguments.map { |e| Recipe::FileEvaluator.evaluate(e, @env) }
44
+ arguments.map { |e| Recipe::FileEvaluator.evaluate(e, env) }
64
45
  end
65
46
 
66
47
  private
67
48
 
68
- def build_env
69
- Env.new(input: @stdin, output: @stdout, error_output: @stderr)
70
- end
71
-
72
- def configure_environment! environment
73
- @env.verbose = true if environment.key? ENV_VERBOSE_KEY
74
- @env.debug = true if environment.key? ENV_DEBUG_KEY
75
- @env.dry_run = true if environment.key? ENV_DRYRUN_KEY
76
- end
77
-
78
49
  def split_arguments_lists arguments
79
- arguments
80
- .chunk { |e| e == ARGUMENTS_SEPARATOR }
81
- .reject { |a, _| a }
82
- .map &:last
83
- end
84
-
85
- def option_parser
86
- OptionParser.new do |opts|
87
- opts.banner = USAGE
88
- opts.separator ''
89
- opts.separator 'options:'
90
-
91
- option_parser_add_boolean_options opts
92
- opts.on '-t', '--target HOST', 'target host' do |e|
93
- env.target = e
94
- end
95
- end
96
- end
97
-
98
- def option_parser_add_boolean_options opts
99
- { v: 'verbose', d: 'debug', n: 'dry run' }.each do |k, v|
100
- opts.on "-#{k}", "--#{v.tr ' ', '-'}", "enable #{v} mode" do
101
- env.send "#{v.tr ' ', '_'}=", true
102
- end
103
- end
50
+ head, tail = arguments.slice_after(ARGUMENTS_SEPARATOR).to_a
51
+ [head[0..-2], tail]
104
52
  end
105
53
  end
106
54
  end
@@ -1,20 +1,16 @@
1
1
  module Producer
2
2
  module Core
3
- class Env
3
+ class Env < Baf::Env
4
4
  extend Forwardable
5
5
  def_delegators :@registry, :[]=, :key?
6
6
 
7
- attr_reader :input, :output, :error_output, :registry, :logger
8
- attr_accessor :target, :verbose, :debug, :dry_run, :recipe_argv
7
+ attr_reader :input, :output, :output_error, :registry, :logger
8
+ attr_accessor :recipe_argv
9
9
 
10
- def initialize input: $stdin, output: $stdout, error_output: $stderr,
11
- remote: nil, registry: {}
12
- @verbose = @debug = @dry_run = false
13
- @input = input
14
- @output = output
15
- @error_output = error_output
16
- @remote = remote
17
- @registry = registry
10
+ def initialize remote: nil, registry: {}, **opts
11
+ super **opts
12
+ @remote = remote
13
+ @registry = registry
18
14
  end
19
15
 
20
16
  def remote
@@ -39,18 +35,6 @@ module Producer
39
35
  logger.send severity, message
40
36
  end
41
37
 
42
- def verbose?
43
- @verbose
44
- end
45
-
46
- def debug?
47
- @debug
48
- end
49
-
50
- def dry_run?
51
- @dry_run
52
- end
53
-
54
38
  def cleanup
55
39
  remote.cleanup
56
40
  end
@@ -1,14 +1,16 @@
1
1
  module Producer
2
2
  module Core
3
- Error = Class.new(StandardError)
4
- RuntimeError = Class.new(RuntimeError)
3
+ Error = Class.new StandardError
4
+ RuntimeError = Class.new RuntimeError
5
5
 
6
- ArgumentError = Class.new(Error)
7
- ConditionNotMetError = Class.new(Error)
8
- RecipeEvaluationError = Class.new(RuntimeError)
9
- RemoteCommandExecutionError = Class.new(RuntimeError)
10
- RegistryKeyError = Class.new(RuntimeError)
11
- RemoteInvalidError = Class.new(ArgumentError)
12
- TemplateMissingError = Class.new(RuntimeError)
6
+ ArgumentError = Class.new Error
7
+ ConditionNotMetError = Class.new Error
8
+ RecipeEvaluationError = Class.new RuntimeError
9
+ RegistryKeyError = Class.new RuntimeError
10
+ RemoteCommandExecutionError = Class.new RuntimeError
11
+ RemoteInvalidError = Class.new ArgumentError
12
+ RemoteMismatchError = Class.new RuntimeError
13
+ RemoteUnknownError = Class.new RuntimeError
14
+ TemplateMissingError = Class.new RuntimeError
13
15
  end
14
16
  end
@@ -11,7 +11,13 @@ module Producer
11
11
  def session
12
12
  @session ||= begin
13
13
  check_hostname!
14
- Net::SSH.start(@hostname, user_name)
14
+ Net::SSH.start @hostname, user_name, verify_host_key: :always
15
+ rescue Net::SSH::HostKeyError => e
16
+ error = '`%s\' authenticity can\'t be established' % hostname
17
+ case e
18
+ when Net::SSH::HostKeyUnknown then fail RemoteUnknownError, error
19
+ when Net::SSH::HostKeyMismatch then fail RemoteMismatchError, error
20
+ end
15
21
  end
16
22
  end
17
23
 
@@ -28,7 +28,6 @@ module Producer
28
28
  define_action :file_append, Actions::FileAppend
29
29
  define_action :file_replace_content, Actions::FileReplaceContent
30
30
  define_action :file_write, Actions::FileWriter
31
- define_action :yaml_write, Actions::YAMLWriter
32
31
 
33
32
  attr_reader :name, :actions, :condition
34
33
 
@@ -1,3 +1,3 @@
1
1
  Then /^the output must contain my current login name$/ do
2
- assert_partial_output Etc.getlogin, all_output
2
+ expect($_baf[:process].output).to include Etc.getlogin
3
3
  end
@@ -1,34 +1,33 @@
1
- def run_recipe remote: false, options: nil, check: false, rargv: nil
2
- command = %w[producer recipe.rb]
1
+ def run_recipe remote: false, options: nil, check: false, rargv: nil, wait: true
2
+ command = $_baf[:program] + %w[recipe.rb]
3
3
  case remote
4
4
  when :unknown then command += %w[-t unknown_host.test]
5
5
  when true then command += %w[-t some_host.test]
6
6
  end
7
- command << options if options
8
- command << ['--', *rargv] if rargv
7
+ command += options if options
8
+ command += %w[--] + rargv if rargv
9
9
 
10
- with_environment 'HOME' => expand_path('.') do
11
- run_simple command.join(' '), false
12
- end
10
+ env_allow = Baf::Testing::ENV_WHITELIST + $_baf[:env_allow]
11
+ $_baf[:process] = Baf::Testing.run command, env_allow: env_allow, wait: wait
13
12
 
14
- assert_exit_status 0 if check
15
- assert_matching_output '\ASocketError', all_output if remote == :unknown
13
+ Baf::Testing.expect_ex $_baf[:process], 0 if check
14
+ expect($_baf[:process].output).to match /\ASocketError/ if remote == :unknown
16
15
  end
17
16
 
18
17
  Given /^a recipe with:$/ do |recipe_body|
19
- write_file 'recipe.rb', recipe_body
18
+ Baf::Testing.write_file 'recipe.rb', recipe_body + $/
20
19
  end
21
20
 
22
21
  Given /^a recipe with an error$/ do
23
- write_file 'recipe.rb', "fail 'some error'\n"
22
+ Baf::Testing.write_file 'recipe.rb', "fail 'some error'\n"
24
23
  end
25
24
 
26
25
  Given /^a recipe using a remote$/ do
27
- write_file 'recipe.rb', "task(:some_task) { sh 'echo hello' }\n"
26
+ Baf::Testing.write_file 'recipe.rb', "task(:some_task) { sh 'echo hello' }\n"
28
27
  end
29
28
 
30
29
  Given /^a recipe named "([^"]+)" with:$/ do |recipe_path, recipe_body|
31
- write_file recipe_path, recipe_body
30
+ Baf::Testing.write_file recipe_path, recipe_body
32
31
  end
33
32
 
34
33
  When /^I execute the recipe$/ do
@@ -44,11 +43,11 @@ When /^I execute the recipe on unknown remote target$/ do
44
43
  end
45
44
 
46
45
  When /^I execute the recipe with options? (-.+)$/ do |options|
47
- run_recipe options: options
46
+ run_recipe options: options.split(' ')
48
47
  end
49
48
 
50
49
  When /^I execute the recipe on unknown remote target with options? (-.+)$/ do |options|
51
- run_recipe remote: :unknown, options: options
50
+ run_recipe remote: :unknown, options: options.split(' ')
52
51
  end
53
52
 
54
53
  When /^I successfully execute the recipe$/ do
@@ -60,17 +59,17 @@ When /^I successfully execute the recipe on remote target$/ do
60
59
  end
61
60
 
62
61
  When /^I successfully execute the recipe on remote target with options? (-.+)$/ do |options|
63
- run_recipe remote: true, options: options, check: true
62
+ run_recipe remote: true, options: options.split(' '), check: true
64
63
  end
65
64
 
66
65
  When /^I successfully execute the recipe with options? (-.+)$/ do |options|
67
- run_recipe options: options, check: true
66
+ run_recipe options: options.split(' '), check: true
68
67
  end
69
68
 
70
69
  When /^I successfully execute the recipe with arguments "([^"]+)"$/ do |rargv|
71
- run_recipe rargv: rargv, check: true
70
+ run_recipe rargv: rargv.split(' '), check: true
72
71
  end
73
72
 
74
73
  When /^I execute the recipe interactively$/ do
75
- run 'producer recipe.rb'
74
+ run_recipe remote: true, wait: false
76
75
  end
@@ -1,43 +1,37 @@
1
1
  def stat_mode path
2
- cd '.' do
3
- ('%o' % [File::Stat.new(path).mode])[-4, 4]
4
- end
2
+ ('%o' % [File::Stat.new(path).mode])[-4, 4]
5
3
  end
6
4
 
7
5
  Given /^a remote directory named "([^"]+)"$/ do |path|
8
- create_directory path
6
+ FileUtils.mkdir_p path
9
7
  end
10
8
 
11
9
  Given /^a remote file named "([^"]+)"$/ do |file_name|
12
- write_file file_name, ''
10
+ Baf::Testing.write_file file_name, ''
13
11
  end
14
12
 
15
13
  Given /^a remote file named "([^"]+)" with "([^"]+)"$/ do |file_name, content|
16
- write_file file_name, content
14
+ Baf::Testing.write_file file_name, content
17
15
  end
18
16
 
19
17
  Then /^the remote directory "([^"]+)" must exist$/ do |path|
20
- expect(path).to be_an_existing_directory
18
+ expect(Dir.exist? path).to be true
21
19
  end
22
20
 
23
21
  Then /^the remote file "([^"]+)" must exist$/ do |path|
24
- check_file_presence [path], true
22
+ expect(File.file? path).to be true
25
23
  end
26
24
 
27
25
  Then /^the remote file "([^"]+)" must contain "([^"]+)"$/ do |path, content|
28
- expect(path).to have_file_content Regexp.new(content)
26
+ expect(IO.read path).to include content
29
27
  end
30
28
 
31
29
  Then /^the remote file "([^"]+)" must contain exactly "([^"]+)"$/ do |path, content|
32
- expect(path).to have_file_content content
30
+ expect(IO.read path).to include content
33
31
  end
34
32
 
35
33
  Then /^the remote file "([^"]+)" must contain exactly:$/ do |path, content|
36
- expect(path).to have_file_content content
37
- end
38
-
39
- Then /^the remote file "([^"]+)" must match \/([^\/]+)\/$/ do |path, pattern|
40
- expect(path).to have_file_content /#{pattern}/
34
+ expect(IO.read path).to eq content
41
35
  end
42
36
 
43
37
  Then /^the remote file "([^"]+)" must have (\d+) mode$/ do |path, mode|
@@ -1,3 +1,11 @@
1
+ Given /^SSH known hosts:$/ do |db|
2
+ Baf::Testing.write_file '.ssh/known_hosts', db
3
+ end
4
+
1
5
  Given /^an SSH config with:$/ do |config|
2
- write_file '.ssh/config', config
6
+ Baf::Testing.write_file '.ssh/config', config
7
+ end
8
+
9
+ Given /^no SSH known hosts$/ do
10
+ Baf::Testing.write_file '.ssh/known_hosts', ''
3
11
  end
@@ -1,35 +1,7 @@
1
- require 'aruba/cucumber'
2
- require 'aruba/in_process'
1
+ require 'cucumber/sshd/cucumber'
3
2
 
4
3
  require 'producer/core'
5
- require 'producer/core/testing/aruba_program_wrapper'
6
4
  require 'producer/core/testing/cucumber/etc_steps'
7
- require 'producer/core/testing/cucumber/execution_steps'
8
- require 'producer/core/testing/cucumber/output_steps'
9
5
  require 'producer/core/testing/cucumber/recipe_steps'
10
6
  require 'producer/core/testing/cucumber/remote_steps'
11
7
  require 'producer/core/testing/cucumber/ssh_steps'
12
-
13
- # Raise aruba default timeout so test suite can run on a slow machine.
14
- Before do
15
- @aruba_timeout_seconds = 8
16
- end
17
-
18
- # Use aruba "in process" optimization only for scenarios not tagged @exec.
19
- # We need a real process in a few cases: real program name, interactive usage…
20
- Before('@exec') do
21
- aruba.config.command_launcher = :spawn
22
- end
23
-
24
- Before('~@exec') do
25
- aruba.config.command_launcher = :in_process
26
- aruba.config.main_class = Producer::Core::Testing::ArubaProgramWrapper
27
- end
28
-
29
- # Enable cucumber-sshd "fast" mode (persists sshd across scenarios), and
30
- # register hooks for @sshd tagged scenarios.
31
- Before do
32
- @_sshd_fast = true
33
- @_sshd_wait_ready = true if ENV.key? 'TRAVIS'
34
- end
35
- require 'cucumber/sshd/cucumber'
@@ -1,5 +1,5 @@
1
1
  module Producer
2
2
  module Core
3
- VERSION = '0.6.1'.freeze
3
+ VERSION = '0.6.2'.freeze
4
4
  end
5
5
  end
data/lib/producer/core.rb CHANGED
@@ -5,6 +5,7 @@ require 'optparse'
5
5
  require 'pathname'
6
6
  require 'yaml'
7
7
 
8
+ require 'baf/cli'
8
9
  require 'net/ssh'
9
10
  require 'net/sftp'
10
11
 
@@ -16,7 +17,6 @@ require 'producer/core/actions/mkdir'
16
17
  require 'producer/core/actions/file_append'
17
18
  require 'producer/core/actions/file_replace_content'
18
19
  require 'producer/core/actions/file_writer'
19
- require 'producer/core/actions/yaml_writer'
20
20
 
21
21
  # condition tests
22
22
  require 'producer/core/test'
metadata CHANGED
@@ -1,29 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: producer-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.1
4
+ version: 0.6.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Thibault Jouan
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-01-28 00:00:00.000000000 Z
11
+ date: 2022-07-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: net-ssh
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '3.1'
19
+ version: 4.2.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "~>"
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: '3.1'
26
+ version: 4.2.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: net-sftp
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -39,25 +39,19 @@ dependencies:
39
39
  - !ruby/object:Gem::Version
40
40
  version: '2.1'
41
41
  - !ruby/object:Gem::Dependency
42
- name: aruba
42
+ name: baf
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '0.8'
48
- - - "<"
49
- - !ruby/object:Gem::Version
50
- version: '0.9'
51
- type: :development
47
+ version: '0.15'
48
+ type: :runtime
52
49
  prerelease: false
53
50
  version_requirements: !ruby/object:Gem::Requirement
54
51
  requirements:
55
52
  - - "~>"
56
53
  - !ruby/object:Gem::Version
57
- version: '0.8'
58
- - - "<"
59
- - !ruby/object:Gem::Version
60
- version: '0.9'
54
+ version: '0.15'
61
55
  - !ruby/object:Gem::Dependency
62
56
  name: cucumber
63
57
  requirement: !ruby/object:Gem::Requirement
@@ -78,34 +72,28 @@ dependencies:
78
72
  requirements:
79
73
  - - "~>"
80
74
  - !ruby/object:Gem::Version
81
- version: '1.1'
82
- - - ">="
83
- - !ruby/object:Gem::Version
84
- version: 1.1.1
75
+ version: '2.0'
85
76
  type: :development
86
77
  prerelease: false
87
78
  version_requirements: !ruby/object:Gem::Requirement
88
79
  requirements:
89
80
  - - "~>"
90
81
  - !ruby/object:Gem::Version
91
- version: '1.1'
92
- - - ">="
93
- - !ruby/object:Gem::Version
94
- version: 1.1.1
82
+ version: '2.0'
95
83
  - !ruby/object:Gem::Dependency
96
84
  name: rake
97
85
  requirement: !ruby/object:Gem::Requirement
98
86
  requirements:
99
- - - "~>"
87
+ - - ">="
100
88
  - !ruby/object:Gem::Version
101
- version: '10.1'
89
+ version: '0'
102
90
  type: :development
103
91
  prerelease: false
104
92
  version_requirements: !ruby/object:Gem::Requirement
105
93
  requirements:
106
- - - "~>"
94
+ - - ">="
107
95
  - !ruby/object:Gem::Version
108
- version: '10.1'
96
+ version: '0'
109
97
  - !ruby/object:Gem::Dependency
110
98
  name: rspec
111
99
  requirement: !ruby/object:Gem::Requirement
@@ -120,9 +108,10 @@ dependencies:
120
108
  - - "~>"
121
109
  - !ruby/object:Gem::Version
122
110
  version: '3.1'
123
- description: |2
124
- Software provisioning and configuration management tool, providing a
125
- DSL to write "recipes".
111
+ description: |
112
+ producer-core is a software configuration management tool providing a DSL
113
+ to describe infrastructure as code.
114
+ It helps automating software deployment, configuration and management.
126
115
  email: tj@a13.fr
127
116
  executables:
128
117
  - producer
@@ -140,7 +129,6 @@ files:
140
129
  - lib/producer/core/actions/file_writer.rb
141
130
  - lib/producer/core/actions/mkdir.rb
142
131
  - lib/producer/core/actions/shell_command.rb
143
- - lib/producer/core/actions/yaml_writer.rb
144
132
  - lib/producer/core/cli.rb
145
133
  - lib/producer/core/condition.rb
146
134
  - lib/producer/core/env.rb
@@ -159,12 +147,8 @@ files:
159
147
  - lib/producer/core/template/raw_renderer.rb
160
148
  - lib/producer/core/template/yaml_renderer.rb
161
149
  - lib/producer/core/test.rb
162
- - lib/producer/core/testing.rb
163
- - lib/producer/core/testing/aruba_program_wrapper.rb
164
150
  - lib/producer/core/testing/cucumber.rb
165
151
  - lib/producer/core/testing/cucumber/etc_steps.rb
166
- - lib/producer/core/testing/cucumber/execution_steps.rb
167
- - lib/producer/core/testing/cucumber/output_steps.rb
168
152
  - lib/producer/core/testing/cucumber/recipe_steps.rb
169
153
  - lib/producer/core/testing/cucumber/remote_steps.rb
170
154
  - lib/producer/core/testing/cucumber/ssh_steps.rb
@@ -185,7 +169,7 @@ homepage: https://rubygems.org/gems/producer-core
185
169
  licenses:
186
170
  - BSD-3-Clause
187
171
  metadata: {}
188
- post_install_message:
172
+ post_install_message:
189
173
  rdoc_options: []
190
174
  require_paths:
191
175
  - lib
@@ -200,9 +184,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
200
184
  - !ruby/object:Gem::Version
201
185
  version: '0'
202
186
  requirements: []
203
- rubyforge_project:
204
- rubygems_version: 2.6.10
205
- signing_key:
187
+ rubygems_version: 3.3.17
188
+ signing_key:
206
189
  specification_version: 4
207
- summary: Provisioning tool
190
+ summary: Software configuration management tool
208
191
  test_files: []
@@ -1,22 +0,0 @@
1
- module Producer
2
- module Core
3
- module Actions
4
- class YAMLWriter < FileWriter
5
- def setup
6
- super
7
- @content = options.delete(:data).to_yaml
8
- end
9
-
10
- def name
11
- 'yaml_write'
12
- end
13
-
14
- private
15
-
16
- def arguments_size
17
- 1
18
- end
19
- end
20
- end
21
- end
22
- end
@@ -1,24 +0,0 @@
1
- module Producer
2
- module Core
3
- module Testing
4
- class ArubaProgramWrapper
5
- def initialize argv, stdin = $stdin, stdout = $stdout, stderr = $stderr,
6
- kernel = Kernel
7
- @argv = argv
8
- @stdin = stdin
9
- @stdout = stdout
10
- @stderr = stderr
11
- @kernel = kernel
12
- end
13
-
14
- def execute!
15
- Producer::Core::CLI.run!(
16
- @argv.dup, stdin: @stdin, stdout: @stdout, stderr: @stderr
17
- )
18
- rescue SystemExit => e
19
- @kernel.exit e.status
20
- end
21
- end
22
- end
23
- end
24
- end
@@ -1,3 +0,0 @@
1
- Then /^the exit status must be (\d+)$/ do |exit_status|
2
- assert_exit_status exit_status.to_i
3
- end
@@ -1,47 +0,0 @@
1
- Then /^the output must contain exactly the usage$/ do
2
- assert_exact_output <<-eoh, all_output
3
- Usage: producer [options] [recipes] [-- recipe_argument...]
4
-
5
- options:
6
- -v, --verbose enable verbose mode
7
- -d, --debug enable debug mode
8
- -n, --dry-run enable dry run mode
9
- -t, --target HOST target host
10
- eoh
11
- end
12
-
13
- Then /^the output must match \/([^\/]+)\/$/ do |pattern|
14
- assert_matching_output pattern, all_output
15
- end
16
-
17
- Then /^the output must contain "([^"]+)"$/ do |content|
18
- assert_partial_output content, all_output
19
- end
20
-
21
- Then /^the output must contain:$/ do |content|
22
- assert_partial_output content, all_output
23
- end
24
-
25
- Then /^the output must not contain "([^"]+)"$/ do |content|
26
- assert_no_partial_output content, all_output
27
- end
28
-
29
- Then /^the output must contain exactly "([^"]+)"$/ do |content|
30
- assert_exact_output content, all_output
31
- end
32
-
33
- Then /^the output must contain exactly:$/ do |content|
34
- assert_exact_output content, all_output
35
- end
36
-
37
- Then /^the error output must contain exactly "([^"]+)"$/ do |content|
38
- assert_exact_output content, all_stderr
39
- end
40
-
41
- Then /^the output must contain ruby lib directory$/ do
42
- assert_partial_output RbConfig::CONFIG['rubylibdir'], all_output
43
- end
44
-
45
- Then /^the output must not contain ruby lib directory$/ do
46
- assert_no_partial_output RbConfig::CONFIG['rubylibdir'], all_output
47
- end
@@ -1 +0,0 @@
1
- require 'producer/core/testing/mock_remote'