molder 0.1.4 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +14 -13
- data/README.md +5 -0
- data/lib/molder/app.rb +21 -9
- data/lib/molder/cli.rb +65 -37
- data/lib/molder/version.rb +14 -2
- data/molder.gemspec +1 -0
- metadata +35 -22
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 416984ac32edc7ff37f6d1e6af4452d6e76c06a067ef47d224f06d98e77e4f7b
|
4
|
+
data.tar.gz: 12793070ad5336d858f8ebe2059088c382f83419e5dfd49ee6378df7c0cc2770
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ed68c853eb5586055bea4674204af94018d6e0e4816d63fbd924a90cce11cb5b2899ea451397e6557b1a099ceaa2218d3c3519c6f3a026fca3619f8246cad57b
|
7
|
+
data.tar.gz: c77e6d30a6e960ace71885e7e804b8c0924cafae972d30fbd54844e4c3f1afe4ddba1a569efa10a6c25bce8442219cdc6804364df2a899937fc344cfea8cbf67
|
data/.travis.yml
CHANGED
@@ -1,26 +1,27 @@
|
|
1
1
|
language: ruby
|
2
|
-
env:
|
3
|
-
global:
|
4
|
-
- CODECLIMATE_REPO_TOKEN=49ca8c0e2d56ab70e7eabc237692e21cc8fe43ef13ed5d411fa20bf1e8997a44
|
5
2
|
rvm:
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
3
|
+
- 2.2.9
|
4
|
+
- 2.3.6
|
5
|
+
- 2.4.3
|
6
|
+
- 2.5.0
|
10
7
|
cache:
|
11
8
|
- bundler
|
12
9
|
before_script:
|
13
|
-
|
14
|
-
|
15
|
-
|
10
|
+
- curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64
|
11
|
+
> ./cc-test-reporter
|
12
|
+
- chmod +x ./cc-test-reporter
|
13
|
+
- "./cc-test-reporter before-build"
|
16
14
|
after_script:
|
17
|
-
|
15
|
+
- "./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT"
|
18
16
|
script: bundle exec rspec
|
19
17
|
notifications:
|
20
18
|
slack:
|
21
|
-
rooms:
|
19
|
+
rooms:
|
22
20
|
email:
|
23
21
|
recipients:
|
24
|
-
|
22
|
+
- kigster@gmail.com
|
25
23
|
on_success: change
|
26
24
|
on_failure: always
|
25
|
+
env:
|
26
|
+
global:
|
27
|
+
secure: ojmeEPTv11JMBQcHdPq96qEVk+TTmuJp+HeTIrhCUwNuTXMIUUhTXyhKWCuzNN2J7YxzkyzxKx5cWGd0ydBCv6F91dEmyiaLmtBGsRp+aF30bmPWeiu8srvUVU7RfP9AOzJPrgruFoSfJOKUvwERgs3gUZRwNMBlWIK18hY7jZRLziVFrqf9QAIhC/DMqjjwq/ko9VCj+Lf3YgW88fk83TobXGLXtaoLoj5h9Vo2AYHCd9P4bq5vr1HirUOG9j3+CVI0fUprvifK8nrxYBCk6nCX7rYgkdLzYRg8BaNj8MDUSZ2eMwyNsVaY0VisC2vAg1LdvO2nsKtFzgdZ/etAP5iOuS+Lc/IhrYKdM9bgXB2eb8cC68NQ+15YW2nuFdyv9F7gMEKiQIZoyU9Vw607Dk5vogBQdIajwUUQHnEHyU4rwUNZ8V5+XLDsNnm7Ky8JlTQuv1SMbForNiCTfiei5aX0ETsu+02+lgDOXy2nIUZ+tXfPzjD5IMbK+hHKE0I0wUX9R/W68wYyVZW975yvIeW9VraU+IhIQheUqqWhBx7cbMCh7bb1SJWp6ggT30tD4SMAozSVvcApARCom3olXz1orL29A7DAaqa8O/J5/97uHRDWrqR2jahwD1ZAetYXyBHVj23JgL29PCYQ92yp1zwj93c4Nww4a4MTOSXTcx4=
|
data/README.md
CHANGED
@@ -1,4 +1,7 @@
|
|
1
1
|
[](https://travis-ci.org/kigster/molder)
|
2
|
+
[](https://codeclimate.com/github/kigster/molder/maintainability)
|
3
|
+
[](https://codeclimate.com/github/kigster/molder/test_coverage)
|
4
|
+
[](https://rubygems.org/gems/molder)
|
2
5
|
|
3
6
|
# Molder
|
4
7
|
|
@@ -169,6 +172,8 @@ Let's understand this command:
|
|
169
172
|
* next we pass `-a environment=production` — notice that our provision command defined in the template uses `{{ environment }}` token, even though no such attribute is defined in any of the templates. if we do not supply this argument, the value of environment in the command line would be blank.
|
170
173
|
|
171
174
|
* Note that you can pass multiple attributes, separated by a slash, like so: `-a environment=production/flavor=c5.4xlarge`
|
175
|
+
|
176
|
+
* You can also pass multiple attributes by using `-a/--attrs` more than once, eg. `-a key1=value1 -a key2=value2 ....`
|
172
177
|
|
173
178
|
* The final argument is the template file. The default location is `config/molder.yml` — so if you place the file in that folder you don't need to pass `-c` argument.
|
174
179
|
|
data/lib/molder/app.rb
CHANGED
@@ -24,22 +24,34 @@ module Molder
|
|
24
24
|
colors = %i(yellow blue red green magenta cyan white)
|
25
25
|
|
26
26
|
FileUtils.mkdir_p(log_dir)
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
27
|
+
if options.dry_run
|
28
|
+
puts "\nDry-run print of #{commands.size} commands:\n".bold.cyan.underlined
|
29
|
+
commands.count.times do |i|
|
30
|
+
color = colors[i % colors.size]
|
31
|
+
cmd = commands[i ]
|
32
|
+
puts "#{cmd}\n".send(color).send(:bold)
|
33
|
+
end
|
34
|
+
else
|
35
|
+
puts "Executing #{commands.size} commands using a pool of up to #{options.max_processes} processes:\n".bold.cyan.underlined
|
36
|
+
::Parallel.each((1..commands.size),
|
37
|
+
:in_processes => options.max_processes) do |i|
|
33
38
|
|
34
|
-
|
35
|
-
|
39
|
+
color = colors[(i - 1) % colors.size]
|
40
|
+
cmd = commands[i - 1]
|
41
|
+
printf('%s', "Worker: #{Parallel.worker_number}, command #{i}\n".send(color)) if options.verbose
|
42
|
+
puts "#{cmd}\n".send(color)
|
36
43
|
|
37
|
-
|
44
|
+
system %Q(( #{cmd} ) > #{log_dir}/#{command_name}.#{i}.log)
|
45
|
+
end
|
38
46
|
end
|
39
47
|
end
|
40
48
|
|
41
49
|
private
|
42
50
|
|
51
|
+
def puts(*args)
|
52
|
+
::Molder::CLI.instance.stdout.puts(*args)
|
53
|
+
end
|
54
|
+
|
43
55
|
def resolve_templates!
|
44
56
|
self.templates ||= []
|
45
57
|
options.names.each_pair do |name, indexes|
|
data/lib/molder/cli.rb
CHANGED
@@ -7,6 +7,11 @@ require 'etc'
|
|
7
7
|
module Molder
|
8
8
|
class CLI
|
9
9
|
attr_accessor :argv, :original_argv, :options, :config, :command
|
10
|
+
attr_reader :stdout, :stdin, :stderr, :kernel
|
11
|
+
|
12
|
+
class << self
|
13
|
+
attr_accessor :instance
|
14
|
+
end
|
10
15
|
|
11
16
|
def initialize(argv, stdin = STDIN, stdout = STDOUT, stderr = STDERR, kernel = Kernel)
|
12
17
|
@argv, @stdin, @stdout, @stderr, @kernel = argv, stdin, stdout, stderr, kernel
|
@@ -15,41 +20,27 @@ module Molder
|
|
15
20
|
self.options[:max_processes] = Etc.nprocessors - 2
|
16
21
|
self.argv = argv.dup
|
17
22
|
self.original_argv = argv.dup
|
23
|
+
self.class.instance = self
|
24
|
+
end
|
25
|
+
|
26
|
+
def execute!
|
18
27
|
|
19
28
|
self.argv << '-h' if argv.empty?
|
20
29
|
|
21
30
|
parser.parse!(self.argv)
|
22
|
-
exit(0) if options.help
|
23
|
-
|
24
|
-
pre_parse!
|
25
31
|
|
26
|
-
if options.
|
27
|
-
|
28
|
-
|
29
|
-
if values.nil?
|
30
|
-
override[name] = option.indexes
|
31
|
-
end
|
32
|
-
end
|
33
|
-
options.names.merge!(override)
|
32
|
+
if options.help
|
33
|
+
@kernel.exit(0)
|
34
|
+
return
|
34
35
|
end
|
35
36
|
|
36
|
-
self.config = if options.config
|
37
|
-
if File.exist?(options.config)
|
38
|
-
Configuration.load(options.config)
|
39
|
-
else
|
40
|
-
report_error(message: "file #{options.config} does not exist.")
|
41
|
-
end
|
42
|
-
else
|
43
|
-
Configuration.default
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
def execute!
|
48
37
|
exit_code = begin
|
49
38
|
$stderr = @stderr
|
50
39
|
$stdin = @stdin
|
51
40
|
$stdout = @stdout
|
52
41
|
|
42
|
+
parse_args!
|
43
|
+
|
53
44
|
App.new(config: config, options: options, command_name: command).execute!
|
54
45
|
|
55
46
|
0
|
@@ -68,6 +59,30 @@ module Molder
|
|
68
59
|
|
69
60
|
private
|
70
61
|
|
62
|
+
def parse_args!
|
63
|
+
pre_parse!
|
64
|
+
|
65
|
+
if options.indexes
|
66
|
+
override = {}
|
67
|
+
options.names.each_pair do |name, values|
|
68
|
+
if values.nil?
|
69
|
+
override[name] = option.indexes
|
70
|
+
end
|
71
|
+
end
|
72
|
+
options.names.merge!(override)
|
73
|
+
end
|
74
|
+
|
75
|
+
self.config = if options.config
|
76
|
+
if File.exist?(options.config)
|
77
|
+
Configuration.load(options.config)
|
78
|
+
else
|
79
|
+
report_error(message: "file #{options.config} does not exist.")
|
80
|
+
end
|
81
|
+
else
|
82
|
+
Configuration.default
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
71
86
|
def pre_parse!
|
72
87
|
if argv[0] && !argv[0].start_with?('-')
|
73
88
|
self.command = argv.shift
|
@@ -84,10 +99,10 @@ module Molder
|
|
84
99
|
opts.separator 'OPTIONS:'.bold.yellow
|
85
100
|
|
86
101
|
opts.on('-c', '--config [file]',
|
87
|
-
'Main YAML configuration file') { |config| options[:config] = config }
|
102
|
+
'Main YAML configuration file', ' ') { |config| options[:config] = config }
|
88
103
|
|
89
104
|
opts.on('-t', '--template [n1/n2/..]',
|
90
|
-
'Names of the templates to use') do |value|
|
105
|
+
'Names of the templates to use', ' ') do |value|
|
91
106
|
options[:names] ||= Hashie::Mash.new
|
92
107
|
value.split('/').each { |arg| parse_templates(arg) }
|
93
108
|
end
|
@@ -95,25 +110,30 @@ module Molder
|
|
95
110
|
opts.on('-i', '--index [range/array]',
|
96
111
|
'Numbers to use in generating commands',
|
97
112
|
'Can be a comma-separated list of values,',
|
98
|
-
'or a range, eg "1..5"') do |value|
|
113
|
+
'or a range, eg "1..5"', ' ') do |value|
|
99
114
|
options[:indexes] = index_expression_to_array(value)
|
100
115
|
end
|
101
116
|
|
102
117
|
opts.on('-a', '--attrs [k1=v1/k2=v2/...]',
|
103
|
-
'Provide additional attributes, or
|
118
|
+
'Provide additional attributes, or ',
|
119
|
+
'override existing ones. Can be used ',
|
120
|
+
'more than once on a command line', ' ') do |value|
|
104
121
|
h = {}
|
105
122
|
value.split('/').each do |pair|
|
106
123
|
key, value = pair.split('=')
|
107
124
|
h[key] = value
|
108
125
|
end
|
109
|
-
options[:override]
|
126
|
+
options[:override] ||= {}
|
127
|
+
options[:override].merge!(h)
|
110
128
|
end
|
111
129
|
|
112
130
|
opts.on('-m', '--max-processes [number]',
|
113
|
-
'
|
131
|
+
'Limit number of concurrent running processes',
|
132
|
+
'The default is the number of CPU cores', ' '
|
133
|
+
) { |value| options[:max_processes] = value.to_i }
|
114
134
|
|
115
135
|
opts.on('-l', '--log-dir [dir]',
|
116
|
-
'
|
136
|
+
'Folder where STDOUT of the commands is saved') { |value| options[:log_dir] = value }
|
117
137
|
|
118
138
|
opts.on('-n', '--dry-run',
|
119
139
|
'Don\'t actually run commands, just print them') { |_value| options[:dry_run] = true }
|
@@ -132,17 +152,21 @@ module Molder
|
|
132
152
|
|
133
153
|
end.tap do |p|
|
134
154
|
p.banner = <<-eof
|
155
|
+
|
135
156
|
#{'DESCRIPTION'.bold.yellow}
|
136
|
-
Molder is a template
|
137
|
-
generate many similar and yet somewhat different commands,
|
138
|
-
YAML template. Please
|
139
|
-
a detailed explanation of the config file structure.
|
157
|
+
Molder is a template-based command generator and runner for cases where
|
158
|
+
you need to generate many similar and yet somewhat different commands,
|
159
|
+
defined in the YAML template. Please visit #{'https://github.com/kigster/molder'.bold.blue.underlined}
|
160
|
+
for a detailed explanation of the config file structure.
|
140
161
|
|
141
|
-
Note that the default
|
162
|
+
Note, that the default config is #{Molder::Configuration::DEFAULT_CONFIG.bold.green}.
|
142
163
|
|
143
164
|
#{'USAGE'.bold.yellow}
|
144
|
-
#{'
|
145
|
-
#{'molder [-c config.yml] command
|
165
|
+
#{'# shorthand usage - combine multiple templates with a slash:'.bold.black}
|
166
|
+
#{'molder [-c config.yml] command template1[n1..n2]/... [options]'.bold.blue}
|
167
|
+
|
168
|
+
#{'# alternatively, use -t and -i CLI options:'.bold.black}
|
169
|
+
#{'molder [-c config.yml] command -t template -i index [options]'.blue.bold}
|
146
170
|
|
147
171
|
#{'EXAMPLES'.bold.yellow}
|
148
172
|
#{'# The following commands assume YAML file is in the default location:'.bold.black}
|
@@ -151,6 +175,10 @@ module Molder
|
|
151
175
|
#{'# -n flag means dry run — so instead of running commands, just print them:'.bold.black}
|
152
176
|
#{'molder provision web[1..4]/job[1..4] -n'.bold.blue}
|
153
177
|
|
178
|
+
#{'# Here we supply (or override) attributes "environment" and "flavor":'.bold.black}
|
179
|
+
#{'molder provision web[1..4]/job[1..4] -n -a environment=production \
|
180
|
+
-a flavor=c5.8xlarge'.bold.blue}
|
181
|
+
|
154
182
|
eof
|
155
183
|
end
|
156
184
|
end
|
data/lib/molder/version.rb
CHANGED
@@ -1,7 +1,19 @@
|
|
1
1
|
module Molder
|
2
|
-
VERSION = '0.
|
2
|
+
VERSION = '0.2.0'.freeze
|
3
3
|
DESCRIPTION = <<-eof
|
4
|
-
Molder is a command line tool for generating and running (in parallel,
|
4
|
+
Molder is a handy command line tool for generating and running (in parallel,
|
5
|
+
using a pool of processes with a configurable size) a set of related and yet
|
6
|
+
different commands. A YAML file defines both the attributes and the command
|
7
|
+
template, and Molder then merges the two with CLI arguments to give you a
|
8
|
+
consistent set of commands for, eg. provisioning thousands of virtual hosts
|
9
|
+
in a cloud. The gem is not limnited to any particular cloud, tool, or a
|
10
|
+
command, and can be used across various domains to generate a consistent set
|
11
|
+
of commands based on the YAML-supplied attributes and templates, that might
|
12
|
+
vary across custom dimensions. For example, you could generate 600 provisioning
|
13
|
+
commands for hosts in EC2, numbered from 1 to 100, but constrained to the
|
14
|
+
zones "a", "b", "c", and data centers "dc" (values: ['us-west2', 'us-east1' ]).
|
15
|
+
Behind the scenes Molder uses another Ruby gem Parallel — for actually running
|
16
|
+
the provisioning commands.
|
5
17
|
eof
|
6
18
|
.gsub(/\s{2,}/, ' ')
|
7
19
|
end
|
data/molder.gemspec
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: molder
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Konstantin Gredeskoul
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-04-
|
11
|
+
date: 2018-04-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: liquid
|
@@ -164,17 +164,27 @@ dependencies:
|
|
164
164
|
- - ">="
|
165
165
|
- !ruby/object:Gem::Version
|
166
166
|
version: '0'
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
167
|
+
- !ruby/object:Gem::Dependency
|
168
|
+
name: aruba
|
169
|
+
requirement: !ruby/object:Gem::Requirement
|
170
|
+
requirements:
|
171
|
+
- - ">="
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '0'
|
174
|
+
type: :development
|
175
|
+
prerelease: false
|
176
|
+
version_requirements: !ruby/object:Gem::Requirement
|
177
|
+
requirements:
|
178
|
+
- - ">="
|
179
|
+
- !ruby/object:Gem::Version
|
180
|
+
version: '0'
|
181
|
+
description: |2
|
182
|
+
Molder is a handy command line tool for generating and running (in parallel, using a pool of processes with a configurable size) a set of related and yet
|
183
|
+
different commands. A YAML file defines both the attributes and the command
|
184
|
+
template, and Molder then merges the two with CLI arguments to give you a
|
185
|
+
consistent set of commands for, eg. provisioning thousands of virtual hosts in a cloud. The gem is not limnited to any particular cloud, tool, or a command, and can be used across various domains to generate a consistent set of commands based on the YAML-supplied attributes and templates, that might
|
186
|
+
vary across custom dimensions. For example, you could generate 600 provisioning commands for hosts in EC2, numbered from 1 to 100, but constrained to the zones "a", "b", "c", and data centers "dc" (values: ['us-west2', 'us-east1' ]). Behind the scenes Molder uses another Ruby gem Parallel — for actually running
|
187
|
+
the provisioning commands.
|
178
188
|
email:
|
179
189
|
- kigster@gmail.com
|
180
190
|
executables:
|
@@ -228,13 +238,16 @@ rubyforge_project:
|
|
228
238
|
rubygems_version: 2.7.6
|
229
239
|
signing_key:
|
230
240
|
specification_version: 4
|
231
|
-
summary: 'Molder is a command line tool for generating and running (in parallel,
|
232
|
-
a
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
241
|
+
summary: 'Molder is a handy command line tool for generating and running (in parallel,
|
242
|
+
using a pool of processes with a configurable size) a set of related and yet different
|
243
|
+
commands. A YAML file defines both the attributes and the command template, and
|
244
|
+
Molder then merges the two with CLI arguments to give you a consistent set of commands
|
245
|
+
for, eg. provisioning thousands of virtual hosts in a cloud. The gem is not limnited
|
246
|
+
to any particular cloud, tool, or a command, and can be used across various domains
|
247
|
+
to generate a consistent set of commands based on the YAML-supplied attributes and
|
248
|
+
templates, that might vary across custom dimensions. For example, you could generate
|
249
|
+
600 provisioning commands for hosts in EC2, numbered from 1 to 100, but constrained
|
250
|
+
to the zones "a", "b", "c", and data centers "dc" (values: [''us-west2'', ''us-east1''
|
251
|
+
]). Behind the scenes Molder uses another Ruby gem Parallel — for actually running
|
252
|
+
the provisioning commands.'
|
240
253
|
test_files: []
|