rbcm 0.0.11 → 0.0.12
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 +4 -4
- data/app/action/action.rb +3 -3
- data/app/action/command.rb +1 -1
- data/app/action/file.rb +8 -3
- data/app/action/list.rb +14 -14
- data/app/cli.rb +11 -11
- data/app/lib/aescrypt.rb +2 -2
- data/app/lib/array_hash.rb +2 -2
- data/app/lib/lib.rb +0 -10
- data/app/lib/options.rb +1 -1
- data/app/lib/params.rb +1 -1
- data/app/node/file.rb +6 -7
- data/app/node/filesystem.rb +2 -2
- data/app/node/job.rb +1 -1
- data/app/node/job_search.rb +1 -1
- data/app/node/node.rb +5 -5
- data/app/node/remote.rb +4 -4
- data/app/node/sandbox.rb +25 -16
- data/app/pool.rb +8 -0
- data/app/project/addon.rb +1 -1
- data/app/project/capability.rb +1 -1
- data/app/project/definition.rb +1 -1
- data/app/project/file.rb +6 -6
- data/app/project/project.rb +5 -5
- data/app/project/sandbox.rb +1 -1
- data/app/project/template.rb +2 -2
- data/app/project/template_list.rb +1 -1
- data/app/rbcm.rb +78 -75
- data/bin/rbcm +1 -1
- metadata +16 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 96bce981ffdae8328626cf5a431989237b2a852ad5cf99f1fe41b72cd8b07316
|
4
|
+
data.tar.gz: a56eb30ae086b3ac75ab71d149d2dc660dd02a3932dd26f81d1dd70e9e21ae92
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a45f56bec3da7c49f4f48450cd04b1cbe93593e72533f9981782c0a9da4524491628ba853dede679e3e24ed24744240e02d7a2c69924e59c77f5f862817e2ee2
|
7
|
+
data.tar.gz: d70b4ac03aa966e51798c6ec16e3fcfd486b1fc37cf2d4f639b4a2c402ca2c52701ff5f3f54d82a764fed1ce204d59e01f546751372a7e8cfe7f106c81c0ed7c
|
data/app/action/action.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
class Action
|
1
|
+
class RBCM::Action
|
2
2
|
attr_accessor :approved, :applied
|
3
3
|
attr_reader :triggered_by, :trigger, :chain, :dependencies,
|
4
4
|
:obsolete, :job, :check, :triggered, :result,
|
@@ -30,7 +30,7 @@ class Action
|
|
30
30
|
end
|
31
31
|
|
32
32
|
def checkable?
|
33
|
-
@check.any? or self.class == Action::File
|
33
|
+
@check.any? or self.class == RBCM::Action::File
|
34
34
|
end
|
35
35
|
|
36
36
|
def neccessary?
|
@@ -71,7 +71,7 @@ class Action
|
|
71
71
|
|
72
72
|
def approve! input=:y
|
73
73
|
if [:a, :y].include? input
|
74
|
-
@job.node.files[@path].content = content if self.class == Action::File
|
74
|
+
@job.node.files[@path].content = content if self.class == RBCM::Action::File
|
75
75
|
@approved = true
|
76
76
|
siblings.each.approve! if input == :a
|
77
77
|
@job.node.triggered << @trigger
|
data/app/action/command.rb
CHANGED
data/app/action/file.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
# ToDo: approve all changes to a spicific file at once
|
2
|
-
class Action::File < Action
|
2
|
+
class RBCM::Action::File < RBCM::Action
|
3
3
|
attr_reader :path, :content
|
4
4
|
|
5
5
|
def check!
|
@@ -8,7 +8,7 @@ class Action::File < Action
|
|
8
8
|
end
|
9
9
|
|
10
10
|
def obsolete
|
11
|
-
@job.node.files[path].content
|
11
|
+
@job.node.files[path].content == content
|
12
12
|
end
|
13
13
|
|
14
14
|
def siblings
|
@@ -17,7 +17,12 @@ class Action::File < Action
|
|
17
17
|
|
18
18
|
def apply!
|
19
19
|
@applied = true
|
20
|
-
|
20
|
+
#@result = @job.node.remote.execute("echo #{Shellwords.escape content} > #{path}")
|
21
|
+
@result = Net::SCP::upload!(@job.node.name, nil, StringIO.new(content), @params[0])
|
22
|
+
def @result.exitstatus
|
23
|
+
self.class == TrueClass ? 0 : 1
|
24
|
+
end
|
25
|
+
@result
|
21
26
|
end
|
22
27
|
|
23
28
|
def content
|
data/app/action/list.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
class ActionList < Array
|
1
|
+
class RBCM::ActionList < Array
|
2
2
|
def initialize array=[]
|
3
3
|
array.each do |element|
|
4
4
|
insert -1, element
|
@@ -10,7 +10,7 @@ class ActionList < Array
|
|
10
10
|
self.each do |action|
|
11
11
|
resolve_action_dependencies action
|
12
12
|
end
|
13
|
-
ActionList.new @actions
|
13
|
+
RBCM::ActionList.new @actions
|
14
14
|
end
|
15
15
|
|
16
16
|
def resolve_triggers
|
@@ -18,52 +18,52 @@ class ActionList < Array
|
|
18
18
|
self.each do |action|
|
19
19
|
resolve_action_triggers action
|
20
20
|
end
|
21
|
-
ActionList.new @actions
|
21
|
+
RBCM::ActionList.new @actions
|
22
22
|
end
|
23
23
|
|
24
24
|
def file path
|
25
|
-
ActionList.new select{|action| action.path == path}
|
25
|
+
RBCM::ActionList.new select{|action| action.path == path}
|
26
26
|
end
|
27
27
|
|
28
28
|
def node node_name
|
29
29
|
return self unless node_name
|
30
|
-
ActionList.new select{|action| action.job.node.name == node_name}
|
30
|
+
RBCM::ActionList.new select{|action| action.job.node.name == node_name}
|
31
31
|
end
|
32
32
|
|
33
33
|
def checkable
|
34
|
-
ActionList.new select.checkable?
|
34
|
+
RBCM::ActionList.new select.checkable?
|
35
35
|
end
|
36
36
|
|
37
37
|
def unneccessary
|
38
|
-
ActionList.new (self - neccessary)
|
38
|
+
RBCM::ActionList.new (self - neccessary)
|
39
39
|
end
|
40
40
|
|
41
41
|
def neccessary
|
42
|
-
ActionList.new select.neccessary?
|
42
|
+
RBCM::ActionList.new select.neccessary?
|
43
43
|
end
|
44
44
|
|
45
45
|
def approvable
|
46
|
-
ActionList.new select.approvable?
|
46
|
+
RBCM::ActionList.new select.approvable?
|
47
47
|
end
|
48
48
|
|
49
49
|
def approved
|
50
|
-
ActionList.new select.approved?
|
50
|
+
RBCM::ActionList.new select.approved?
|
51
51
|
end
|
52
52
|
|
53
53
|
def applyable
|
54
|
-
ActionList.new select.applyable?
|
54
|
+
RBCM::ActionList.new select.applyable?
|
55
55
|
end
|
56
56
|
|
57
57
|
def applied
|
58
|
-
ActionList.new select.applied?
|
58
|
+
RBCM::ActionList.new select.applied?
|
59
59
|
end
|
60
60
|
|
61
61
|
def succeeded
|
62
|
-
ActionList.new applied.select.succeeded?
|
62
|
+
RBCM::ActionList.new applied.select.succeeded?
|
63
63
|
end
|
64
64
|
|
65
65
|
def failed
|
66
|
-
ActionList.new applied.select.failed?
|
66
|
+
RBCM::ActionList.new applied.select.failed?
|
67
67
|
end
|
68
68
|
|
69
69
|
private
|
data/app/cli.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
|
-
class CLI
|
1
|
+
class RBCM::CLI
|
2
2
|
def initialize argv
|
3
3
|
render section: "RBCM starting", first: true
|
4
4
|
args = Hash[ argv.join(' ').scan(/--?([^=\s]+)(?:[=\s](\S+))?/) ]
|
5
5
|
render :args, content: args
|
6
6
|
# bootstrap
|
7
|
-
@rbcm = rbcm = RBCM.new argv[0] || `pwd`.chomp
|
7
|
+
@rbcm = rbcm = RBCM::Core.new argv[0] || `pwd`.chomp
|
8
8
|
render :project
|
9
9
|
render :capabilities
|
10
10
|
# parse
|
@@ -22,7 +22,7 @@ class CLI
|
|
22
22
|
approve action
|
23
23
|
if action.approved?
|
24
24
|
approve action.siblings
|
25
|
-
approve action.same_file if action.class == Action::File
|
25
|
+
approve action.same_file if action.class == RBCM::Action::File
|
26
26
|
end
|
27
27
|
end
|
28
28
|
# apply
|
@@ -38,9 +38,9 @@ class CLI
|
|
38
38
|
|
39
39
|
def check action
|
40
40
|
@action = action
|
41
|
-
if action.class == Action::Command
|
41
|
+
if action.class == RBCM::Action::Command
|
42
42
|
render checking: action.check.join("; ") if action.checkable?
|
43
|
-
elsif action.class == Action::File
|
43
|
+
elsif action.class == RBCM::Action::File
|
44
44
|
render checking: action.job.params[0]
|
45
45
|
end
|
46
46
|
action.check!
|
@@ -53,7 +53,7 @@ class CLI
|
|
53
53
|
next if not action.approvable?
|
54
54
|
render :siblings if action.siblings.any?
|
55
55
|
render :source if action.source.flatten.compact.any?
|
56
|
-
render :diff if action.class == Action::File
|
56
|
+
render :diff if action.class == RBCM::Action::File
|
57
57
|
render :prompt
|
58
58
|
sleep 0.25 unless [:a,:y,:n,:i].include? r = STDIN.getch.to_sym # avoid 'ctrl-c'-trap
|
59
59
|
(binding.pry; sleep 1) if r == :i
|
@@ -69,8 +69,7 @@ class CLI
|
|
69
69
|
@action = action
|
70
70
|
response = action.apply!
|
71
71
|
render :title, color: response.exitstatus == 0 ? :green : :red
|
72
|
-
render :
|
73
|
-
render response: response if response.length > 0
|
72
|
+
render response: response if response.to_s.length > 0 and action.class == RBCM::Action::Command
|
74
73
|
end
|
75
74
|
end
|
76
75
|
|
@@ -88,7 +87,7 @@ class CLI
|
|
88
87
|
elsif element == :capabilities
|
89
88
|
elsif element == :project
|
90
89
|
([@rbcm.project] + @rbcm.project.all_addons).each do |project|
|
91
|
-
out "┣━ #{project.class}#{" #{project.type}: #{project.name}" if project.class == Addon}"
|
90
|
+
out "┣━ #{project.class}#{" #{project.type}: #{project.name}" if project.class == RBCM::Addon}"
|
92
91
|
out prefix + "#{project.files.count} ruby files, #{project.templates.count} templates #{project.directories.count} directories, #{project.other.count} other files"
|
93
92
|
out prefix + "capabilities: #{project.capabilities.join(", ")}"
|
94
93
|
out prefix + "templates: #{project.templates.each.clean_path.join(", ")}"
|
@@ -122,14 +121,14 @@ class CLI
|
|
122
121
|
out prefix + Diffy::Diff.new(
|
123
122
|
@action.job.node.files[@action.path].content,
|
124
123
|
@action.content
|
125
|
-
).to_s(:color).split("\n").join("\n#{prefix
|
124
|
+
).to_s(:color).split("\n").join("\n#{prefix}")
|
126
125
|
elsif element == :approved
|
127
126
|
string = @action.approved? ? "#{format :green} APPROVED" : "#{format :red} DECLINED"
|
128
127
|
out "#{prefix} #{string} #{format} "
|
129
128
|
elsif element.class == String
|
130
129
|
out prefix + "#{element}"
|
131
130
|
elsif checking
|
132
|
-
out prefix + "
|
131
|
+
out prefix + "#{@action.job.node.name}: #{checking}"
|
133
132
|
elsif response
|
134
133
|
out prefix + response.to_s.chomp.split("\n").join("\n#{prefix}")
|
135
134
|
elsif element == :applied
|
@@ -143,6 +142,7 @@ class CLI
|
|
143
142
|
end
|
144
143
|
|
145
144
|
def out line
|
145
|
+
# `tput cols`
|
146
146
|
puts "\r#{line}"
|
147
147
|
end
|
148
148
|
|
data/app/lib/aescrypt.rb
CHANGED
@@ -55,7 +55,7 @@ module AESCrypt
|
|
55
55
|
#:arg: iv => String
|
56
56
|
#:arg: cipher_type => String
|
57
57
|
def self.decrypt_data(encrypted_data, key, iv, cipher_type)
|
58
|
-
aes = OpenSSL::Cipher.new(cipher_type)
|
58
|
+
aes = RBCM::OpenSSL::Cipher.new(cipher_type)
|
59
59
|
aes.decrypt
|
60
60
|
aes.key = key
|
61
61
|
aes.iv = iv if iv != nil
|
@@ -74,7 +74,7 @@ module AESCrypt
|
|
74
74
|
#:arg: iv => String
|
75
75
|
#:arg: cipher_type => String
|
76
76
|
def self.encrypt_data(data, key, iv, cipher_type)
|
77
|
-
aes = OpenSSL::Cipher.new(cipher_type)
|
77
|
+
aes = RBCM::OpenSSL::Cipher.new(cipher_type)
|
78
78
|
aes.encrypt
|
79
79
|
aes.key = key
|
80
80
|
aes.iv = iv if iv != nil
|
data/app/lib/array_hash.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# a hash which keys are initiated as arrays
|
2
|
-
# default values via
|
2
|
+
# default values via RBCM::`Hash.new []` are inadequate for being volatile
|
3
3
|
|
4
|
-
class ArrayHash < Hash
|
4
|
+
class RBCM::ArrayHash < Hash
|
5
5
|
def [] key
|
6
6
|
store key, [] unless has_key? key
|
7
7
|
super
|
data/app/lib/lib.rb
CHANGED
@@ -36,13 +36,3 @@ class Integer
|
|
36
36
|
end
|
37
37
|
end
|
38
38
|
end
|
39
|
-
|
40
|
-
# a hash which keys are initiated as arrays
|
41
|
-
# default values via `Hash.new []` are inadequate for being volatile
|
42
|
-
|
43
|
-
class ArrayHash < Hash
|
44
|
-
def [] key
|
45
|
-
store key, [] unless has_key? key
|
46
|
-
super
|
47
|
-
end
|
48
|
-
end
|
data/app/lib/options.rb
CHANGED
data/app/lib/params.rb
CHANGED
data/app/node/file.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
class Node::NodeFile
|
1
|
+
class RBCM::Node::NodeFile
|
2
2
|
def initialize path:, filesystem:
|
3
3
|
@path = path
|
4
4
|
@filesystem = filesystem
|
@@ -7,12 +7,11 @@ class Node::NodeFile
|
|
7
7
|
attr_writer :content, :user, :group, :mode
|
8
8
|
|
9
9
|
def content
|
10
|
-
@content ||=
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
)
|
10
|
+
@content ||= begin
|
11
|
+
result = Net::SCP::download!(@filesystem.node.name, nil, @path)
|
12
|
+
rescue Net::SCP::Error
|
13
|
+
result = ""
|
14
|
+
end
|
16
15
|
end
|
17
16
|
|
18
17
|
def diffable # TODO?
|
data/app/node/filesystem.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
class Node::NodeFilesystem
|
1
|
+
class RBCM::Node::NodeFilesystem
|
2
2
|
def initialize node, overlays: false
|
3
3
|
@node = node
|
4
4
|
@underlying = overlays
|
@@ -11,7 +11,7 @@ class Node::NodeFilesystem
|
|
11
11
|
if @underlying
|
12
12
|
@files[path] || @underlying[path]
|
13
13
|
else
|
14
|
-
@files[path] ||= Node::NodeFile.new path: path, filesystem: self
|
14
|
+
@files[path] ||= RBCM::Node::NodeFile.new path: path, filesystem: self
|
15
15
|
end
|
16
16
|
end
|
17
17
|
end
|
data/app/node/job.rb
CHANGED
data/app/node/job_search.rb
CHANGED
data/app/node/node.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
class Node
|
1
|
+
class RBCM::Node
|
2
2
|
attr_reader :jobs, :definitions, :files, :name, :remote, :rbcm, :sandbox,
|
3
3
|
:path
|
4
4
|
attr_accessor :actions, :memberships, :triggered
|
@@ -8,10 +8,10 @@ class Node
|
|
8
8
|
@name = name
|
9
9
|
@path = path
|
10
10
|
@definitions = []
|
11
|
-
@sandbox = Node::Sandbox.new self
|
12
|
-
@remote = Node::Remote.new self
|
13
|
-
@files = Node::NodeFilesystem.new self, overlays: @remote.files
|
14
|
-
@actions = ActionList.new
|
11
|
+
@sandbox = RBCM::Node::Sandbox.new self
|
12
|
+
@remote = RBCM::Node::Remote.new self
|
13
|
+
@files = RBCM::Node::NodeFilesystem.new self, overlays: @remote.files
|
14
|
+
@actions = RBCM::ActionList.new
|
15
15
|
@memberships = []
|
16
16
|
@jobs = []
|
17
17
|
@blocked_jobs = []
|
data/app/node/remote.rb
CHANGED
@@ -1,16 +1,16 @@
|
|
1
|
-
class Node::Remote
|
1
|
+
class RBCM::Node::Remote
|
2
2
|
def initialize node
|
3
3
|
@node = node
|
4
|
-
@files = Node::NodeFilesystem.new node
|
4
|
+
@files = RBCM::Node::NodeFilesystem.new node
|
5
5
|
end
|
6
6
|
|
7
7
|
attr_reader :node, :files
|
8
8
|
|
9
9
|
def execute action
|
10
|
-
@session ||= Net::SSH.start @node.name
|
10
|
+
@session ||= Net::SSH.start @node.name
|
11
11
|
@session.exec! action
|
12
12
|
end
|
13
13
|
end
|
14
14
|
|
15
|
-
# @session = Net::SSH.start 'test.ckn.li'
|
15
|
+
# @session = Net::SSH.start 'test.ckn.li'
|
16
16
|
# @session.exec!("ls").class
|
data/app/node/sandbox.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# runs a definition and catches jobs
|
2
2
|
# accepts definition-Proc and provides definition-Proc and job list
|
3
3
|
|
4
|
-
class Node::Sandbox
|
4
|
+
class RBCM::Node::Sandbox
|
5
5
|
attr_reader :content, :jobs
|
6
6
|
|
7
7
|
def initialize node
|
@@ -19,7 +19,7 @@ class Node::Sandbox
|
|
19
19
|
end
|
20
20
|
# wrap base_capabilities
|
21
21
|
[:file, :run].each do |base_capability|
|
22
|
-
__add_capability Project::Capability.new(
|
22
|
+
__add_capability RBCM::Project::Capability.new(
|
23
23
|
name: base_capability,
|
24
24
|
content: method(base_capability).unbind,
|
25
25
|
project_file: false
|
@@ -81,9 +81,13 @@ class Node::Sandbox
|
|
81
81
|
end
|
82
82
|
end
|
83
83
|
|
84
|
+
def localhost
|
85
|
+
# mark node as local
|
86
|
+
end
|
87
|
+
|
84
88
|
def run action, check: nil, tags: nil, trigger: nil, triggered_by: nil
|
85
89
|
__cache check: check, tags: tags, trigger: trigger, triggered_by: triggered_by, working_dirs: working_dir do
|
86
|
-
@node.actions << Action::Command.new(
|
90
|
+
@node.actions << RBCM::Action::Command.new(
|
87
91
|
job: @node.jobs.last,
|
88
92
|
line: action,
|
89
93
|
dependencies: @dependency_cache.dup,
|
@@ -101,20 +105,25 @@ class Node::Sandbox
|
|
101
105
|
run "mkdir -p #{File.dirname path}",
|
102
106
|
check: "ls #{File.dirname path}"
|
103
107
|
__cache tags: tags, trigger: trigger, triggered_by: triggered_by, working_dirs: working_dir do
|
104
|
-
@node.actions << Action::File.new(
|
108
|
+
@node.actions << RBCM::Action::File.new(
|
105
109
|
job: job,
|
106
|
-
params: Params.new([path], named),
|
110
|
+
params: RBCM::Params.new([path], named),
|
107
111
|
state: @cache.collect{|k,v| [k, v.dup]}.to_h
|
108
112
|
)
|
109
|
-
|
110
|
-
|
111
|
-
|
113
|
+
end if named.keys.include? :content or named.keys.include? :template
|
114
|
+
run "chmod #{named[:mode]} '#{path}'",
|
115
|
+
check: "stat -c '%a' * #{path} | grep -q #{named[:mode]}" if named[:mode]
|
116
|
+
run "chown #{named[:user]} '#{path}'",
|
117
|
+
check: "stat -c '%U' * #{path} | grep -q #{named[:user]}" if named[:user]
|
118
|
+
run "chown :#{named[:group]} '#{path}'",
|
119
|
+
check: "stat -c '%G' * #{path} | grep -q #{named[:group]}" if named[:group]
|
112
120
|
end
|
113
121
|
|
114
122
|
def dir path="", templates:, context: {}, tags: nil, trigger: nil, triggered_by: nil
|
123
|
+
templates.gsub! /!^/, ''
|
115
124
|
__cache tags: tags, trigger: trigger, triggered_by: triggered_by, working_dirs: working_dir do
|
116
125
|
@node.rbcm.project.templates.under("#{working_dir}/#{templates}").each do |template|
|
117
|
-
file template.clean_full_path.gsub(
|
126
|
+
file template.clean_full_path.gsub(/^#{working_dir}/, '').gsub(/^\/#{templates}/, ''),
|
118
127
|
template: template.clean_path,
|
119
128
|
context: context
|
120
129
|
end
|
@@ -123,8 +132,8 @@ class Node::Sandbox
|
|
123
132
|
|
124
133
|
def working_dir
|
125
134
|
@cache[:chain].select{ |i|
|
126
|
-
i.class == Project::Definition or (
|
127
|
-
i.class == Project::Capability and not [:file, :run].include? i.name
|
135
|
+
i.class == RBCM::Project::Definition or (
|
136
|
+
i.class == RBCM::Project::Capability and not [:file, :run].include? i.name
|
128
137
|
)
|
129
138
|
}.last.project_file.path.split("/")[0..-2].join("/")
|
130
139
|
end
|
@@ -137,7 +146,7 @@ class Node::Sandbox
|
|
137
146
|
def method_missing name, *named, **ordered, &block
|
138
147
|
#log "method #{name} missing on #{@name}"
|
139
148
|
capability_name = name[0..-2].to_sym
|
140
|
-
params = Params.new named, ordered
|
149
|
+
params = RBCM::Params.new named, ordered
|
141
150
|
if not @@capabilities.include? capability_name
|
142
151
|
super
|
143
152
|
elsif name =~ /\!$/
|
@@ -180,7 +189,7 @@ class Node::Sandbox
|
|
180
189
|
end
|
181
190
|
return r.collect &block if block_given? # no-each-syntax
|
182
191
|
return r
|
183
|
-
JobSearch.new r
|
192
|
+
RBCM::JobSearch.new r
|
184
193
|
end
|
185
194
|
|
186
195
|
def __cache trigger: nil, triggered_by: nil, params: nil, check: nil,
|
@@ -212,8 +221,8 @@ class Node::Sandbox
|
|
212
221
|
# define wrapper method
|
213
222
|
if capability.type == :regular
|
214
223
|
define_singleton_method capability.name do |*ordered, **named|
|
215
|
-
params = Params.new ordered, named
|
216
|
-
@node.jobs.append Node::Job.new(
|
224
|
+
params = RBCM::Params.new ordered, named
|
225
|
+
@node.jobs.append RBCM::Node::Job.new(
|
217
226
|
node: @node,
|
218
227
|
capability: capability,
|
219
228
|
params: params
|
@@ -238,7 +247,7 @@ class Node::Sandbox
|
|
238
247
|
else
|
239
248
|
raise "unknown capability type #{capability.type}"
|
240
249
|
end
|
241
|
-
# return JobSearch.new r
|
250
|
+
# return RBCM::JobSearch.new r
|
242
251
|
end
|
243
252
|
|
244
253
|
def self.capabilities
|
data/app/pool.rb
ADDED
data/app/project/addon.rb
CHANGED
data/app/project/capability.rb
CHANGED
data/app/project/definition.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# holds a definition on form of a proc to be executed in a nodes sandbox
|
2
2
|
|
3
|
-
class Project::Definition
|
3
|
+
class RBCM::Project::Definition
|
4
4
|
def initialize type:, name:, content:, project_file:
|
5
5
|
@type, @name, @content, @project_file = type, name, content, project_file
|
6
6
|
end
|
data/app/project/file.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# extracts capabilities and definitions from project files
|
2
2
|
|
3
|
-
class Project::ProjectFile
|
3
|
+
class RBCM::Project::ProjectFile
|
4
4
|
def initialize project:, path:
|
5
5
|
@project = project
|
6
6
|
@path = path
|
@@ -10,11 +10,11 @@ class Project::ProjectFile
|
|
10
10
|
file = File.read path
|
11
11
|
method_names_cache = methods(false)
|
12
12
|
instance_eval file
|
13
|
-
sandbox = Project::Sandbox.dup
|
13
|
+
sandbox = RBCM::Project::Sandbox.dup
|
14
14
|
sandbox.module_eval(file)
|
15
15
|
sandbox.instance_methods.each do |name|
|
16
16
|
raise "ERROR: capability name '#{name}' not allowed" if [:node, :group].include? name
|
17
|
-
@capabilities.append Project::Capability.new(
|
17
|
+
@capabilities.append RBCM::Project::Capability.new(
|
18
18
|
name: name,
|
19
19
|
content: sandbox.instance_method(name),
|
20
20
|
project_file: self
|
@@ -31,12 +31,12 @@ class Project::ProjectFile
|
|
31
31
|
keys = named.keys - [:github, :dir, :file]
|
32
32
|
).any?
|
33
33
|
named.each do |type, name|
|
34
|
-
@addons.append Addon.new type: type, name: name
|
34
|
+
@addons.append RBCM::Addon.new type: type, name: name
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
38
38
|
def group name=nil
|
39
|
-
@definitions.append Project::Definition.new(
|
39
|
+
@definitions.append RBCM::Project::Definition.new(
|
40
40
|
type: :group,
|
41
41
|
name: name,
|
42
42
|
content: Proc.new,
|
@@ -46,7 +46,7 @@ class Project::ProjectFile
|
|
46
46
|
|
47
47
|
def node names=nil
|
48
48
|
[names].flatten(1).each do |name|
|
49
|
-
@definitions.append Project::Definition.new(
|
49
|
+
@definitions.append RBCM::Project::Definition.new(
|
50
50
|
type: name.class == Regexp ? :pattern : :node,
|
51
51
|
name: name,
|
52
52
|
content: Proc.new,
|
data/app/project/project.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
|
-
class Project
|
1
|
+
class RBCM::Project
|
2
2
|
def initialize path, template_engines: [:mustache, :erb], addon: false
|
3
3
|
@path = path
|
4
4
|
@files = []
|
5
|
-
@templates = Project::TemplateList.new
|
5
|
+
@templates = RBCM::Project::TemplateList.new
|
6
6
|
@other = []
|
7
7
|
@directories = []
|
8
8
|
@template_engines = template_engines
|
@@ -47,12 +47,12 @@ class Project
|
|
47
47
|
if File.directory? path
|
48
48
|
Dir["#{path}/**/*"].each do |file_path|
|
49
49
|
if file_path.end_with? ".rb"
|
50
|
-
@files.append Project::ProjectFile.new(
|
50
|
+
@files.append RBCM::Project::ProjectFile.new(
|
51
51
|
project: self,
|
52
52
|
path: file_path
|
53
53
|
)
|
54
54
|
elsif @template_engines.include? file_path.split(".").last.to_sym
|
55
|
-
@templates.append Project::Template.new(
|
55
|
+
@templates.append RBCM::Project::Template.new(
|
56
56
|
project: self,
|
57
57
|
path: file_path
|
58
58
|
)
|
@@ -64,7 +64,7 @@ class Project
|
|
64
64
|
end
|
65
65
|
else
|
66
66
|
@files = [
|
67
|
-
Project::ProjectFile.new(
|
67
|
+
RBCM::Project::ProjectFile.new(
|
68
68
|
project: self,
|
69
69
|
path: path
|
70
70
|
)
|
data/app/project/sandbox.rb
CHANGED
data/app/project/template.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
class Project::Template
|
1
|
+
class RBCM::Project::Template
|
2
2
|
@@engines = [:erb, :mustache]
|
3
3
|
|
4
4
|
def initialize project:, path:
|
@@ -38,7 +38,7 @@ class Project::Template
|
|
38
38
|
)
|
39
39
|
end
|
40
40
|
|
41
|
-
def clean_filename
|
41
|
+
def clean_filename
|
42
42
|
File.basename(clean_path)
|
43
43
|
end
|
44
44
|
|
data/app/rbcm.rb
CHANGED
@@ -1,91 +1,94 @@
|
|
1
|
-
|
2
|
-
require "
|
3
|
-
require "
|
4
|
-
require "
|
5
|
-
require "
|
6
|
-
require "
|
1
|
+
module RBCM
|
2
|
+
require "net/ssh"
|
3
|
+
require "net/scp"
|
4
|
+
require "fileutils"
|
5
|
+
require "shellwords"
|
6
|
+
require "diffy"
|
7
|
+
require "pry"
|
8
|
+
require "git"
|
7
9
|
|
8
|
-
APPDIR = File.expand_path File.dirname(__FILE__)
|
9
|
-
[ "action/action", "action/command",
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
].each{|requirement| require "#{APPDIR}/#{requirement}.rb"}
|
10
|
+
APPDIR = File.expand_path File.dirname(__FILE__)
|
11
|
+
[ "action/action", "action/command",
|
12
|
+
"action/file", "action/list",
|
13
|
+
"node/node", "node/file",
|
14
|
+
"node/job", "node/filesystem",
|
15
|
+
"node/remote", "node/sandbox",
|
16
|
+
"node/job_search",
|
17
|
+
"lib/lib", "lib/array_hash",
|
18
|
+
"lib/options", "lib/quick_each",
|
19
|
+
"lib/params", "lib/aescrypt",
|
20
|
+
"project/project", "project/definition",
|
21
|
+
"project/file", "project/capability",
|
22
|
+
"project/sandbox", "project/addon",
|
23
|
+
"project/template", "project/template_list",
|
24
|
+
"cli"
|
25
|
+
].each{|requirement| require "#{APPDIR}/#{requirement}.rb"}
|
24
26
|
|
25
|
-
class
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
27
|
+
class Core
|
28
|
+
def initialize project_path
|
29
|
+
# initialize project
|
30
|
+
@project = RBCM::Project.new project_path
|
31
|
+
# create nodes
|
32
|
+
@group_additions = RBCM::ArrayHash.new
|
33
|
+
@nodes = {}
|
34
|
+
@project.definitions(:node).each do |node_definition|
|
35
|
+
@nodes[node_definition.name] ||= RBCM::Node.new(
|
36
|
+
self,
|
37
|
+
node_definition.name,
|
38
|
+
node_definition.project_file.path
|
39
|
+
)
|
40
|
+
@nodes[node_definition.name] << node_definition
|
41
|
+
# apply pattern definitions to node
|
42
|
+
@nodes[node_definition.name] << @project.definitions(:pattern).collect do |pattern_definition|
|
43
|
+
pattern_definition if node_definition.name =~ /#{pattern_definition.name}/
|
44
|
+
end
|
45
|
+
end
|
46
|
+
# create groups
|
47
|
+
@groups = RBCM::ArrayHash.new
|
48
|
+
@project.definitions(:group).each do |group_definition|
|
49
|
+
@groups[group_definition.name] << group_definition
|
42
50
|
end
|
43
51
|
end
|
44
|
-
# create groups
|
45
|
-
@groups = ArrayHash.new
|
46
|
-
@project.definitions(:group).each do |group_definition|
|
47
|
-
@groups[group_definition.name] << group_definition
|
48
|
-
end
|
49
|
-
end
|
50
52
|
|
51
|
-
|
52
|
-
|
53
|
+
attr_reader :nodes, :groups, :project, :actions
|
54
|
+
attr_accessor :group_additions
|
53
55
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
def jobs
|
59
|
-
nodes.values.each.jobs.flatten(1)
|
60
|
-
end
|
56
|
+
def actions
|
57
|
+
RBCM::ActionList.new nodes.values.each.actions.flatten(1)
|
58
|
+
end
|
61
59
|
|
62
|
-
|
63
|
-
|
64
|
-
nodes.values.each.parse
|
65
|
-
# parsing additions
|
66
|
-
nodes.values.each do |node|
|
67
|
-
node.sandbox.evaluate node.additions
|
60
|
+
def jobs
|
61
|
+
nodes.values.each.jobs.flatten(1)
|
68
62
|
end
|
69
|
-
|
70
|
-
|
71
|
-
|
63
|
+
|
64
|
+
def parse
|
65
|
+
# parsing nodes
|
66
|
+
nodes.values.each.parse
|
67
|
+
# parsing additions
|
68
|
+
nodes.values.each do |node|
|
69
|
+
node.sandbox.evaluate node.additions
|
70
|
+
end
|
71
|
+
# parsing 'cap!'
|
72
|
+
nodes.values.each do |node|
|
73
|
+
node.capabilities.each{|capability| node.sandbox.send "#{capability.name}!"}
|
74
|
+
end
|
72
75
|
end
|
73
|
-
end
|
74
76
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
77
|
+
def check! &block
|
78
|
+
Net::SSH::Multi.start do |session|
|
79
|
+
session.via 'gateway', 'gateway-user'
|
80
|
+
@nodes.each do |name, node|
|
81
|
+
session.group name.to_sym do
|
82
|
+
session.use "#{name}"
|
83
|
+
end
|
81
84
|
end
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
85
|
+
actions.checkable.each do |action|
|
86
|
+
actions.check.each do |check|
|
87
|
+
session.with(action.job.node.name.to_sym).exec check &block
|
88
|
+
end
|
86
89
|
end
|
90
|
+
session.loop
|
87
91
|
end
|
88
|
-
session.loop
|
89
92
|
end
|
90
93
|
end
|
91
94
|
end
|
data/bin/rbcm
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rbcm
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.12
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Martin Wiegand
|
@@ -52,6 +52,20 @@ dependencies:
|
|
52
52
|
- - '='
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: 4.2.0
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: net-scp
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 1.2.2.rc2
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 1.2.2.rc2
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
70
|
name: git
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -105,6 +119,7 @@ files:
|
|
105
119
|
- app/node/node.rb
|
106
120
|
- app/node/remote.rb
|
107
121
|
- app/node/sandbox.rb
|
122
|
+
- app/pool.rb
|
108
123
|
- app/project/addon.rb
|
109
124
|
- app/project/capability.rb
|
110
125
|
- app/project/definition.rb
|