rundock 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +39 -0
  3. data/.rspec +2 -0
  4. data/.rubocop.yml +49 -0
  5. data/.travis.yml +3 -0
  6. data/CHANGELOG.md +3 -0
  7. data/Gemfile +4 -0
  8. data/LICENSE +22 -0
  9. data/README.md +74 -0
  10. data/Rakefile +137 -0
  11. data/bin/console +14 -0
  12. data/bin/setup +7 -0
  13. data/circle.yml +11 -0
  14. data/default_ssh.yml +8 -0
  15. data/exe/rundock +4 -0
  16. data/lib/rundock/backend.rb +130 -0
  17. data/lib/rundock/cli.rb +50 -0
  18. data/lib/rundock/ext/hash.rb +23 -0
  19. data/lib/rundock/ext/object/blank.rb +45 -0
  20. data/lib/rundock/logger.rb +106 -0
  21. data/lib/rundock/node.rb +27 -0
  22. data/lib/rundock/operation/base.rb +20 -0
  23. data/lib/rundock/operation/command.rb +11 -0
  24. data/lib/rundock/operation/task.rb +16 -0
  25. data/lib/rundock/operation_factory.rb +30 -0
  26. data/lib/rundock/runner.rb +182 -0
  27. data/lib/rundock/scenario.rb +7 -0
  28. data/lib/rundock/version.rb +3 -0
  29. data/lib/rundock.rb +17 -0
  30. data/rundock.gemspec +30 -0
  31. data/scenario_sample.yml +53 -0
  32. data/spec/integration/platforms/centos6/Dockerfile +16 -0
  33. data/spec/integration/platforms/centos6/setup.sh +78 -0
  34. data/spec/integration/platforms/localhost/scenarios/simple_echo_scenario.yml +9 -0
  35. data/spec/integration/platforms/localhost/scenarios/use_default_ssh_scenario.yml +4 -0
  36. data/spec/integration/recipes/simple_echo_scenario_spec.rb +6 -0
  37. data/spec/integration/recipes/simple_echo_spec.rb +6 -0
  38. data/spec/integration/scenarios/simple_echo_scenario.yml +33 -0
  39. data/spec/integration/scenarios/use_default_ssh_scenario.yml +4 -0
  40. data/spec/integration/spec_helper.rb +19 -0
  41. metadata +202 -0
@@ -0,0 +1,106 @@
1
+ require 'rundock'
2
+ require 'logger'
3
+ require 'ansi/code'
4
+
5
+ module Rundock
6
+ module Logger
7
+ class Formatter
8
+ attr_accessor :colored
9
+ attr_accessor :indent_depth
10
+ attr_accessor :color
11
+
12
+ def initialize(*args)
13
+ super
14
+ @indent_depth = 0
15
+ end
16
+
17
+ def call(severity, datetime, progname, msg)
18
+ out = "[%5s:] %s%s\n" % [severity, ' ' * 2 * indent_depth, msg2str(msg)]
19
+ if colored
20
+ colorize(out, severity)
21
+ else
22
+ out
23
+ end
24
+ end
25
+
26
+ def indent
27
+ add_indent
28
+ yield
29
+ ensure
30
+ reduce_indent
31
+ end
32
+
33
+ def add_indent
34
+ @indent_depth += 1
35
+ end
36
+
37
+ def reduce_indent
38
+ @indent_depth -= 1 if @indent_depth > 0
39
+ end
40
+
41
+ def color(code)
42
+ prev_color = @color
43
+ @color = code
44
+ yield
45
+ ensure
46
+ @color = prev_color
47
+ end
48
+
49
+ private
50
+
51
+ def msg2str(msg)
52
+ case msg
53
+ when ::String
54
+ msg
55
+ when ::Exception
56
+ "#{msg.message} (#{msg.class})\n" << (msg.backtrace || []).join("\n")
57
+ else
58
+ msg.inspect
59
+ end
60
+ end
61
+
62
+ def colorize(msg, severity)
63
+ if @color
64
+ col = @color
65
+ else
66
+ col = case severity
67
+ when 'INFO'
68
+ :clear
69
+ when 'WARN'
70
+ :yellow
71
+ when 'ERROR'
72
+ :red
73
+ else
74
+ :clear
75
+ end
76
+ end
77
+
78
+ ANSI.public_send(col) { msg }
79
+ end
80
+ end
81
+
82
+ class << self
83
+ def logger
84
+ @logger ||= create_logger
85
+ end
86
+
87
+ private
88
+
89
+ def create_logger
90
+ ::Logger.new($stdout).tap do |logger|
91
+ logger.formatter = Formatter.new
92
+ end
93
+ end
94
+
95
+ private
96
+
97
+ def respond_to_missing?(method, include_private = false)
98
+ logger.respond_to?(method)
99
+ end
100
+
101
+ def method_missing(method, *args, &block)
102
+ logger.public_send(method, *args, &block)
103
+ end
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,27 @@
1
+ require 'rundock'
2
+
3
+ module Rundock
4
+ class Node
5
+ attr_reader :name
6
+ attr_reader :operations
7
+ attr_reader :backend
8
+
9
+ def initialize(name, backend)
10
+ @name = name
11
+ @backend = backend
12
+ end
13
+
14
+ def add_operation(ope)
15
+ @operations = [] unless @operations
16
+ @operations << ope
17
+ end
18
+
19
+ def run
20
+ Logger.debug("run name: #{@name}")
21
+ @operations.each do |ope|
22
+ Logger.debug("operation type: #{ope.class}")
23
+ ope.run(@backend, ope.attributes)
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,20 @@
1
+ module Rundock
2
+ module Operation
3
+ class Base
4
+ OperationNotImplementedError = Class.new(NotImplementedError)
5
+
6
+ attr_reader :instruction
7
+ attr_reader :attributes
8
+
9
+ def initialize(instruction, attributes)
10
+ @instruction = instruction
11
+ @attributes = attributes
12
+ @attributes = {} unless attributes
13
+ end
14
+
15
+ def run(backend, attributes = {})
16
+ raise OperationNotImplementedError
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,11 @@
1
+ module Rundock
2
+ module Operation
3
+ class Command < Base
4
+ def run(backend, attributes = {})
5
+ @instruction.each do |i|
6
+ backend.run_commands(i, attributes)
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,16 @@
1
+ module Rundock
2
+ module Operation
3
+ class Task < Base
4
+ def run(backend, attributes = {})
5
+ @instruction.each do |i|
6
+ unless attributes.key?(i)
7
+ Logger.warn("[WARN]task not found and ignored: #{i}")
8
+ next
9
+ end
10
+
11
+ backend.run_commands(attributes[i])
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,30 @@
1
+ module Rundock
2
+ class OperationFactory
3
+ OperationNotImplementedError = Class.new(NotImplementedError)
4
+
5
+ def self.instance(type)
6
+ self.new(type)
7
+ end
8
+
9
+ def initialize(type)
10
+ @type = type
11
+ end
12
+
13
+ def create(instruction, attributes)
14
+ klass = "Rundock::Operation::#{@type.to_s.to_camel_case}"
15
+ raise OperationNotImplementedError unless Rundock::Operation::Base.subclasses.map(&:to_s).include?(klass)
16
+
17
+ obj = nil
18
+ klass.split('::').map do |k|
19
+ if obj.nil?
20
+ obj = Kernel.const_get(k)
21
+ else
22
+ obj = obj.const_get(k)
23
+ end
24
+ end
25
+
26
+ operation = obj.new(instruction, attributes)
27
+ operation
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,182 @@
1
+ require 'rundock'
2
+ require 'yaml'
3
+ require 'tempfile'
4
+ require 'open-uri'
5
+
6
+ module Rundock
7
+ class Runner
8
+ PRESET_SSH_OPTIONS_DEFAULT_FILE_PATH = "#{Gem::Specification.find_by_path('rundock').full_gem_path}/default_ssh.yml"
9
+ ScenarioNotFoundError = Class.new(StandardError)
10
+ CommandArgNotFoundError = Class.new(StandardError)
11
+
12
+ class << self
13
+ def run(options)
14
+ Logger.info 'Starting Rundoc:'
15
+
16
+ runner = self.new(options)
17
+ runner.build(options)
18
+ runner.run
19
+ end
20
+ end
21
+
22
+ attr_reader :backend
23
+ attr_reader :scenario
24
+
25
+ def initialize(options)
26
+ @options = options
27
+ end
28
+
29
+ def run
30
+ @scenario.run
31
+ end
32
+
33
+ def build(options)
34
+ if options['scenario_yaml']
35
+ unless FileTest.exist?(options['scenario_yaml'])
36
+ raise ScenarioNotFoundError, "'#{options['scenario_yaml']}' scenario file is not found."
37
+ end
38
+
39
+ # parse scenario
40
+ if options['scenario_yaml'] =~ %r{^(http|https)://}
41
+ # read from http/https
42
+ open(options['scenario_yaml']) do |f|
43
+ @scenario = parse_scenario(f, options)
44
+ end
45
+ else
46
+ File.open(options['scenario_yaml']) do |f|
47
+ @scenario = parse_scenario(f, options)
48
+ end
49
+ end
50
+ else
51
+ @scenario = parse_scenario(nil, options)
52
+ end
53
+ end
54
+
55
+ private
56
+
57
+ def parse_default_ssh(options)
58
+ opts = {}
59
+
60
+ if options['default_ssh_opts_yaml'] && FileTest.exist?(options['default_ssh_opts_yaml'])
61
+ def_ssh_file = options['default_ssh_opts_yaml']
62
+ else
63
+ def_ssh_file = PRESET_SSH_OPTIONS_DEFAULT_FILE_PATH
64
+ end
65
+
66
+ File.open(def_ssh_file) do |f|
67
+ YAML.load_documents(f) do |y|
68
+ y.each do |k, v|
69
+ opts["#{k}_ssh_default"] = v
70
+ end
71
+ end
72
+ end
73
+
74
+ opts
75
+ end
76
+
77
+ def parse_scenario(scen_file, options)
78
+ # parse default ssh file
79
+ opts = parse_default_ssh(options)
80
+ opts.merge!(options)
81
+
82
+ scen = Scenario.new
83
+
84
+ # no use scenario file
85
+ if opts['host']
86
+ scen << build_no_scenario_node_operation(opts)
87
+ return scen
88
+ end
89
+
90
+ type = [:main, :node_info, :tasks]
91
+ scenario_data = {}
92
+
93
+ if scen_file
94
+ YAML.load_documents(scen_file).each_with_index do |data, idx|
95
+ scenario_data[type[idx]] = data
96
+ end
97
+ end
98
+
99
+ node = nil
100
+
101
+ # use scenario file
102
+ scenario_data[:main].each do |n|
103
+ scen << node if node
104
+
105
+ n.each do |k, v|
106
+ if k == 'node'
107
+ node = Node.new(
108
+ v,
109
+ build_backend(v, scenario_data[:node_info], opts))
110
+ else
111
+ ope = build_operations(k, v, scenario_data[:tasks], opts)
112
+ node.add_operation(ope) if node
113
+ end
114
+ end
115
+ end
116
+
117
+ scen << node if node
118
+ scen
119
+ end
120
+
121
+ def build_no_scenario_node_operation(options)
122
+ raise CommandArgNotFoundError, %("--command or -c" option is not specified.) unless options['command']
123
+
124
+ node_info = { options['host'] => { 'ssh_opts' => {} } }
125
+
126
+ %w(user key port ssh_config ask_password sudo).each { |o| node_info[options['host']]['ssh_opts'][o] = options[o] if options[o] }
127
+
128
+ node = Node.new(options['host'], build_backend(options['host'], node_info, options))
129
+ node.add_operation(Rundock::OperationFactory.instance(:command).create(Array(options['command']), nil))
130
+ node
131
+ end
132
+
133
+ def build_operations(ope_type, ope_content, tasks, options)
134
+ if options['command']
135
+ Logger.debug(%("--command or -c" option is specified and ignore scenario file.))
136
+ return Rundock::OperationFactory.instance(:command).create(Array(options['command']), nil)
137
+ end
138
+
139
+ Rundock::OperationFactory.instance(ope_type.to_sym).create(Array(ope_content), tasks)
140
+ end
141
+
142
+ def build_backend(host, node_info, options)
143
+ opts = {}
144
+
145
+ if !node_info ||
146
+ !node_info[host]
147
+ node_info = { host => {} }
148
+ end
149
+ node_info[host]['ssh_opts'] = {} unless node_info[host]['ssh_opts']
150
+ is_local = host =~ /localhost|127\.0\.0\.1/
151
+
152
+ # replace default ssh options if exists
153
+ options.keys.select { |o| o =~ /(\w+)_ssh_default$/ }.each do |oo|
154
+ opt = oo.gsub(/_ssh_default/, '')
155
+ # no use default ssh options if local
156
+ # (like docker or localhost with port access host should not use default ssh options)
157
+ node_info[host]['ssh_opts'][opt] = options[oo] if !is_local && !node_info[host]['ssh_opts'][opt]
158
+ end
159
+
160
+ if is_local &&
161
+ !node_info[host]['ssh_opts']['port'] &&
162
+ !node_info[host]['ssh_opts']['user'] &&
163
+ !node_info[host]['ssh_opts']['ssh_config']
164
+ backend_type = :local
165
+ else
166
+ backend_type = :ssh
167
+ opts['host'] = host
168
+ end
169
+
170
+ opts.merge!(options)
171
+
172
+ # update ssh options for node from node_info
173
+ opts.merge!(node_info[host]['ssh_opts'])
174
+ # delete trash ssh_options(node[host::ssh_options])
175
+ node_info[host].delete('ssh_opts')
176
+
177
+ # add any attributes for host from node_info
178
+ opts.merge!(node_info[host])
179
+ Backend.create(backend_type, opts)
180
+ end
181
+ end
182
+ end
@@ -0,0 +1,7 @@
1
+ module Rundock
2
+ class Scenario < Array
3
+ def run
4
+ self.each(&:run)
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,3 @@
1
+ module Rundock
2
+ VERSION = '0.1.0'
3
+ end
data/lib/rundock.rb ADDED
@@ -0,0 +1,17 @@
1
+ require 'rundock/version'
2
+ require 'rundock/ext/object/blank'
3
+ require 'rundock/ext/hash'
4
+ require 'rundock/logger'
5
+ require 'rundock/operation/base'
6
+ require 'rundock/operation/task'
7
+ require 'rundock/operation/command'
8
+ require 'rundock/operation_factory'
9
+ require 'rundock/node'
10
+ require 'rundock/scenario'
11
+ require 'rundock/backend'
12
+ require 'rundock/runner'
13
+ require 'rundock/cli'
14
+
15
+ module Rundock
16
+ # Your code goes here...
17
+ end
data/rundock.gemspec ADDED
@@ -0,0 +1,30 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'rundock/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'rundock'
8
+ spec.version = Rundock::VERSION
9
+ spec.authors = ['hiracy']
10
+ spec.email = ['leizhen@mbr.nifty.com']
11
+
12
+ spec.summary = 'Simple Execution framework for various servers'
13
+ spec.homepage = 'https://github.com/hiracy/rundock'
14
+ spec.license = 'MIT'
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.bindir = 'exe'
18
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
19
+ spec.require_paths = ['lib']
20
+
21
+ spec.add_development_dependency 'bundler', '~> 1.9'
22
+ spec.add_development_dependency 'rake', '~> 10.0'
23
+ spec.add_development_dependency 'serverspec', '~> 2.1'
24
+ spec.add_development_dependency 'rubocop'
25
+
26
+ spec.add_runtime_dependency 'specinfra', ['>= 2.31.0', '< 3.0.0']
27
+ spec.add_runtime_dependency 'ansi'
28
+ spec.add_runtime_dependency 'thor'
29
+ spec.add_runtime_dependency 'net-ssh'
30
+ end
@@ -0,0 +1,53 @@
1
+ #
2
+ # This file is example of rundock scenario file based on yaml format.
3
+ #
4
+ # -------------------------------------------------------------------
5
+ # ### scenario section ###
6
+ # - node: <nodename>
7
+ # <taskname>:
8
+ # - <task detail>
9
+ # - :
10
+ # <taskname>:
11
+ # - <task detail>
12
+ # - :
13
+ # - node: <nodename>
14
+ # :
15
+ # ---
16
+ # ### host information section ###
17
+ # <hostname>:
18
+ # host: xxx.xxx.xxx.xxx
19
+ # <other_attributes>:
20
+ # :
21
+ # <hostname>:
22
+ # :
23
+ # ---
24
+ # ### task information section ###
25
+ # <taskname>:
26
+ # - "<actual command>"
27
+ # - :
28
+ # <taskname>:
29
+ # :
30
+ # -------------------------------------------------------------------
31
+ #
32
+
33
+ - node: 127.0.0.1
34
+ command:
35
+ - "hostname"
36
+ - "uname -a"
37
+ - node: anyhost-01
38
+ task:
39
+ - echo_platform
40
+ - echo_users
41
+ ---
42
+ anyhost-01:
43
+ host: 192.168.1.11
44
+ ssh_opts:
45
+ port: 22
46
+ user: anyuser
47
+ ---
48
+ echo_platform:
49
+ - "hostname"
50
+ - "uname -a"
51
+ echo_users:
52
+ - "whoami"
53
+ - "w"
@@ -0,0 +1,16 @@
1
+ FROM centos:6
2
+
3
+ RUN yum install -y yum install openssh openssh-server openssh-clients sudo
4
+ RUN useradd tester
5
+ RUN echo "tester" | passwd --stdin tester
6
+ RUN mkdir -p /home/tester/.ssh; chown tester /home/tester/.ssh; chmod 700 /home/tester/.ssh
7
+ ADD authorized_keys /home/tester/.ssh/
8
+ RUN chown tester /home/tester/.ssh/authorized_keys; chmod 600 /home/tester/.ssh/authorized_keys
9
+ RUN echo "tester ALL=(ALL) ALL" >> /etc/sudoers.d/tester
10
+ RUN sed -ri 's/UsePAM yes/#UsePAM yes/g' /etc/ssh/sshd_config
11
+ RUN sed -ri 's/#UsePAM no/UsePAM no/g' /etc/ssh/sshd_config
12
+ RUN sed -ri 's/PasswordAuthentication yes/PasswordAuthentication no/g' /etc/ssh/sshd_config
13
+ RUN /etc/init.d/sshd start
14
+ RUN /etc/init.d/sshd stop
15
+
16
+ CMD /usr/sbin/sshd -D
@@ -0,0 +1,78 @@
1
+ #!/bin/sh
2
+
3
+ set -e
4
+ PROJECT_ROOT="spec/integration"
5
+ PROJECT_NAME=rundock_spec
6
+ PLATFORM_NAME=centos6
7
+ PLATFORM_DIR="${PROJECT_ROOT}/platforms/${PLATFORM_NAME}"
8
+ DOCKER_IMAGE_NAME="${PROJECT_NAME}/${PLATFORM_NAME}"
9
+ DOCKER_CACHE_DIR="${HOME}/docker"
10
+ DOCKER_CACHE_IMAGE_PATH="${DOCKER_CACHE_DIR}/${PLATFORM_NAME}.tar"
11
+ DOCKER_SSH_PORT=22222
12
+ DOCKER_SSH_USER=tester
13
+ DOCKER_SSH_KEY_PRIVATE="${HOME}/.ssh/id_rsa_${PROJECT_NAME}_${PLATFORM_NAME}_tmp"
14
+ DOCKER_SSH_KEY_PUBLIC_LOCAL="${HOME}/.ssh/id_rsa_${PROJECT_NAME}_${PLATFORM_NAME}_tmp.pub"
15
+ DOCKER_SSH_KEY_PUBLIC_REMOTE="${PLATFORM_DIR}/authorized_keys"
16
+ DOCKER_SSH_CONFIG="${HOME}/.ssh/config_${PROJECT_NAME}_${PLATFORM_NAME}"
17
+ RUNDOCK_SCENARIO_DIR="${PROJECT_ROOT}/scenarios"
18
+ RUNDOCK_CACHE_DIR="${HOME}/.rundock/${PLATFORM_NAME}"
19
+ RUNDOCK_DEFAULT_SSH_YML="${RUNDOCK_CACHE_DIR}/integration_default_ssh.yml"
20
+ RUNDOCK_SCENARIO_CACHE_DIR="${RUNDOCK_CACHE_DIR}/scenarios"
21
+
22
+ if [ "${1}x" = "--cleanx" ];then
23
+ if sudo docker ps | grep "${DOCKER_IMAGE_NAME}" > /dev/null; then
24
+ rm -f "${DOCKER_CACHE_IMAGE_PATH}"
25
+ rm -f "${DOCKER_SSH_KEY_PRIVATE}"
26
+ rm -f "${DOCKER_SSH_KEY_PUBLIC_LOCAL}"
27
+ rm -f "${DOCKER_SSH_CONFIG}"
28
+ rm -f ${DOCKER_SSH_KEY_PUBLIC_REMOTE}
29
+ set +x
30
+ sudo docker ps -q | xargs sudo docker rm -f
31
+ fi
32
+
33
+ exit 0
34
+ fi
35
+
36
+ mkdir -p "${RUNDOCK_SCENARIO_CACHE_DIR}"
37
+
38
+ if [ ! -f ${RUNDOCK_DEFAULT_SSH_YML} ]; then
39
+ (
40
+ cat << EOP
41
+ :port: ${DOCKER_SSH_PORT}
42
+ :paranoid: false
43
+ :user: "${DOCKER_SSH_USER}"
44
+ :keys: ["${DOCKER_SSH_KEY_PRIVATE}"]
45
+ EOP
46
+ ) > ${RUNDOCK_DEFAULT_SSH_YML}
47
+ fi
48
+
49
+ cp ${RUNDOCK_SCENARIO_DIR}/* ${RUNDOCK_SCENARIO_CACHE_DIR}
50
+
51
+ find ${RUNDOCK_SCENARIO_CACHE_DIR} -type f -name "*_scenario.yml" | \
52
+ xargs sed -i -e "s#<replaced_by_platforms>#${DOCKER_SSH_KEY_PRIVATE}#g"
53
+
54
+ sudo docker ps | grep "${DOCKER_IMAGE_NAME}" && { echo "docker image is already standing."; exit 0; }
55
+
56
+ yes | ssh-keygen -N "" -t rsa -f ${DOCKER_SSH_KEY_PRIVATE}
57
+ cp ${DOCKER_SSH_KEY_PUBLIC_LOCAL} ${DOCKER_SSH_KEY_PUBLIC_REMOTE}
58
+
59
+ if sudo docker ps | grep "${DOCKER_IMAGE_NAME}" > /dev/null 2>&1; then
60
+ sudo docker ps -q | xargs sudo docker rm -f > /dev/null
61
+ fi
62
+
63
+ if file ${DOCKER_CACHE_IMAGE_PATH} | grep empty; then
64
+ sudo docker load --input ${DOCKER_CACHE_IMAGE_PATH}
65
+ fi
66
+
67
+ sudo docker build -t "${DOCKER_IMAGE_NAME}" ${PLATFORM_DIR}
68
+ rm -f ${DOCKER_SSH_KEY_PUBLIC_REMOTE}
69
+ mkdir -p ${DOCKER_CACHE_DIR}
70
+ sudo docker save "${DOCKER_IMAGE_NAME}" > ${DOCKER_CACHE_IMAGE_PATH}
71
+ sudo docker run -d --privileged -p ${DOCKER_SSH_PORT}:22 "${DOCKER_IMAGE_NAME}"
72
+
73
+ echo "Host ${PLATFORM_NAME}" > $DOCKER_SSH_CONFIG
74
+ echo " HostName 127.0.0.1" >> $DOCKER_SSH_CONFIG
75
+ echo " User ${DOCKER_SSH_USER}" >> $DOCKER_SSH_CONFIG
76
+ echo " Port ${DOCKER_SSH_PORT}" >> $DOCKER_SSH_CONFIG
77
+ echo " IdentityFile ${DOCKER_SSH_KEY_PRIVATE}" >> $DOCKER_SSH_CONFIG
78
+ echo " StrictHostKeyChecking no" >> $DOCKER_SSH_CONFIG
@@ -0,0 +1,9 @@
1
+ - node: localhost
2
+ command:
3
+ - "rm -f /var/tmp/hello_rundock_from_scenario"
4
+ task:
5
+ - write_echo
6
+ ---
7
+ ---
8
+ write_echo:
9
+ - "echo 'Hello Rundock from Scenario.' > /var/tmp/hello_rundock_from_scenario"
@@ -0,0 +1,4 @@
1
+ - node: localhost
2
+ command:
3
+ - "hostname"
4
+ - "uname -a"
@@ -0,0 +1,6 @@
1
+ require 'spec_helper'
2
+
3
+ describe file('/var/tmp/hello_rundock') do
4
+ it { should be_file }
5
+ its(:content) { should match(/Hello Rundock./) }
6
+ end
@@ -0,0 +1,6 @@
1
+ require 'spec_helper'
2
+
3
+ describe file('/var/tmp/hello_rundock_from_scenario') do
4
+ it { should be_file }
5
+ its(:content) { should match(/Hello Rundock from Scenario./) }
6
+ end
@@ -0,0 +1,33 @@
1
+ - node: localhost
2
+ command:
3
+ - "rm -f /var/tmp/hello_rundock_from_scenario"
4
+ - "echo 'Hello Rundock from Scenario.' > /var/tmp/hello_rundock_from_scenario"
5
+ - node: anyhost-01
6
+ task:
7
+ - echo_platform
8
+ command:
9
+ - "hostname"
10
+ - node: anyhost-02
11
+ command:
12
+ - "uname -a"
13
+ task:
14
+ - write_echo
15
+ ---
16
+ anyhost-01:
17
+ host: 127.0.0.1
18
+ ssh_opts:
19
+ port: 22222
20
+ user: tester
21
+ key: "<replaced_by_platforms>"
22
+ anyhost-02:
23
+ host: "127.0.0.1"
24
+ ssh_opts:
25
+ port: 22222
26
+ user: tester
27
+ keys: ["<replaced_by_platforms>"]
28
+ ---
29
+ echo_platform:
30
+ - "hostname"
31
+ - "uname -a"
32
+ write_echo:
33
+ - "echo 'Hello Rundock from Scenario.' > /var/tmp/hello_rundock_from_scenario"
@@ -0,0 +1,4 @@
1
+ - node: localhost
2
+ command:
3
+ - "hostname"
4
+ - "uname -a"