rundock 0.2.0 → 0.2.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
2
  SHA1:
3
- metadata.gz: 0491b048401872650ce67684e7e23556866b43e3
4
- data.tar.gz: 6bd121b04391da55428ba012f7ed550427a7d0cd
3
+ metadata.gz: eef77dde29974f83d4bef90d7ac82886ebfc46d5
4
+ data.tar.gz: 484b9c3e7f4f4f557a3ecb1d3d5ce506566bc45d
5
5
  SHA512:
6
- metadata.gz: b218e32fb3145065062a7d8c7d869e948898361c38a0b63af2c692d6987d2373a20d8fd04187c3f58700b87f6d4cd63411a2292e41311c429570f9bdbb953308
7
- data.tar.gz: 1e327e599076b186c71d67e260b2195d3f19c1b5103b01d5940ad90641b29db8974e726b507895d6eebc0a9dcba0723c919ed4313471fc024d8ff182cd39f35d
6
+ metadata.gz: adf8f0dc23a9a4f38db95b77eb804ac336dae9aba7d0a8d671572221c635c8ec8fc6fd3b71ef0cc8979162f22253b603345a85b33578e413bbe30005037622be
7
+ data.tar.gz: a8b0d0a20eb279a2ae8f46cbe800a38fe266736d4087a0eccb15546cea74d7e13525245e72706a999376e64fd622cad4198b8f4245a6b9408a8b397ab781f5da
data/CHANGELOG.md CHANGED
@@ -1,3 +1,18 @@
1
+ ## v0.2.2
2
+
3
+ Fix
4
+
5
+ - Fix ssh options conflict bugs
6
+ - Support docker 1.6.2 for Circle CI environtment
7
+
8
+ ## v0.2.1
9
+
10
+ Improvements
11
+
12
+ - Support error-exit options.(like shellscript set -e/+e)
13
+ - Change file path option name from '*_yaml' to '*'
14
+ - Add a option that stdout can no-header
15
+
1
16
  ## v0.2.0
2
17
 
3
18
  Refactoring
data/README.md CHANGED
@@ -12,6 +12,28 @@ $ gem install rundock
12
12
 
13
13
  ## Usage
14
14
 
15
+ Edit your hostgroup to "hostgroup.yml" like this sample.
16
+
17
+ ```
18
+ # node section
19
+ - node: 192.168.1.11
20
+ - node: host-alias-01
21
+ ---
22
+ # host information section
23
+ host-alias-01:
24
+ host: 192.168.1.12
25
+ ssh_opts:
26
+ port: 2222
27
+ user: anyuser
28
+ keys: ["~/.ssh/id_rsa_anyuser"]
29
+ ```
30
+
31
+ and execute rundock.
32
+
33
+ $ rundock ssh -g /path/to/your-dir/hostgroup.yml -c 'your-gread-command'
34
+
35
+ or
36
+
15
37
  Edit your operation scenario to "[scenario.yml](https://github.com/hiracy/rundock/blob/master/scenario_sample.yml)" like this sample.
16
38
 
17
39
  ```
@@ -37,19 +59,26 @@ host-alias-01:
37
59
  ---
38
60
  # task information section
39
61
  update_gem:
40
- - "sudo gem update --system"
41
- - "sudo gem update"
62
+ command:
63
+ - "sudo gem update --system"
64
+ - "sudo gem update"
42
65
  install_bundler:
43
- - "sudo gem install bundler --no-ri --no-rdoc"
66
+ command:
67
+ - "sudo gem install bundler --no-ri --no-rdoc"
44
68
  ```
45
69
 
46
- and do rundock.
70
+ and execute rundock.
47
71
 
48
- $ rundock do -s /path/to/your-dir/scenario.yml
72
+ $ rundock do /path/to/your-dir/scenario.yml
49
73
 
50
- You can also specify [ssh_options.yml](http://net-ssh.github.io/net-ssh/classes/Net/SSH.html)(Net::SSH options) file contents that you specified "-d" option to the default ssh options.
74
+ You can also specify [default_ssh_options.yml](https://github.com/hiracy/rundock/blob/master/default_ssh.yml) [(Net::SSH options)](http://net-ssh.github.io/net-ssh/classes/Net/SSH.html) file contents that you specified "-d" option to the default ssh options.
51
75
 
52
- $ rundock do -s /path/to/your-dir/scenario.yml -d /path/to/your-dir/ssh_options.yml
76
+ ```
77
+ $ rundock ssh -g /path/to/your-dir/hostgroup.yml -c 'your-gread-command' -d /path/to/your-dir/default_ssh_options.yml
78
+ ```
79
+ ```
80
+ $ rundock do -s /path/to/your-dir/scenario.yml -d /path/to/your-dir/default_ssh_options.yml
81
+ ```
53
82
 
54
83
  For more detail. You can see from `rundock -h` command.
55
84
 
data/Rakefile CHANGED
@@ -6,15 +6,6 @@ run_commands = [
6
6
  'echo \'Hello Rundock.\' > /var/tmp/hello_rundock'
7
7
  ]
8
8
 
9
- run_scenarios = %w(
10
- use_default_ssh_scenario
11
- simple_echo_scenario
12
- )
13
-
14
- run_groups = %w(
15
- simple_host_group
16
- )
17
-
18
9
  def execute(command, clean_env)
19
10
  puts "[EXECUTE:] #{command}"
20
11
 
@@ -42,8 +33,9 @@ def setup_docker(platform, timeout, interval)
42
33
  raise 'Docker Error.' unless found
43
34
  end
44
35
 
45
- def do_rundock_ssh(commands, platform, groups)
36
+ def do_rundock_ssh(commands, platform)
46
37
  base_dir = "#{ENV['HOME']}/.rundock/#{platform}"
38
+ groups_files_pattern = ["#{base_dir}/groups/*.yml"]
47
39
 
48
40
  if platform == 'localhost'
49
41
  commands.each do |cmd|
@@ -52,38 +44,42 @@ def do_rundock_ssh(commands, platform, groups)
52
44
  else
53
45
  commands.each do |cmd|
54
46
  execute('bundle exec exe/rundock' \
55
- " ssh -c \"#{cmd}\" -h 127.0.0.1 -p 22222 -u tester" \
47
+ " ssh -c \"#{cmd}\" -h 172.17.42.1 -p 22222 -u tester" \
56
48
  " -i #{ENV['HOME']}/.ssh/id_rsa_rundock_spec_#{platform}_tmp -l debug", true)
57
- groups.each do |g|
49
+ Dir.glob(groups_files_pattern).each do |g|
58
50
  execute('bundle exec exe/rundock' \
59
- " ssh -c \"#{cmd}\" -g #{base_dir}/scenarios/#{g}.yml -p 22222 -u tester" \
51
+ " ssh -c \"#{cmd}\" -g #{g} -p 22222 -u tester" \
60
52
  " -i #{ENV['HOME']}/.ssh/id_rsa_rundock_spec_#{platform}_tmp -l debug", true)
61
53
  end
62
54
  end
63
55
  end
64
56
  end
65
57
 
66
- def do_rundock_scenarios(scenarios, platform)
58
+ def do_rundock_scenarios(platform)
67
59
  if platform == 'localhost'
68
60
  base_dir = './spec/integration/platforms/localhost'
61
+ scenario_files_pattern = ['./spec/integration/platforms/localhost/scenarios/*.yml']
69
62
  else
70
63
  base_dir = "#{ENV['HOME']}/.rundock/#{platform}"
64
+ scenario_files_pattern = ["#{base_dir}/scenarios/*.yml"]
71
65
  end
72
66
 
73
- scenarios.each do |scenario|
74
- default_ssh_opt = ''
67
+ Dir.glob(scenario_files_pattern).each do |scenario|
75
68
  if scenario =~ /use_default_ssh/ && platform != 'localhost'
76
69
  default_ssh_opt = " -d #{base_dir}/integration_default_ssh.yml"
70
+ else
71
+ default_ssh_opt = ''
77
72
  end
78
73
 
79
74
  execute('bundle exec exe/rundock' \
80
- " do -s #{base_dir}/scenarios/#{scenario}.yml#{default_ssh_opt} -l debug", true)
75
+ " do #{scenario}#{default_ssh_opt} -l debug", true)
81
76
  end
82
77
  end
83
78
 
84
79
  desc 'Cleaning environments'
85
80
 
86
81
  task :clean do
82
+ execute('rm -f /var/tmp/hello_rundock*', false)
87
83
  Dir.glob('./spec/integration/platforms/*').each do |platform|
88
84
  next if platform =~ /localhost$/
89
85
  execute("#{platform}/setup.sh --clean", false)
@@ -132,8 +128,8 @@ namespace :spec do
132
128
  desc "Run rundock for #{target}"
133
129
 
134
130
  task :rundock do
135
- do_rundock_ssh(run_commands, target, run_groups)
136
- do_rundock_scenarios(run_scenarios, target)
131
+ do_rundock_ssh(run_commands, target)
132
+ do_rundock_scenarios(target)
137
133
  end
138
134
 
139
135
  desc "Run serverspec tests for #{target}"
@@ -141,7 +137,7 @@ namespace :spec do
141
137
  RSpec::Core::RakeTask.new(:serverspec) do |t|
142
138
  ENV['TARGET_HOST'] = target
143
139
  t.ruby_opts = '-I ./spec/integration'
144
- t.pattern = './spec/integration/recipes/*_spec.rb'
140
+ t.pattern = ['./spec/integration/recipes/*_spec.rb']
145
141
  end
146
142
  end
147
143
  end
@@ -25,18 +25,18 @@ module Rundock
25
25
  @backend = create_specinfra_backend
26
26
  end
27
27
 
28
- def run_commands(cmd, options = {})
28
+ def run_commands(cmd, exec_options = {})
29
29
  Array(cmd).each do |c|
30
- run_command(c)
30
+ run_command(c, exec_options)
31
31
  end
32
32
  end
33
33
 
34
34
  private
35
35
 
36
- def run_command(cmd, options = {})
36
+ def run_command(cmd, exec_options = {})
37
37
  command = cmd.strip
38
- command = "cd #{Shellwords.escape(options[:cwd])} && #{command}" if options[:cwd]
39
- command = "sudo -H -u #{Shellwords.escape(user)} -- /bin/sh -c #{command}" if options[:user]
38
+ command = "cd #{Shellwords.escape(exec_options[:cwd])} && #{command}" if exec_options[:cwd]
39
+ command = "sudo -H -u #{Shellwords.escape(user)} -- /bin/sh -c #{command}" if exec_options[:user]
40
40
 
41
41
  Logger.debug(%(Start executing: "#{command}"))
42
42
 
@@ -46,11 +46,12 @@ module Rundock
46
46
  Logger.formatter.indent do
47
47
  Logger.error("#{result.stderr}") unless result.stderr.blank?
48
48
  Logger.info("#{result.stdout.strip}") unless result.stdout.strip.blank?
49
+ Logger.debug("errexit: #{exec_options[:errexit]}")
49
50
  Logger.debug("exit status: #{exit_status}")
50
51
  end
51
52
 
52
- if options[:no_continue_if_error] && exit_status != 0
53
- raise CommandResultStatucError
53
+ if exec_options[:errexit] && exit_status != 0
54
+ raise CommandResultStatusError
54
55
  end
55
56
 
56
57
  result
@@ -81,19 +82,15 @@ module Rundock
81
82
  private
82
83
 
83
84
  def parse(options)
84
- if options['ssh_config'] && FileTest.exists?(options['ssh_config'])
85
- ssh_opts = Net::SSH::Config.for(options['host'], [options['ssh_config']])
85
+ if options[:ssh_config] && FileTest.exists?(options[:ssh_config])
86
+ ssh_opts = Net::SSH::Config.for(options[:host], [options[:ssh_config]])
86
87
  else
87
- ssh_opts = Net::SSH::Config.for(options['host'])
88
+ ssh_opts = Net::SSH::Config.for(options[:host])
88
89
  end
89
90
 
90
- ssh_opts[:host_name] = options['host']
91
- ssh_opts[:user] = options['user']
92
- ssh_opts[:keys] = options['keys']
93
- ssh_opts[:keys] = Array(options['key']) if !ssh_opts[:keys] && options['key']
94
- ssh_opts[:port] = options['port']
95
- ssh_opts[:password] = parse_password_from_stdin if options['ask_password']
96
-
91
+ ssh_opts[:host_name] = options[:host]
92
+ ssh_opts[:keys] = Array(options[:key]) if options[:key]
93
+ ssh_opts[:password] = parse_password_from_stdin if options[:ask_password]
97
94
  ssh_opts.merge!(filter_net_ssh_options(options))
98
95
 
99
96
  Logger.debug(%(Net::SSH Options: "#{ssh_opts}"))
@@ -111,7 +108,7 @@ module Rundock
111
108
  def filter_net_ssh_options(options)
112
109
  opts = {}
113
110
  options.each do |k, v|
114
- opts[k.to_sym] = v if Net::SSH::VALID_OPTIONS.include?(k.to_sym)
111
+ opts[k] = v if Net::SSH::VALID_OPTIONS.include?(k)
115
112
  end
116
113
 
117
114
  opts
@@ -15,12 +15,14 @@ module Rundock
15
15
  opts.merge!(@options)
16
16
 
17
17
  # update ssh options for node from node_info
18
- opts.merge!(@node_info[@nodename]['ssh_opts'])
18
+ opts.merge!(@node_info[@nodename.to_sym][:ssh_opts])
19
+
19
20
  # delete trash ssh_options(node[host::ssh_options])
20
- @node_info[@nodename].delete('ssh_opts')
21
+ @node_info[@nodename.to_sym].delete(:ssh_opts)
21
22
 
22
23
  # add any attributes for host from node_info
23
- opts.merge!(@node_info[@nodename])
24
+ opts.merge!(@node_info[@nodename.to_sym])
25
+
24
26
  Backend.create(backend_type, opts)
25
27
  end
26
28
 
@@ -30,35 +32,34 @@ module Rundock
30
32
  opts = {}
31
33
 
32
34
  if !@node_info ||
33
- !@node_info[@nodename]
34
- @node_info = { @nodename => {} }
35
+ !@node_info[@nodename.to_sym]
36
+ @node_info = { @nodename.to_sym => {} }
35
37
  end
36
- @node_info[@nodename]['ssh_opts'] = {} unless @node_info[@nodename]['ssh_opts']
37
- is_local = @nodename =~ /localhost|127\.0\.0\.1/
38
+ @node_info[@nodename.to_sym][:ssh_opts] = {} unless @node_info[@nodename.to_sym][:ssh_opts]
38
39
 
39
40
  # replace default ssh options if exists
40
- @options.keys.select { |o| o =~ /(\w+)_ssh_default$/ }.each do |oo|
41
- opt = oo.gsub(/_ssh_default/, '')
41
+ @options.keys.select { |o| o.to_s =~ /(\w+)_ssh_default$/ }.each do |oo|
42
42
  # no use default ssh options if local
43
- # (like docker or localhost with port access host should not use default ssh options)
44
- @node_info[@nodename]['ssh_opts'][opt] = @options[oo] if !is_local && !@node_info[@nodename]['ssh_opts'][opt]
43
+ # set unless scenario file and cli options specified and not localhost
44
+ next if @nodename =~ /localhost|127\.0\.0\.1/
45
+ opt = oo.to_s.gsub(/_ssh_default/, '').to_sym
46
+ if !@node_info[@nodename.to_sym][:ssh_opts][opt] && !@options[opt]
47
+ @node_info[@nodename.to_sym][:ssh_opts][opt] = @options[oo]
48
+ end
45
49
  end
46
50
 
47
51
  # replace cli ssh options if exists
48
- %w(user key port ssh_config ask_password sudo).each { |o| @node_info[@nodename]['ssh_opts'][o] = @options[o] if @options[o] }
49
-
50
- opts['host'] = @nodename
52
+ %w(:user :key :port :ssh_config :ask_password :sudo).each { |o| @node_info[@nodename.to_sym][:ssh_opts][o] = @options[o] if @options[o] }
51
53
 
54
+ opts[:host] = @nodename
52
55
  opts
53
56
  end
54
57
 
55
58
  def parse_backend_type
56
- is_local = @nodename =~ /localhost|127\.0\.0\.1/
57
-
58
- if is_local &&
59
- !@node_info[@nodename]['ssh_opts']['port'] &&
60
- !@node_info[@nodename]['ssh_opts']['user'] &&
61
- !@node_info[@nodename]['ssh_opts']['ssh_config']
59
+ if @nodename =~ /localhost|127\.0\.0\.1/ &&
60
+ !@node_info[@nodename.to_sym][:ssh_opts][:port] &&
61
+ !@node_info[@nodename.to_sym][:ssh_opts][:user] &&
62
+ !@node_info[@nodename.to_sym][:ssh_opts][:ssh_config]
62
63
  backend_type = :local
63
64
  else
64
65
  backend_type = :ssh
@@ -12,8 +12,8 @@ module Rundock
12
12
  def build
13
13
  opts = {}
14
14
 
15
- if @options['default_ssh_opts_yaml'] && FileTest.exist?(@options['default_ssh_opts_yaml'])
16
- def_ssh_file = @options['default_ssh_opts_yaml']
15
+ if @options[:default_ssh_opts] && FileTest.exist?(@options[:default_ssh_opts])
16
+ def_ssh_file = @options[:default_ssh_opts]
17
17
  else
18
18
  def_ssh_file = PRESET_SSH_OPTIONS_DEFAULT_FILE_PATH
19
19
  end
@@ -21,7 +21,7 @@ module Rundock
21
21
  File.open(def_ssh_file) do |f|
22
22
  YAML.load_documents(f) do |y|
23
23
  y.each do |k, v|
24
- opts["#{k}_ssh_default"] = v
24
+ opts["#{k}_ssh_default".to_sym] = v
25
25
  end
26
26
  end
27
27
  end
@@ -0,0 +1,88 @@
1
+ module Rundock
2
+ module Builder
3
+ class OperationBuilder < Base
4
+ def build_first(scenario, node_info, tasks)
5
+ if @options[:hostgroup] && !@options[:command]
6
+ raise CommandArgNotFoundError, %("--command or -c" option is required if hostgroup specified.)
7
+ end
8
+
9
+ node = nil
10
+ scen = Scenario.new
11
+ node_attributes = { :task => {} }
12
+ tasks.each { |k, v| node_attributes[:task][k] = v } if tasks
13
+ scen.node_info = node_info
14
+ scen.tasks = tasks
15
+
16
+ # use scenario file
17
+ scenario.each do |n|
18
+ scen.nodes.push(node) if node
19
+
20
+ n.deep_symbolize_keys.each do |k, v|
21
+ if k == :node
22
+ backend = BackendBuilder.new(@options, v, node_info).build
23
+ node = Node.new(v, backend)
24
+ node_attributes[:nodename] = v
25
+
26
+ if @options[:command]
27
+ node.add_operation(build_cli_command_operation(@options[:command], @options))
28
+ end
29
+ else
30
+ if @options[:command] && (k == :command || k == :task)
31
+ Logger.debug(%("--command or -c" option is specified and ignore scenario file.))
32
+ next
33
+ end
34
+
35
+ next unless node
36
+
37
+ ope = build_operations(k, Array(v), node_attributes, @options)
38
+ node.add_operation(ope)
39
+ end
40
+ end
41
+ end
42
+
43
+ scen.nodes.push(node) if node
44
+ scen
45
+ end
46
+
47
+ def build_task(tasks, backend, node_attributes)
48
+ node = Node.new(node_attributes[:nodename], backend)
49
+ scen = Scenario.new
50
+
51
+ tasks.each do |k, v|
52
+ ope = build_operations(k, Array(v), node_attributes, nil)
53
+ node.add_operation(ope)
54
+ end
55
+
56
+ scen.nodes.push(node) if node
57
+ scen
58
+ end
59
+
60
+ def build_cli
61
+ scen = Scenario.new
62
+
63
+ @options[:host].split(',').each do |host|
64
+ backend = BackendBuilder.new(@options, host, nil).build
65
+ node = Node.new(host, backend)
66
+ node.add_operation(build_cli_command_operation(@options[:command], @options))
67
+ scen.nodes.push(node)
68
+ end
69
+
70
+ scen
71
+ end
72
+
73
+ private
74
+
75
+ def build_cli_command_operation(command, cli_options)
76
+ node_attributes = {}
77
+ node_attributes[:errexit] = !cli_options[:run_anyway]
78
+ Rundock::OperationFactory.instance(:command).create(Array(command), nil)
79
+ end
80
+
81
+ def build_operations(ope_type, ope_content, node_attributes, cli_options)
82
+ node_attributes[:errexit] = !cli_options[:run_anyway] if cli_options
83
+ node_attributes[:errexit] = true if cli_options.nil?
84
+ Rundock::OperationFactory.instance(ope_type).create(Array(ope_content), node_attributes)
85
+ end
86
+ end
87
+ end
88
+ end
@@ -13,82 +13,45 @@ module Rundock
13
13
 
14
14
  def build
15
15
  # parse default ssh file
16
- opts = @default_ssh_builder.build
17
- opts.merge!(@options)
16
+ @options.merge!(@default_ssh_builder.build)
18
17
 
19
18
  # use host specified
20
- return build_scenario_with_host(opts) if opts['host']
19
+ return build_scenario_with_cli if @options[:host]
21
20
 
22
21
  # use scenario file
23
- build_scenario(opts)
22
+ build_scenario_with_file
24
23
  end
25
24
 
26
- private
27
-
28
- def build_scenario_with_host(options)
29
- raise CommandArgNotFoundError, %("--command or -c" option is not specified.) unless options['command']
30
-
31
- scen = Scenario.new
32
-
33
- options['host'].split(',').each do |host|
34
- backend = BackendBuilder.new(options, host, nil).build
35
- node = Node.new(host, backend)
36
- node.add_operation(Rundock::OperationFactory.instance(:command).create(Array(options['command']), nil))
37
- scen << node
38
- end
39
-
40
- scen
25
+ def build_task(tasks, backend, node_attributes)
26
+ OperationBuilder.new(@options).build_task(tasks, backend, node_attributes)
41
27
  end
42
28
 
43
- def build_scenario(options)
44
- if options['hostgroup_yaml'] && !options['command']
45
- raise CommandArgNotFoundError, %("--command or -c" option is required if hostgroup specified.)
46
- end
29
+ private
47
30
 
48
- type = [:main, :node_info, :tasks]
49
- scenario_data = {}
31
+ def build_scenario_with_cli
32
+ raise CommandArgNotFoundError, %("--command or -c" option is not specified.) unless @options[:command]
33
+ ope = OperationBuilder.new(@options)
34
+ ope.build_cli
35
+ end
50
36
 
37
+ def build_scenario_with_file
51
38
  if @scenario_file
52
- YAML.load_documents(@scenario_file).each_with_index do |data, idx|
53
- scenario_data[type[idx]] = data
54
- end
55
- end
56
-
57
- node = nil
58
- scen = Scenario.new
59
-
60
- # use scenario file
61
- scenario_data[:main].each do |n|
62
- scen << node if node
63
39
 
64
- n.each do |k, v|
65
- if k == 'node'
66
- backend = BackendBuilder.new(options, v, scenario_data[:node_info]).build
67
- node = Node.new(v, backend)
40
+ type = [:main, :node_info, :tasks]
41
+ scenario_data = {}
68
42
 
69
- if options['command']
70
- node.add_operation(
71
- Rundock::OperationFactory.instance(:command).create(Array(options['command']), nil))
72
- end
43
+ YAML.load_documents(@scenario_file).each_with_index do |data, idx|
44
+ if idx == 0
45
+ scenario_data[type[idx]] = data
73
46
  else
74
-
75
- if options['command'] && (k == 'command' || k == 'task')
76
- Logger.debug(%("--command or -c" option is specified and ignore scenario file.))
77
- next
78
- end
79
-
80
- ope = build_operations(k, v, scenario_data[:tasks], options)
81
- node.add_operation(ope) if node
47
+ scenario_data[type[idx]] = data.deep_symbolize_keys unless data.nil?
82
48
  end
83
49
  end
84
50
  end
85
51
 
86
- scen << node if node
87
- scen
88
- end
89
-
90
- def build_operations(ope_type, ope_content, tasks, options)
91
- Rundock::OperationFactory.instance(ope_type.to_sym).create(Array(ope_content), tasks)
52
+ ope = OperationBuilder.new(@options)
53
+ ope.build_first(
54
+ scenario_data[:main], scenario_data[:node_info], scenario_data[:tasks])
92
55
  end
93
56
  end
94
57
  end
data/lib/rundock/cli.rb CHANGED
@@ -9,12 +9,14 @@ module Rundock
9
9
 
10
10
  class_option :log_level, type: :string, aliases: ['-l'], default: 'info'
11
11
  class_option :color, type: :boolean, default: true
12
+ class_option :header, type: :boolean, default: true
12
13
 
13
14
  def initialize(args, opts, config)
14
15
  super(args, opts, config)
15
16
 
16
17
  Rundock::Logger.level = ::Logger.const_get(options[:log_level].upcase)
17
18
  Rundock::Logger.formatter.colored = options[:color]
19
+ Rundock::Logger.formatter.show_header = options[:header]
18
20
  end
19
21
 
20
22
  desc 'version', 'Print version'
@@ -24,30 +26,31 @@ module Rundock
24
26
 
25
27
  desc 'do [SCENARIO] [options]', 'Run rundock from scenario file'
26
28
  option :sudo, type: :boolean, default: false
27
- option :scenario_yaml, type: :string, aliases: ['-s'], default: DEFAULT_SCENARIO_FILE_PATH
28
- option :default_ssh_opts_yaml, type: :string, aliases: ['-d'], default: DEFAULT_SSH_OPTIONS_DEFAULT_FILE_PATH
29
+ option :default_ssh_opts, type: :string, aliases: ['-d'], default: DEFAULT_SSH_OPTIONS_DEFAULT_FILE_PATH
30
+ option :run_anyway, type: :boolean, default: false
29
31
  def do(*scenario_file_path)
30
32
  scenario_file_path = [DEFAULT_SCENARIO_FILE_PATH] if scenario_file_path.empty?
31
- opts = { :scenario_yaml => scenario_file_path[0] }
33
+ opts = { :scenario => scenario_file_path[0] }
32
34
 
33
- Runner.run(opts.merge(options))
35
+ Runner.run(opts.merge(options.deep_symbolize_keys))
34
36
  end
35
37
 
36
38
  desc 'ssh [options]', 'Run rundock ssh with various options'
37
39
  option :command, type: :string, aliases: ['-c']
38
- option :default_ssh_opts_yaml, type: :string, aliases: ['-d'], default: DEFAULT_SSH_OPTIONS_DEFAULT_FILE_PATH
40
+ option :default_ssh_opts, type: :string, aliases: ['-d'], default: DEFAULT_SSH_OPTIONS_DEFAULT_FILE_PATH
39
41
  option :host, type: :string, aliases: ['-h'], banner: 'You can specify comma separated hosts.[ex: host1,host2,..]'
40
- option :hostgroup_yaml, type: :string, aliases: ['-g']
42
+ option :hostgroup, type: :string, aliases: ['-g']
41
43
  option :user, type: :string, aliases: ['-u']
42
44
  option :key, type: :string, aliases: ['-i']
43
45
  option :port, type: :numeric, aliases: ['-p']
44
46
  option :ssh_config, type: :string, aliases: ['-F']
45
47
  option :ask_password, type: :boolean, default: false
46
48
  option :sudo, type: :boolean, default: false
49
+ option :run_anyway, type: :boolean, default: false
47
50
  def ssh
48
51
  opts = {}
49
52
 
50
- Runner.run(opts.merge(options))
53
+ Runner.run(opts.merge(options.deep_symbolize_keys))
51
54
  end
52
55
  end
53
56
  end
@@ -8,6 +8,7 @@ module Rundock
8
8
  attr_accessor :colored
9
9
  attr_accessor :indent_depth
10
10
  attr_accessor :color
11
+ attr_accessor :show_header
11
12
 
12
13
  def initialize(*args)
13
14
  super
@@ -15,7 +16,12 @@ module Rundock
15
16
  end
16
17
 
17
18
  def call(severity, datetime, progname, msg)
18
- out = "[%5s:] %s%s\n" % [severity, ' ' * 2 * indent_depth, msg2str(msg)]
19
+ if @show_header
20
+ out = "[\%5s:] %s%s\n" % [severity, ' ' * 2 * indent_depth, msg2str(msg)]
21
+ else
22
+ out = "%s\n" % [msg2str(msg)]
23
+ end
24
+
19
25
  if colored
20
26
  colorize(out, severity)
21
27
  else
data/lib/rundock/node.rb CHANGED
@@ -18,6 +18,10 @@ module Rundock
18
18
 
19
19
  def run
20
20
  Logger.debug("run name: #{@name}")
21
+ if @operations.blank?
22
+ Logger.warn("no operation running: #{@name}")
23
+ return
24
+ end
21
25
  @operations.each do |ope|
22
26
  Logger.debug("operation type: #{ope.class}")
23
27
  ope.run(@backend, ope.attributes)
@@ -3,6 +3,11 @@ module Rundock
3
3
  class Command < Base
4
4
  def run(backend, attributes = {})
5
5
  @instruction.each do |i|
6
+ if i.is_a?(Hash)
7
+ attributes.merge!(i)
8
+ next
9
+ end
10
+
6
11
  backend.run_commands(i, attributes)
7
12
  end
8
13
  end
@@ -3,12 +3,15 @@ module Rundock
3
3
  class Task < Base
4
4
  def run(backend, attributes = {})
5
5
  @instruction.each do |i|
6
- unless attributes.key?(i)
7
- Logger.warn("[WARN]task not found and ignored: #{i}")
6
+ unless attributes[:task].key?(i.to_sym)
7
+ Logger.warn("task not found and ignored: #{i}")
8
8
  next
9
9
  end
10
10
 
11
- backend.run_commands(attributes[i])
11
+ scenario = Rundock::Builder::ScenarioBuilder.new(nil, nil).build_task(
12
+ attributes[:task][i.to_sym], backend, attributes)
13
+
14
+ scenario.run
12
15
  end
13
16
  end
14
17
  end
@@ -7,7 +7,7 @@ module Rundock
7
7
 
8
8
  class << self
9
9
  def run(options)
10
- Logger.info 'Starting Rundoc:'
10
+ Logger.debug 'Starting Rundoc:'
11
11
 
12
12
  runner = self.new(options)
13
13
  runner.build(options)
@@ -25,24 +25,28 @@ module Rundock
25
25
  @scenario.run
26
26
  end
27
27
 
28
+ def run_tasks
29
+ @scenario.run
30
+ end
31
+
28
32
  def build(options)
29
- if options['scenario_yaml'] || options['hostgroup_yaml']
30
- if options['scenario_yaml'] && !FileTest.exist?(options['scenario_yaml'])
31
- raise ScenarioNotFoundError, "'#{options['scenario_yaml']}' scenario file is not found."
32
- elsif options['hostgroup_yaml'] && !FileTest.exist?(options['hostgroup_yaml'])
33
- raise ScenarioNotFoundError, "'#{options['hostgroup_yaml']}' hostgroup file is not found."
33
+ if options[:scenario] || options[:hostgroup]
34
+ if options[:scenario] && !FileTest.exist?(options[:scenario])
35
+ raise ScenarioNotFoundError, "'#{options[:scenario]}' scenario file is not found."
36
+ elsif options[:hostgroup] && !FileTest.exist?(options[:hostgroup])
37
+ raise ScenarioNotFoundError, "'#{options[:hostgroup]}' hostgroup file is not found."
34
38
  end
35
39
 
36
- options['scenario_yaml'] = options['hostgroup_yaml'] if options['hostgroup_yaml']
40
+ options[:scenario] = options[:hostgroup] if options[:hostgroup]
37
41
 
38
42
  # parse scenario
39
- if options['scenario_yaml'] =~ %r{^(http|https)://}
43
+ if options[:scenario] =~ %r{^(http|https)://}
40
44
  # read from http/https
41
- open(options['scenario_yaml']) do |f|
45
+ open(options[:scenario]) do |f|
42
46
  @scenario = Rundock::Builder::ScenarioBuilder.new(options, f).build
43
47
  end
44
48
  else
45
- File.open(options['scenario_yaml']) do |f|
49
+ File.open(options[:scenario]) do |f|
46
50
  @scenario = Rundock::Builder::ScenarioBuilder.new(options, f).build
47
51
  end
48
52
  end
@@ -1,7 +1,15 @@
1
1
  module Rundock
2
- class Scenario < Array
2
+ class Scenario
3
+ attr_accessor :nodes
4
+ attr_accessor :node_info
5
+ attr_accessor :tasks
6
+
7
+ def initialize
8
+ @nodes = []
9
+ end
10
+
3
11
  def run
4
- self.each(&:run)
12
+ @nodes.each(&:run)
5
13
  end
6
14
  end
7
15
  end
@@ -1,3 +1,3 @@
1
1
  module Rundock
2
- VERSION = '0.2.0'
2
+ VERSION = '0.2.2'
3
3
  end
data/lib/rundock.rb CHANGED
@@ -12,6 +12,7 @@ require 'rundock/backend'
12
12
  require 'rundock/builder/base'
13
13
  require 'rundock/builder/default_ssh_builder'
14
14
  require 'rundock/builder/backend_builder'
15
+ require 'rundock/builder/operation_builder'
15
16
  require 'rundock/builder/scenario_builder'
16
17
  require 'rundock/runner'
17
18
  require 'rundock/cli'
data/rundock.gemspec CHANGED
@@ -9,7 +9,7 @@ Gem::Specification.new do |spec|
9
9
  spec.authors = ['hiracy']
10
10
  spec.email = ['leizhen@mbr.nifty.com']
11
11
 
12
- spec.summary = 'Simple Execution framework for various servers'
12
+ spec.summary = 'Simple and extensible server operation framework'
13
13
  spec.homepage = 'https://github.com/hiracy/rundock'
14
14
  spec.license = 'MIT'
15
15
 
data/scenario_sample.yml CHANGED
@@ -38,16 +38,26 @@
38
38
  task:
39
39
  - echo_platform
40
40
  - echo_users
41
+ command:
42
+ - errexit: true
43
+ - "rm /tmp/riskyfile"
44
+ - errexit: false
45
+ - "rm /tmp/safetyfile"
46
+ - "ls -1 /tmp"
41
47
  ---
42
- anyhost-01:
48
+ - anyhost-01:
43
49
  host: 192.168.1.11
44
50
  ssh_opts:
45
51
  port: 22
46
52
  user: anyuser
53
+ - anyhost-02:
54
+ host: 192.168.1.12
47
55
  ---
48
56
  echo_platform:
49
- - "hostname"
50
- - "uname -a"
57
+ command:
58
+ - "hostname"
59
+ - "uname -a"
51
60
  echo_users:
52
- - "whoami"
53
- - "w"
61
+ command:
62
+ - "whoami"
63
+ - "w"
@@ -4,7 +4,7 @@
4
4
  - node: anyhost-01
5
5
  ---
6
6
  anyhost-01:
7
- host: 127.0.0.1
7
+ host: 172.17.42.1
8
8
  ssh_opts:
9
9
  port: 22222
10
10
  user: tester
@@ -6,6 +6,7 @@ PROJECT_NAME=rundock_spec
6
6
  PLATFORM_NAME=centos6
7
7
  PLATFORM_DIR="${PROJECT_ROOT}/platforms/${PLATFORM_NAME}"
8
8
  DOCKER_IMAGE_NAME="${PROJECT_NAME}/${PLATFORM_NAME}"
9
+ DOCKER_ADDRESS="172.17.42.1"
9
10
  DOCKER_CACHE_DIR="${HOME}/docker"
10
11
  DOCKER_CACHE_IMAGE_PATH="${DOCKER_CACHE_DIR}/${PLATFORM_NAME}.tar"
11
12
  DOCKER_SSH_PORT=22222
@@ -15,12 +16,17 @@ DOCKER_SSH_KEY_PUBLIC_LOCAL="${HOME}/.ssh/id_rsa_${PROJECT_NAME}_${PLATFORM_NAME
15
16
  DOCKER_SSH_KEY_PUBLIC_REMOTE="${PLATFORM_DIR}/authorized_keys"
16
17
  DOCKER_SSH_CONFIG="${HOME}/.ssh/config_${PROJECT_NAME}_${PLATFORM_NAME}"
17
18
  RUNDOCK_SCENARIO_DIR="${PROJECT_ROOT}/scenarios"
19
+ RUNDOCK_GROUP_DIR="${PROJECT_ROOT}/groups"
18
20
  RUNDOCK_CACHE_DIR="${HOME}/.rundock/${PLATFORM_NAME}"
19
21
  RUNDOCK_DEFAULT_SSH_YML="${RUNDOCK_CACHE_DIR}/integration_default_ssh.yml"
20
22
  RUNDOCK_SCENARIO_CACHE_DIR="${RUNDOCK_CACHE_DIR}/scenarios"
23
+ RUNDOCK_GROUP_CACHE_DIR="${RUNDOCK_CACHE_DIR}/groups"
21
24
 
22
25
  if [ "${1}x" = "--cleanx" ];then
23
26
  if sudo docker ps | grep "${DOCKER_IMAGE_NAME}" > /dev/null; then
27
+ rm -f "/var/tmp/hello_rundock*"
28
+ rm -f "${RUNDOCK_SCENARIO_CACHE_DIR}/*.yml"
29
+ rm -f "${RUNDOCK_GROUP_CACHE_DIR}/*.yml"
24
30
  rm -f "${DOCKER_CACHE_IMAGE_PATH}"
25
31
  rm -f "${DOCKER_SSH_KEY_PRIVATE}"
26
32
  rm -f "${DOCKER_SSH_KEY_PUBLIC_LOCAL}"
@@ -34,6 +40,7 @@ if [ "${1}x" = "--cleanx" ];then
34
40
  fi
35
41
 
36
42
  mkdir -p "${RUNDOCK_SCENARIO_CACHE_DIR}"
43
+ mkdir -p "${RUNDOCK_GROUP_CACHE_DIR}"
37
44
 
38
45
  if [ ! -f ${RUNDOCK_DEFAULT_SSH_YML} ]; then
39
46
  (
@@ -47,8 +54,11 @@ EOP
47
54
  fi
48
55
 
49
56
  cp ${RUNDOCK_SCENARIO_DIR}/* ${RUNDOCK_SCENARIO_CACHE_DIR}
57
+ cp ${RUNDOCK_GROUP_DIR}/* ${RUNDOCK_GROUP_CACHE_DIR}
50
58
 
51
- find ${RUNDOCK_SCENARIO_CACHE_DIR} -type f -name "*_scenario.yml" -or -name "*_group.yml" | \
59
+ find ${RUNDOCK_SCENARIO_CACHE_DIR} -type f -name "*_scenario.yml" | \
60
+ xargs sed -i -e "s#<replaced_by_platforms>#${DOCKER_SSH_KEY_PRIVATE}#g"
61
+ find ${RUNDOCK_GROUP_CACHE_DIR} -type f -name "*_group.yml" | \
52
62
  xargs sed -i -e "s#<replaced_by_platforms>#${DOCKER_SSH_KEY_PRIVATE}#g"
53
63
 
54
64
  sudo docker ps | grep "${DOCKER_IMAGE_NAME}" && { echo "docker image is already standing."; exit 0; }
@@ -68,10 +78,10 @@ sudo docker build -t "${DOCKER_IMAGE_NAME}" ${PLATFORM_DIR}
68
78
  rm -f ${DOCKER_SSH_KEY_PUBLIC_REMOTE}
69
79
  mkdir -p ${DOCKER_CACHE_DIR}
70
80
  sudo docker save "${DOCKER_IMAGE_NAME}" > ${DOCKER_CACHE_IMAGE_PATH}
71
- sudo docker run -d --privileged -p ${DOCKER_SSH_PORT}:22 "${DOCKER_IMAGE_NAME}"
81
+ sudo docker run -d --privileged -p ${DOCKER_ADDRESS}:${DOCKER_SSH_PORT}:22 "${DOCKER_IMAGE_NAME}"
72
82
 
73
83
  echo "Host ${PLATFORM_NAME}" > $DOCKER_SSH_CONFIG
74
- echo " HostName 127.0.0.1" >> $DOCKER_SSH_CONFIG
84
+ echo " HostName ${DOCKER_ADDRESS}" >> $DOCKER_SSH_CONFIG
75
85
  echo " User ${DOCKER_SSH_USER}" >> $DOCKER_SSH_CONFIG
76
86
  echo " Port ${DOCKER_SSH_PORT}" >> $DOCKER_SSH_CONFIG
77
87
  echo " IdentityFile ${DOCKER_SSH_KEY_PRIVATE}" >> $DOCKER_SSH_CONFIG
@@ -0,0 +1,14 @@
1
+ - node: localhost
2
+ command:
3
+ - errexit: false
4
+ - "rm /noexistdir/noexistfile1"
5
+ - "rm /noexistdir/noexistfile2"
6
+ task:
7
+ - err_task
8
+ ---
9
+ ---
10
+ err_task:
11
+ command:
12
+ - "uname -a"
13
+ - errexit: false
14
+ - "rm /noexistdir/noexistfile2"
@@ -6,4 +6,5 @@
6
6
  ---
7
7
  ---
8
8
  write_echo:
9
- - "echo 'Hello Rundock from Scenario.' > /var/tmp/hello_rundock_from_scenario"
9
+ command:
10
+ - "echo 'Hello Rundock from Scenario.' > /var/tmp/hello_rundock_from_scenario"
@@ -14,20 +14,22 @@
14
14
  - write_echo
15
15
  ---
16
16
  anyhost-01:
17
- host: 127.0.0.1
17
+ host: 172.17.42.1
18
18
  ssh_opts:
19
19
  port: 22222
20
20
  user: tester
21
21
  key: "<replaced_by_platforms>"
22
22
  anyhost-02:
23
- host: "127.0.0.1"
23
+ host: "172.17.42.1"
24
24
  ssh_opts:
25
25
  port: 22222
26
26
  user: tester
27
27
  keys: ["<replaced_by_platforms>"]
28
28
  ---
29
29
  echo_platform:
30
- - "hostname"
31
- - "uname -a"
30
+ command:
31
+ - "hostname"
32
+ - "uname -a"
32
33
  write_echo:
33
- - "echo 'Hello Rundock from Scenario.' > /var/tmp/hello_rundock_from_scenario"
34
+ command:
35
+ - "echo 'Hello Rundock from Scenario.' > /var/tmp/hello_rundock_from_scenario"
@@ -9,6 +9,7 @@ if ENV['TARGET_HOST'] != 'localhost'
9
9
  options = Net::SSH::Config.for(host, ["#{ENV['HOME']}/.ssh/config_rundock_spec_#{ENV['TARGET_HOST']}"])
10
10
 
11
11
  options[:user] ||= Etc.getlogin
12
+ options[:paranoid] = false
12
13
 
13
14
  set :host, options[:host_name] || host
14
15
  set :ssh_options, options
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rundock
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - hiracy
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2015-07-14 00:00:00.000000000 Z
11
+ date: 2015-07-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -155,6 +155,7 @@ files:
155
155
  - lib/rundock/builder/backend_builder.rb
156
156
  - lib/rundock/builder/base.rb
157
157
  - lib/rundock/builder/default_ssh_builder.rb
158
+ - lib/rundock/builder/operation_builder.rb
158
159
  - lib/rundock/builder/scenario_builder.rb
159
160
  - lib/rundock/cli.rb
160
161
  - lib/rundock/ext/hash.rb
@@ -170,14 +171,15 @@ files:
170
171
  - lib/rundock/version.rb
171
172
  - rundock.gemspec
172
173
  - scenario_sample.yml
174
+ - spec/integration/groups/simple_host_group.yml
173
175
  - spec/integration/platforms/centos6/Dockerfile
174
176
  - spec/integration/platforms/centos6/setup.sh
177
+ - spec/integration/platforms/localhost/scenarios/run_anyway_scenario.yml
175
178
  - spec/integration/platforms/localhost/scenarios/simple_echo_scenario.yml
176
179
  - spec/integration/platforms/localhost/scenarios/use_default_ssh_scenario.yml
177
180
  - spec/integration/recipes/simple_echo_scenario_spec.rb
178
181
  - spec/integration/recipes/simple_echo_spec.rb
179
182
  - spec/integration/scenarios/simple_echo_scenario.yml
180
- - spec/integration/scenarios/simple_host_group.yml
181
183
  - spec/integration/scenarios/use_default_ssh_scenario.yml
182
184
  - spec/integration/spec_helper.rb
183
185
  homepage: https://github.com/hiracy/rundock
@@ -203,5 +205,5 @@ rubyforge_project:
203
205
  rubygems_version: 2.4.5
204
206
  signing_key:
205
207
  specification_version: 4
206
- summary: Simple Execution framework for various servers
208
+ summary: Simple and extensible server operation framework
207
209
  test_files: []