rundock 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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"
|