pantry 0.0.0 → 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 +4 -4
- data/.gitignore +9 -0
- data/.ruby-version +1 -0
- data/.travis.yml +19 -0
- data/Gemfile +15 -0
- data/Guardfile +16 -0
- data/LICENSE +20 -0
- data/README.md +53 -0
- data/Rakefile +18 -0
- data/Vagrantfile +86 -0
- data/bin/pantry +11 -0
- data/bin/pantry-client +38 -0
- data/bin/pantry-server +33 -0
- data/dist/client.yml +79 -0
- data/dist/server.yml +56 -0
- data/dist/upstart/pantry-client.conf +12 -0
- data/dist/upstart/pantry-server.conf +12 -0
- data/doc/message_packet.dot +19 -0
- data/doc/message_packet.dot.png +0 -0
- data/doc/network_topology.dot +42 -0
- data/doc/network_topology.dot.png +0 -0
- data/lib/celluloid_zmq_patches.rb +16 -0
- data/lib/opt_parse_plus.rb +184 -0
- data/lib/pantry.rb +197 -0
- data/lib/pantry/cli.rb +154 -0
- data/lib/pantry/client.rb +131 -0
- data/lib/pantry/client_info.rb +34 -0
- data/lib/pantry/client_registry.rb +104 -0
- data/lib/pantry/command.rb +194 -0
- data/lib/pantry/command_handler.rb +53 -0
- data/lib/pantry/command_line.rb +115 -0
- data/lib/pantry/commands/create_client.rb +30 -0
- data/lib/pantry/commands/download_directory.rb +35 -0
- data/lib/pantry/commands/echo.rb +32 -0
- data/lib/pantry/commands/edit_application.rb +60 -0
- data/lib/pantry/commands/register_client.rb +38 -0
- data/lib/pantry/commands/status.rb +78 -0
- data/lib/pantry/commands/sync_directory.rb +50 -0
- data/lib/pantry/commands/update_application.rb +45 -0
- data/lib/pantry/commands/upload_file.rb +68 -0
- data/lib/pantry/communication.rb +20 -0
- data/lib/pantry/communication/client.rb +75 -0
- data/lib/pantry/communication/client_filter.rb +117 -0
- data/lib/pantry/communication/file_service.rb +125 -0
- data/lib/pantry/communication/file_service/file_progress.rb +164 -0
- data/lib/pantry/communication/file_service/receive_file.rb +97 -0
- data/lib/pantry/communication/file_service/send_file.rb +74 -0
- data/lib/pantry/communication/publish_socket.rb +20 -0
- data/lib/pantry/communication/reading_socket.rb +89 -0
- data/lib/pantry/communication/receive_socket.rb +23 -0
- data/lib/pantry/communication/security.rb +44 -0
- data/lib/pantry/communication/security/authentication.rb +98 -0
- data/lib/pantry/communication/security/curve_key_store.rb +120 -0
- data/lib/pantry/communication/security/curve_security.rb +70 -0
- data/lib/pantry/communication/security/null_security.rb +32 -0
- data/lib/pantry/communication/send_socket.rb +19 -0
- data/lib/pantry/communication/serialize_message.rb +84 -0
- data/lib/pantry/communication/server.rb +97 -0
- data/lib/pantry/communication/subscribe_socket.rb +33 -0
- data/lib/pantry/communication/wait_list.rb +45 -0
- data/lib/pantry/communication/writing_socket.rb +46 -0
- data/lib/pantry/config.rb +182 -0
- data/lib/pantry/file_editor.rb +67 -0
- data/lib/pantry/logger.rb +78 -0
- data/lib/pantry/message.rb +134 -0
- data/lib/pantry/multi_command.rb +36 -0
- data/lib/pantry/server.rb +132 -0
- data/lib/pantry/test/acceptance.rb +83 -0
- data/lib/pantry/test/support/fake_fs.rb +31 -0
- data/lib/pantry/test/support/matchers.rb +13 -0
- data/lib/pantry/test/support/minitest.rb +13 -0
- data/lib/pantry/test/support/mock_ui.rb +23 -0
- data/lib/pantry/test/unit.rb +13 -0
- data/lib/pantry/ui.rb +68 -0
- data/lib/pantry/version.rb +3 -0
- data/pantry.gemspec +40 -0
- data/test/acceptance/cli/error_handling_test.rb +7 -0
- data/test/acceptance/cli/execute_command_on_clients_test.rb +32 -0
- data/test/acceptance/cli/request_info_from_server_test.rb +44 -0
- data/test/acceptance/communication/client_requests_info_from_server_test.rb +28 -0
- data/test/acceptance/communication/heartbeat_test.rb +19 -0
- data/test/acceptance/communication/pub_sub_communication_test.rb +53 -0
- data/test/acceptance/communication/security_test.rb +117 -0
- data/test/acceptance/communication/server_requests_info_from_client_test.rb +41 -0
- data/test/acceptance/test_helper.rb +25 -0
- data/test/fixtures/config.yml +22 -0
- data/test/fixtures/empty.yml +2 -0
- data/test/fixtures/file_to_upload +3 -0
- data/test/root_dir/.gitkeep +0 -0
- data/test/unit/cli_test.rb +173 -0
- data/test/unit/client_registry_test.rb +61 -0
- data/test/unit/client_test.rb +128 -0
- data/test/unit/command_handler_test.rb +79 -0
- data/test/unit/command_line_test.rb +5 -0
- data/test/unit/command_test.rb +206 -0
- data/test/unit/commands/create_client_test.rb +25 -0
- data/test/unit/commands/download_directory_test.rb +58 -0
- data/test/unit/commands/echo_test.rb +22 -0
- data/test/unit/commands/edit_application_test.rb +84 -0
- data/test/unit/commands/register_client_test.rb +41 -0
- data/test/unit/commands/status_test.rb +81 -0
- data/test/unit/commands/sync_directory_test.rb +75 -0
- data/test/unit/commands/update_application_test.rb +35 -0
- data/test/unit/commands/upload_file_test.rb +51 -0
- data/test/unit/communication/client_filter_test.rb +262 -0
- data/test/unit/communication/client_test.rb +99 -0
- data/test/unit/communication/file_service/receive_file_test.rb +214 -0
- data/test/unit/communication/file_service/send_file_test.rb +110 -0
- data/test/unit/communication/file_service_test.rb +56 -0
- data/test/unit/communication/publish_socket_test.rb +19 -0
- data/test/unit/communication/reading_socket_test.rb +110 -0
- data/test/unit/communication/receive_socket_test.rb +20 -0
- data/test/unit/communication/security/authentication_test.rb +97 -0
- data/test/unit/communication/security/curve_key_store_test.rb +110 -0
- data/test/unit/communication/security/curve_security_test.rb +44 -0
- data/test/unit/communication/security/null_security_test.rb +15 -0
- data/test/unit/communication/security_test.rb +49 -0
- data/test/unit/communication/send_socket_test.rb +19 -0
- data/test/unit/communication/serialize_message_test.rb +128 -0
- data/test/unit/communication/server_test.rb +106 -0
- data/test/unit/communication/subscribe_socket_test.rb +46 -0
- data/test/unit/communication/wait_list_test.rb +60 -0
- data/test/unit/communication/writing_socket_test.rb +46 -0
- data/test/unit/config_test.rb +150 -0
- data/test/unit/logger_test.rb +79 -0
- data/test/unit/message_test.rb +179 -0
- data/test/unit/multi_command_test.rb +45 -0
- data/test/unit/opt_parse_plus_test.rb +218 -0
- data/test/unit/pantry_test.rb +82 -0
- data/test/unit/server_test.rb +166 -0
- data/test/unit/test_helper.rb +25 -0
- data/test/unit/ui_test.rb +58 -0
- metadata +389 -13
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
digraph message {
|
|
2
|
+
node [shape=record];
|
|
3
|
+
rankdir = LR;
|
|
4
|
+
|
|
5
|
+
subgraph cluster_zmq {
|
|
6
|
+
label = "ZMQ";
|
|
7
|
+
labeljust = right;
|
|
8
|
+
body [shape=record width=2 label="Stream |<metadata> Metadata | body[0] | body[1] | ..."];
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
subgraph cluster_metadata {
|
|
12
|
+
label = "JSON Metadata";
|
|
13
|
+
labeljust = right;
|
|
14
|
+
|
|
15
|
+
metadata [shape=record width=2 label="<top> Type | Source | Response\nRequired?"];
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
body:metadata -> metadata:top;
|
|
19
|
+
}
|
|
Binary file
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
digraph pantry {
|
|
2
|
+
rankdir = LR;
|
|
3
|
+
color = black;
|
|
4
|
+
splines = ortho;
|
|
5
|
+
node [shape=rectangle];
|
|
6
|
+
|
|
7
|
+
subgraph cluster_server {
|
|
8
|
+
label = "Pantry Server";
|
|
9
|
+
labeljust = left;
|
|
10
|
+
edge [style=dashed];
|
|
11
|
+
|
|
12
|
+
server [label="Server"];
|
|
13
|
+
publish [label="PUB"];
|
|
14
|
+
|
|
15
|
+
server_dealer [label="ROUTER"];
|
|
16
|
+
|
|
17
|
+
server -> publish;
|
|
18
|
+
server -> server_dealer [dir=back];
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
subgraph cluster_client {
|
|
22
|
+
label = "Pantry Client";
|
|
23
|
+
labeljust = right;
|
|
24
|
+
edge [style=dashed];
|
|
25
|
+
|
|
26
|
+
client [label="Client"];
|
|
27
|
+
subscribe [label="SUB"];
|
|
28
|
+
provisioning [label="Chef"];
|
|
29
|
+
shell [label="Shell"];
|
|
30
|
+
|
|
31
|
+
client_dealer [label="DEALER"];
|
|
32
|
+
|
|
33
|
+
client -> provisioning [dir=both];
|
|
34
|
+
client -> shell [dir=both];
|
|
35
|
+
|
|
36
|
+
subscribe -> client;
|
|
37
|
+
client_dealer -> client [dir=back];
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
server_dealer -> client_dealer [dir=back];
|
|
41
|
+
publish -> subscribe;
|
|
42
|
+
}
|
|
Binary file
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Monkey Patch Celluloid::ZMQ to allow pass through
|
|
2
|
+
# of direct setsockopt calls, so we can configure sockets
|
|
3
|
+
# as we need to
|
|
4
|
+
|
|
5
|
+
module Celluloid
|
|
6
|
+
module ZMQ
|
|
7
|
+
class Socket
|
|
8
|
+
def set(*args)
|
|
9
|
+
unless ::ZMQ::Util.resultcode_ok? @socket.setsockopt(*args)
|
|
10
|
+
raise IOError, "couldn't set value: #{::ZMQ::Util.error_string}"
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
require 'optparse'
|
|
2
|
+
|
|
3
|
+
class OptParsePlus
|
|
4
|
+
|
|
5
|
+
attr_reader :options, :summary
|
|
6
|
+
|
|
7
|
+
class OptionsFound < Hash
|
|
8
|
+
attr_accessor :command_found
|
|
9
|
+
|
|
10
|
+
# Let these options be queried by a string key or symbol
|
|
11
|
+
# key equally.
|
|
12
|
+
def [](key)
|
|
13
|
+
super ||
|
|
14
|
+
(key.is_a?(Symbol) && super(key.to_s)) ||
|
|
15
|
+
(key.is_a?(String) && super(key.to_sym))
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def initialize(parent = nil)
|
|
20
|
+
@parent = parent || self
|
|
21
|
+
@parser = OptionParser.new
|
|
22
|
+
@options = OptionsFound.new
|
|
23
|
+
@commands = {}
|
|
24
|
+
@summary = ""
|
|
25
|
+
|
|
26
|
+
add_default_help
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def add_options(&block)
|
|
30
|
+
instance_exec(&block)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def add_command(command_name, &block)
|
|
34
|
+
command_parser = OptParsePlus.new(self)
|
|
35
|
+
|
|
36
|
+
base_command = base_command_name(command_name.to_s)
|
|
37
|
+
rest = command_name.gsub(base_command, '')
|
|
38
|
+
|
|
39
|
+
command_parser.banner "Usage: #$0 #{base_command} [options]#{rest}"
|
|
40
|
+
command_parser.add_options(&block) if block_given?
|
|
41
|
+
@commands[base_command] = command_parser
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def option(*arguments)
|
|
45
|
+
argument_name = parse_argument_name(arguments)
|
|
46
|
+
@parser.on(*arguments) do |arg|
|
|
47
|
+
@options[argument_name] = arg
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def banner(message)
|
|
52
|
+
@parser.banner = message
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def group(group_name = nil)
|
|
56
|
+
if group_name
|
|
57
|
+
@group = group_name
|
|
58
|
+
else
|
|
59
|
+
@group
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def description(message)
|
|
64
|
+
@summary = clean_up_white_space(message)
|
|
65
|
+
@parser.separator("")
|
|
66
|
+
@parser.separator(@summary)
|
|
67
|
+
@parser.separator("")
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def set(key, value)
|
|
71
|
+
@options[key] = value
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def parse!(command_line)
|
|
75
|
+
@parser.order!(command_line)
|
|
76
|
+
final = @options
|
|
77
|
+
|
|
78
|
+
next_token = command_line.first
|
|
79
|
+
|
|
80
|
+
if command_parser = @commands[next_token]
|
|
81
|
+
command_line.shift
|
|
82
|
+
command_parser.parse!(command_line)
|
|
83
|
+
|
|
84
|
+
final.command_found = next_token
|
|
85
|
+
final.merge!({
|
|
86
|
+
next_token => command_parser.options
|
|
87
|
+
})
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
final
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def help
|
|
94
|
+
help_parts = []
|
|
95
|
+
help_parts << @parser.to_s
|
|
96
|
+
|
|
97
|
+
if @commands.any?
|
|
98
|
+
help_parts << ["Known Commands", ""]
|
|
99
|
+
command_list = group_and_sort_command_help
|
|
100
|
+
|
|
101
|
+
command_list.each do |cmd_line|
|
|
102
|
+
help_parts << cmd_line
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
help_parts << ""
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
help_parts << ""
|
|
109
|
+
help_parts.flatten.join("\n")
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
protected
|
|
113
|
+
|
|
114
|
+
def clean_up_white_space(message)
|
|
115
|
+
message.split("\n").map(&:strip).join("\n")
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def add_default_help
|
|
119
|
+
@parser.on_tail('-h', '--help', 'Show this help message') do
|
|
120
|
+
puts help
|
|
121
|
+
@parent.set('help', true)
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def base_command_name(command_string)
|
|
126
|
+
command_string.split(/\s/).first
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
def parse_argument_name(arguments)
|
|
130
|
+
full_name_arg = arguments.select {|a| a =~ /\A--/ }.first
|
|
131
|
+
full_name_arg.split(/\s/).first.gsub("--", "")
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def group_and_sort_command_help
|
|
135
|
+
grouped_commands = Hash.new {|hash, key| hash[key] = []}
|
|
136
|
+
|
|
137
|
+
@commands.each do |command_name, parser|
|
|
138
|
+
grouped_commands[parser.group] << [command_name, parser]
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
command_list = []
|
|
142
|
+
sorted_group_names = grouped_commands.keys.sort {|a, b| a.to_s <=> b.to_s }
|
|
143
|
+
sorted_group_names.each do |group_name|
|
|
144
|
+
command_list << build_help_for_command_group(group_name, grouped_commands[group_name])
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
command_list.flatten(1)
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
def build_help_for_command_group(group_name, group_commands)
|
|
151
|
+
command_list = []
|
|
152
|
+
|
|
153
|
+
if group_name
|
|
154
|
+
command_list << nil
|
|
155
|
+
command_list << "#{group_name} commands"
|
|
156
|
+
command_list << nil
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
command_list + generate_short_help_for_commands(group_commands)
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
def generate_short_help_for_commands(group_commands)
|
|
163
|
+
longest_command_length = 0
|
|
164
|
+
group_commands.each do |(command_name, _)|
|
|
165
|
+
longest_command_length = command_name.length if command_name.length > longest_command_length
|
|
166
|
+
end
|
|
167
|
+
# Give ourselves a small buffer between command and summary
|
|
168
|
+
longest_command_length += 3
|
|
169
|
+
|
|
170
|
+
sorted_group_commands = group_commands.sort {|a, b| a[0] <=> b[0]}
|
|
171
|
+
sorted_group_commands.map do |(command_name, parser)|
|
|
172
|
+
sprintf(
|
|
173
|
+
"%-#{longest_command_length}s %s",
|
|
174
|
+
command_name,
|
|
175
|
+
first_line_of_summary(parser)
|
|
176
|
+
)
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
def first_line_of_summary(parser)
|
|
181
|
+
parser.summary.split("\n").first
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
end
|
data/lib/pantry.rb
ADDED
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
require 'celluloid'
|
|
2
|
+
require 'celluloid/zmq'
|
|
3
|
+
require 'json'
|
|
4
|
+
require 'logger'
|
|
5
|
+
require 'pathname'
|
|
6
|
+
require 'rubygems'
|
|
7
|
+
require 'safe_yaml/load'
|
|
8
|
+
require 'securerandom'
|
|
9
|
+
require 'socket'
|
|
10
|
+
require 'syslog/logger'
|
|
11
|
+
require 'tempfile'
|
|
12
|
+
require 'open3'
|
|
13
|
+
require 'yaml'
|
|
14
|
+
|
|
15
|
+
require 'opt_parse_plus'
|
|
16
|
+
require 'celluloid_zmq_patches'
|
|
17
|
+
|
|
18
|
+
require 'pantry/version'
|
|
19
|
+
require 'pantry/ui'
|
|
20
|
+
require 'pantry/config'
|
|
21
|
+
require 'pantry/logger'
|
|
22
|
+
require 'pantry/message'
|
|
23
|
+
require 'pantry/command_line'
|
|
24
|
+
require 'pantry/file_editor'
|
|
25
|
+
|
|
26
|
+
require 'pantry/command'
|
|
27
|
+
require 'pantry/multi_command'
|
|
28
|
+
require 'pantry/command_handler'
|
|
29
|
+
|
|
30
|
+
require 'pantry/commands/echo'
|
|
31
|
+
require 'pantry/commands/edit_application'
|
|
32
|
+
require 'pantry/commands/update_application'
|
|
33
|
+
require 'pantry/commands/status'
|
|
34
|
+
require 'pantry/commands/register_client'
|
|
35
|
+
require 'pantry/commands/upload_file'
|
|
36
|
+
require 'pantry/commands/sync_directory'
|
|
37
|
+
require 'pantry/commands/download_directory'
|
|
38
|
+
require 'pantry/commands/create_client'
|
|
39
|
+
|
|
40
|
+
require 'pantry/communication'
|
|
41
|
+
require 'pantry/communication/serialize_message'
|
|
42
|
+
require 'pantry/communication/server'
|
|
43
|
+
require 'pantry/communication/client'
|
|
44
|
+
require 'pantry/communication/client_filter'
|
|
45
|
+
require 'pantry/communication/wait_list'
|
|
46
|
+
|
|
47
|
+
require 'pantry/communication/security/null_security'
|
|
48
|
+
require 'pantry/communication/security/curve_security'
|
|
49
|
+
require 'pantry/communication/security/curve_key_store'
|
|
50
|
+
require 'pantry/communication/security/authentication'
|
|
51
|
+
require 'pantry/communication/security'
|
|
52
|
+
|
|
53
|
+
require 'pantry/communication/reading_socket'
|
|
54
|
+
require 'pantry/communication/writing_socket'
|
|
55
|
+
require 'pantry/communication/publish_socket'
|
|
56
|
+
require 'pantry/communication/subscribe_socket'
|
|
57
|
+
require 'pantry/communication/receive_socket'
|
|
58
|
+
require 'pantry/communication/send_socket'
|
|
59
|
+
|
|
60
|
+
require 'pantry/communication/file_service'
|
|
61
|
+
require 'pantry/communication/file_service/file_progress'
|
|
62
|
+
require 'pantry/communication/file_service/receive_file'
|
|
63
|
+
require 'pantry/communication/file_service/send_file'
|
|
64
|
+
|
|
65
|
+
require 'pantry/client_info'
|
|
66
|
+
require 'pantry/client_registry'
|
|
67
|
+
|
|
68
|
+
require 'pantry/client'
|
|
69
|
+
require 'pantry/server'
|
|
70
|
+
require 'pantry/cli'
|
|
71
|
+
|
|
72
|
+
module Pantry
|
|
73
|
+
|
|
74
|
+
# Default identity of a Server, so as to help differentiate where
|
|
75
|
+
# messages are coming from.
|
|
76
|
+
SERVER_IDENTITY = ""
|
|
77
|
+
|
|
78
|
+
##
|
|
79
|
+
# Various exceptions Pantry can raise
|
|
80
|
+
##
|
|
81
|
+
|
|
82
|
+
# A command is expecting a certain option
|
|
83
|
+
class MissingOption < Exception; end
|
|
84
|
+
|
|
85
|
+
# Thrown when trying to add a non Pantry::Command class as a Pantry command
|
|
86
|
+
class InvalidCommandError < Exception; end
|
|
87
|
+
|
|
88
|
+
# Thrown when trying to add a Command that has the same message_type
|
|
89
|
+
# as a Command already registered
|
|
90
|
+
class DuplicateCommandError < Exception; end
|
|
91
|
+
|
|
92
|
+
# The root of all stored Pantry data for this Server/Client
|
|
93
|
+
# Uses Pantry.config.root_dir
|
|
94
|
+
def root(config = Pantry.config)
|
|
95
|
+
Pathname.new(config.root_dir)
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
# Update the process's proc title with the given string
|
|
99
|
+
def set_proc_title(title)
|
|
100
|
+
$0 = title
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# Calculate the checksum of a file at the given path
|
|
104
|
+
def file_checksum(file_path)
|
|
105
|
+
Digest::SHA256.file(file_path).hexdigest
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
# Register a command object class to be handled only by Clients
|
|
109
|
+
def add_client_command(command_class)
|
|
110
|
+
ensure_proper_command_class(command_class)
|
|
111
|
+
check_for_duplicates(client_commands, command_class)
|
|
112
|
+
|
|
113
|
+
client_commands << command_class
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
# Register a command object class to be handled only by the Server
|
|
117
|
+
def add_server_command(command_class)
|
|
118
|
+
ensure_proper_command_class(command_class)
|
|
119
|
+
check_for_duplicates(server_commands, command_class)
|
|
120
|
+
|
|
121
|
+
server_commands << command_class
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
# Return the list of known Client command classes
|
|
125
|
+
def client_commands
|
|
126
|
+
@client_commands ||= []
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
# Return the list of known Server command classes
|
|
130
|
+
def server_commands
|
|
131
|
+
@server_commands ||= []
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
# Return all known commands
|
|
135
|
+
def all_commands
|
|
136
|
+
[client_commands, server_commands].flatten
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def ensure_proper_command_class(command_class)
|
|
140
|
+
unless command_class.is_a?(Class)
|
|
141
|
+
raise Pantry::InvalidCommandError.new("Expected a Class, got an #{command_class.class}")
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
unless command_class.ancestors.include?(Pantry::Command)
|
|
145
|
+
raise Pantry::InvalidCommandError.new("Expected a class that's a subclass of Pantry::Command")
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
def check_for_duplicates(command_list, command_class_to_add)
|
|
150
|
+
known_commands = command_list.map(&:message_type)
|
|
151
|
+
if known_commands.include?(command_class_to_add.message_type)
|
|
152
|
+
raise Pantry::DuplicateCommandError.new("Command with type #{command_class_to_add.message_type} already registered")
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
# Find all installed Pantry plugin gems.
|
|
157
|
+
# Plugins are defined as gems who contain a file named "pantry/init.rb".
|
|
158
|
+
def load_plugins
|
|
159
|
+
Gem.find_latest_files("pantry/init.rb").each do |path|
|
|
160
|
+
begin
|
|
161
|
+
gem_path = path.gsub("#{Gem.dir}/gems/", '')
|
|
162
|
+
Pantry.logger.debug("Installing plugin from #{gem_path}")
|
|
163
|
+
require path
|
|
164
|
+
rescue Exception => ex
|
|
165
|
+
Pantry.logger.warn("Unable to load plugin at #{gem_path}, #{ex.message}")
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
extend self
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
Celluloid.exception_handler do |exception|
|
|
174
|
+
Pantry.logger.error("Exception thrown: #{exception.inspect}")
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
SafeYAML::OPTIONS[:default_mode] = :safe
|
|
178
|
+
SafeYAML::OPTIONS[:deserialize_symbols] = false
|
|
179
|
+
|
|
180
|
+
####################
|
|
181
|
+
# Command Registry #
|
|
182
|
+
####################
|
|
183
|
+
|
|
184
|
+
## Client Commands
|
|
185
|
+
|
|
186
|
+
Pantry.add_client_command(Pantry::Commands::Echo)
|
|
187
|
+
|
|
188
|
+
## Server Commands
|
|
189
|
+
|
|
190
|
+
Pantry.add_server_command(Pantry::Commands::EditApplication)
|
|
191
|
+
Pantry.add_server_command(Pantry::Commands::UpdateApplication)
|
|
192
|
+
Pantry.add_server_command(Pantry::Commands::Status)
|
|
193
|
+
Pantry.add_server_command(Pantry::Commands::RegisterClient)
|
|
194
|
+
Pantry.add_server_command(Pantry::Commands::DownloadDirectory)
|
|
195
|
+
Pantry.add_server_command(Pantry::Commands::CreateClient)
|
|
196
|
+
|
|
197
|
+
Pantry.load_plugins
|