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.
- checksums.yaml +7 -0
- data/.gitignore +39 -0
- data/.rspec +2 -0
- data/.rubocop.yml +49 -0
- data/.travis.yml +3 -0
- data/CHANGELOG.md +3 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +74 -0
- data/Rakefile +137 -0
- data/bin/console +14 -0
- data/bin/setup +7 -0
- data/circle.yml +11 -0
- data/default_ssh.yml +8 -0
- data/exe/rundock +4 -0
- data/lib/rundock/backend.rb +130 -0
- data/lib/rundock/cli.rb +50 -0
- data/lib/rundock/ext/hash.rb +23 -0
- data/lib/rundock/ext/object/blank.rb +45 -0
- data/lib/rundock/logger.rb +106 -0
- data/lib/rundock/node.rb +27 -0
- data/lib/rundock/operation/base.rb +20 -0
- data/lib/rundock/operation/command.rb +11 -0
- data/lib/rundock/operation/task.rb +16 -0
- data/lib/rundock/operation_factory.rb +30 -0
- data/lib/rundock/runner.rb +182 -0
- data/lib/rundock/scenario.rb +7 -0
- data/lib/rundock/version.rb +3 -0
- data/lib/rundock.rb +17 -0
- data/rundock.gemspec +30 -0
- data/scenario_sample.yml +53 -0
- data/spec/integration/platforms/centos6/Dockerfile +16 -0
- data/spec/integration/platforms/centos6/setup.sh +78 -0
- data/spec/integration/platforms/localhost/scenarios/simple_echo_scenario.yml +9 -0
- data/spec/integration/platforms/localhost/scenarios/use_default_ssh_scenario.yml +4 -0
- data/spec/integration/recipes/simple_echo_scenario_spec.rb +6 -0
- data/spec/integration/recipes/simple_echo_spec.rb +6 -0
- data/spec/integration/scenarios/simple_echo_scenario.yml +33 -0
- data/spec/integration/scenarios/use_default_ssh_scenario.yml +4 -0
- data/spec/integration/spec_helper.rb +19 -0
- 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
|
data/lib/rundock/node.rb
ADDED
@@ -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,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
|
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
|
data/scenario_sample.yml
ADDED
@@ -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,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"
|