rundock 0.1.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.
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"