mamiya 0.0.1.alpha20 → 0.0.1.alpha21
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/README.md +6 -0
- data/example/Procfile +2 -0
- data/example/config.rb +9 -0
- data/example/deploy.rb +34 -0
- data/lib/mamiya/agent.rb +8 -4
- data/lib/mamiya/agent/tasks/abstract.rb +3 -0
- data/lib/mamiya/agent/tasks/fetch.rb +13 -2
- data/lib/mamiya/cli.rb +4 -4
- data/lib/mamiya/configuration.rb +29 -0
- data/lib/mamiya/dsl.rb +7 -1
- data/lib/mamiya/master.rb +1 -1
- data/lib/mamiya/master/agent_monitor.rb +24 -2
- data/lib/mamiya/master/agent_monitor_handlers.rb +2 -2
- data/lib/mamiya/steps/abstract.rb +1 -2
- data/lib/mamiya/version.rb +1 -1
- data/spec/agent/tasks/fetch_spec.rb +27 -2
- data/spec/agent_spec.rb +20 -1
- data/spec/configuration_spec.rb +35 -0
- data/spec/dsl_spec.rb +4 -0
- data/spec/master/agent_monitor_spec.rb +84 -16
- metadata +8 -5
- data/lib/mamiya/config.rb +0 -57
- data/spec/config_spec.rb +0 -50
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4a0a40c67ec9701a56d9d5454ed090bca4f8c7c4
|
4
|
+
data.tar.gz: c6989472920d7302838ca131b425b62715383809
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 60cfeb34db85ab130c792c28723e91518f2367a6bf29ff9221b7b969fa956c8fb2dfd12f69e0b44143081619ac346862270ab6c46b6afb4d343cb1fe2c7ac815
|
7
|
+
data.tar.gz: fc6c115392f4dca0acd05aa5c4708d796a29086b4c8863a65432a82206c397829b065d063bc909a98adb5bf09d70cb6b3bbf08cd5fc9218735d55f50dc0eb62c
|
data/README.md
CHANGED
@@ -36,6 +36,12 @@ TODO: Write usage instructions here
|
|
36
36
|
|
37
37
|
## Upgrade Notes
|
38
38
|
|
39
|
+
### 0.0.1.alpha21
|
40
|
+
|
41
|
+
#### Configuration now written in Ruby
|
42
|
+
|
43
|
+
You should rewrite your configuration yaml in Ruby. See examples/config.rb for example.
|
44
|
+
|
39
45
|
### 0.0.1.alpha20
|
40
46
|
|
41
47
|
_tl;dr_ Don't mix alpha19 and alpha20.
|
data/example/Procfile
ADDED
@@ -0,0 +1,2 @@
|
|
1
|
+
master: bundle exec env MAMIYA_SYNC_OUT=1 mamiya master -d --serf bind=0.0.0.0:7760,rpc_addr=127.0.0.1:17760,node=${HOSTNAME}_${PORT}
|
2
|
+
agent: bundle exec env MAMIYA_SYNC_OUT=1 sh -c 'sleep 2; mamiya agent -d --serf bind=0.0.0.0:$PORT,rpc_addr=127.0.0.1:1$PORT,join=127.0.0.1:7760,node=${HOSTNAME}_${PORT}'
|
data/example/config.rb
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
set :storage, {
|
2
|
+
type: :s3,
|
3
|
+
bucket: ENV["MAMIYA_S3_BUCKET"] || ENV["S3_BUCKET"] || raise("specify your S3 bucket via $MAMIYA_S3_BUCKET or $S3_BUCKET"),
|
4
|
+
region: ENV["AWS_REGION"] || 'ap-northeast-1',
|
5
|
+
}
|
6
|
+
|
7
|
+
set :packages_dir, "#{File.dirname(__FILE__)}/dst"
|
8
|
+
set :keep_packages, 3
|
9
|
+
set :fetch_sleep, 2
|
data/example/deploy.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'digest/sha1'
|
2
|
+
require 'fileutils'
|
3
|
+
require 'pathname'
|
4
|
+
|
5
|
+
set :application, 'myapp'
|
6
|
+
#set :repository, '...'
|
7
|
+
|
8
|
+
#set :package_under, 'dir'
|
9
|
+
set :exclude_from_package, ['tmp', 'log', 'spec', '.sass-cache']
|
10
|
+
set :dereference_symlinks, true
|
11
|
+
|
12
|
+
# http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?revision=45360&view=revision
|
13
|
+
set :build_to, "#{File.dirname(__FILE__)}/pkg"
|
14
|
+
set :deploy_to, "..."
|
15
|
+
|
16
|
+
set :bundle_without, [:development, :test]
|
17
|
+
set :bundle_dir, "#{deploy_to}/shared/bundle"
|
18
|
+
|
19
|
+
#use :git, exclude_git_clean_targets: true
|
20
|
+
|
21
|
+
prepare_build("bundle install") do
|
22
|
+
run "bundle", "install"
|
23
|
+
end
|
24
|
+
|
25
|
+
build("include assets and .bundle") do
|
26
|
+
exclude_from_package.reject! { |_| _ == 'public/assets/' }
|
27
|
+
exclude_from_package.reject! { |_| _ == '.bundle/' }
|
28
|
+
end
|
29
|
+
|
30
|
+
build("assets compile") do
|
31
|
+
run "bundle", "exec", "rake", "assets:precompile"
|
32
|
+
end
|
33
|
+
|
34
|
+
|
data/lib/mamiya/agent.rb
CHANGED
@@ -76,15 +76,15 @@ module Mamiya
|
|
76
76
|
|
77
77
|
##
|
78
78
|
# Returns agent status. Used for HTTP API and `serf query` inspection.
|
79
|
-
def status
|
79
|
+
def status(packages: true)
|
80
|
+
# When changing signature, don't forget to change samely of Master#status too
|
80
81
|
{}.tap do |s|
|
81
|
-
s[:master] = false
|
82
82
|
s[:name] = serf.name
|
83
83
|
s[:version] = Mamiya::VERSION
|
84
84
|
|
85
85
|
s[:queues] = task_queue.status
|
86
86
|
|
87
|
-
s[:packages] = self.existing_packages
|
87
|
+
s[:packages] = self.existing_packages if packages
|
88
88
|
end
|
89
89
|
end
|
90
90
|
|
@@ -135,7 +135,11 @@ module Mamiya
|
|
135
135
|
end
|
136
136
|
|
137
137
|
serf.respond('mamiya:status') do |event|
|
138
|
-
self.status.to_json
|
138
|
+
self.status(packages: false).to_json
|
139
|
+
end
|
140
|
+
|
141
|
+
serf.respond('mamiya:packages') do |event|
|
142
|
+
self.existing_packages.to_json
|
139
143
|
end
|
140
144
|
end
|
141
145
|
end
|
@@ -28,14 +28,17 @@ module Mamiya
|
|
28
28
|
end
|
29
29
|
|
30
30
|
def execute
|
31
|
+
@logger.info "Task started: #{task.inspect}"
|
31
32
|
before
|
32
33
|
run
|
33
34
|
rescue Exception => error
|
34
35
|
@error = error
|
35
36
|
raise if raise_error?
|
36
37
|
errored
|
38
|
+
@logger.error "Encountered error: #{error.inspect}\n\t#{error.backtrace.join("\n\t")}"
|
37
39
|
ensure
|
38
40
|
after
|
41
|
+
@logger.info "Task finished"
|
39
42
|
end
|
40
43
|
|
41
44
|
def before
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
1
3
|
require 'mamiya/agent/tasks/notifyable'
|
2
4
|
require 'mamiya/steps/fetch'
|
3
5
|
require 'mamiya/storages/abstract'
|
@@ -7,10 +9,12 @@ module Mamiya
|
|
7
9
|
module Tasks
|
8
10
|
class Fetch < Notifyable
|
9
11
|
def run
|
10
|
-
|
11
|
-
|
12
|
+
prepare_destination
|
12
13
|
take_interval
|
14
|
+
|
15
|
+
logger.info "Fetching #{application}/#{package}"
|
13
16
|
step.run!
|
17
|
+
|
14
18
|
order_cleaning
|
15
19
|
rescue Mamiya::Storages::Abstract::AlreadyFetched
|
16
20
|
logger.info "It has already fetched; skipping."
|
@@ -26,6 +30,13 @@ module Mamiya
|
|
26
30
|
rand(wait)
|
27
31
|
end
|
28
32
|
|
33
|
+
def prepare_destination
|
34
|
+
unless File.exist?(destination)
|
35
|
+
@logger.info "Creating #{destination}"
|
36
|
+
FileUtils.mkdir_p(destination)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
29
40
|
def order_cleaning
|
30
41
|
task_queue.enqueue(:clean, {})
|
31
42
|
end
|
data/lib/mamiya/cli.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'mamiya'
|
2
2
|
|
3
|
-
require 'mamiya/
|
3
|
+
require 'mamiya/configuration'
|
4
4
|
require 'mamiya/script'
|
5
5
|
require 'mamiya/logger'
|
6
6
|
|
@@ -227,15 +227,15 @@ module Mamiya
|
|
227
227
|
|
228
228
|
def config(dont_raise_error = false)
|
229
229
|
return @config if @config
|
230
|
-
path = [options[:config], './mamiya.
|
230
|
+
path = [options[:config], './mamiya.conf.rb', './config.rb'].compact.find { |_| File.exists?(_) }
|
231
231
|
|
232
232
|
if path
|
233
233
|
logger.debug "Using configuration: #{path}"
|
234
|
-
@config = Mamiya::
|
234
|
+
@config = Mamiya::Configuration.new.load!(File.expand_path(path))
|
235
235
|
else
|
236
236
|
logger.debug "Couldn't find configuration file"
|
237
237
|
return nil if dont_raise_error
|
238
|
-
fatal! "Configuration File not found (try --config(-C) option or place it at ./
|
238
|
+
fatal! "Configuration File not found (try --config(-C) option or place it at ./config.rb)"
|
239
239
|
end
|
240
240
|
end
|
241
241
|
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'mamiya/dsl'
|
2
|
+
require 'mamiya/storages'
|
3
|
+
|
4
|
+
require 'shellwords'
|
5
|
+
|
6
|
+
module Mamiya
|
7
|
+
class Configuration < DSL
|
8
|
+
# common
|
9
|
+
set_default :serf, {}
|
10
|
+
set_default :storage, {}
|
11
|
+
set_default :show_backtrace_in_fatal, true
|
12
|
+
|
13
|
+
set_default :application, nil
|
14
|
+
|
15
|
+
# agent
|
16
|
+
set_default :packages_dir, nil
|
17
|
+
set_default :fetch_sleep, 12
|
18
|
+
set_default :keep_packages, 3
|
19
|
+
|
20
|
+
# master
|
21
|
+
set_default :master, {monitor: {refresh_interval: nil}} # TODO: don't nest
|
22
|
+
set_default :web, {port: 7761, bind: '0.0.0.0', environment: :development} # TODO: IPv6
|
23
|
+
|
24
|
+
def storage_class
|
25
|
+
Storages.find(self[:storage][:type])
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
data/lib/mamiya/dsl.rb
CHANGED
@@ -28,7 +28,7 @@ module Mamiya
|
|
28
28
|
k = name.to_sym
|
29
29
|
return if self.instance_methods.include?(k)
|
30
30
|
|
31
|
-
define_method(k) {
|
31
|
+
define_method(k) { self[k] }
|
32
32
|
end
|
33
33
|
|
34
34
|
##
|
@@ -154,6 +154,12 @@ module Mamiya
|
|
154
154
|
set(k, value)
|
155
155
|
end
|
156
156
|
|
157
|
+
##
|
158
|
+
# (DSL) Retrieve value for key +key+. Value can be set using DSL#set .
|
159
|
+
def [](key)
|
160
|
+
@variables[key] || self.class.defaults[key]
|
161
|
+
end
|
162
|
+
|
157
163
|
##
|
158
164
|
# (DSL) Define task named +name+ with given block.
|
159
165
|
def task(name, &block)
|
data/lib/mamiya/master.rb
CHANGED
@@ -14,6 +14,7 @@ module Mamiya
|
|
14
14
|
include AgentMonitorHandlers
|
15
15
|
|
16
16
|
STATUS_QUERY = 'mamiya:status'.freeze
|
17
|
+
PACKAGES_QUERY = 'mamiya:packages'.freeze
|
17
18
|
DEFAULT_INTERVAL = 60
|
18
19
|
|
19
20
|
def initialize(master, raise_exception: false)
|
@@ -99,8 +100,12 @@ module Mamiya
|
|
99
100
|
end
|
100
101
|
|
101
102
|
@commit_lock.synchronize {
|
102
|
-
|
103
|
-
|
103
|
+
status_query_th = Thread.new { @master.serf.query(STATUS_QUERY, '', **kwargs) }
|
104
|
+
packages_query_th = Thread.new { @master.serf.query(PACKAGES_QUERY, '', **kwargs) }
|
105
|
+
status_response = status_query_th.value
|
106
|
+
packages_response = packages_query_th.value
|
107
|
+
|
108
|
+
status_response["Responses"].each do |name, json|
|
104
109
|
begin
|
105
110
|
new_statuses[name] = JSON.parse(json)
|
106
111
|
rescue JSON::ParserError => e
|
@@ -110,6 +115,23 @@ module Mamiya
|
|
110
115
|
end
|
111
116
|
end
|
112
117
|
|
118
|
+
packages_response["Responses"].each do |name, json|
|
119
|
+
next unless new_statuses[name]
|
120
|
+
|
121
|
+
begin
|
122
|
+
new_statuses[name]['packages'] = JSON.parse(json)
|
123
|
+
rescue JSON::ParserError => e
|
124
|
+
logger.warn "Failed to parse packages from #{name}: #{e.message}"
|
125
|
+
next
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
(new_statuses.keys - packages_response["Responses"].keys).each do |name|
|
130
|
+
if @statuses[name] && @statuses[name]['packages']
|
131
|
+
new_statuses[name]['packages'] = @statuses[name]['packages']
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
113
135
|
new_failed_agents = new_failed_agents.to_a
|
114
136
|
|
115
137
|
(new_agents.keys - @agents.keys).join(", ").tap do |agents|
|
@@ -29,7 +29,7 @@ module Mamiya
|
|
29
29
|
|
30
30
|
def task__finish(status, payload, event)
|
31
31
|
task = payload['task']
|
32
|
-
logger.
|
32
|
+
logger.info "#{status['name']} has finished task #{task['task'].inspect}"
|
33
33
|
|
34
34
|
task__finalize(status, payload, event)
|
35
35
|
|
@@ -41,7 +41,7 @@ module Mamiya
|
|
41
41
|
|
42
42
|
def task__error(status, payload, event)
|
43
43
|
task = payload['task']
|
44
|
-
logger.error "#{status['name']} failed task #{task['task']}: #{payload['error']}"
|
44
|
+
logger.error "#{status['name']} has failed task #{task['task'].inspect}: #{payload['error']}"
|
45
45
|
|
46
46
|
task__finalize(status, payload, event)
|
47
47
|
|
@@ -1,11 +1,10 @@
|
|
1
|
-
require 'mamiya/config'
|
2
1
|
require 'mamiya/script'
|
3
2
|
require 'mamiya/logger'
|
4
3
|
|
5
4
|
module Mamiya
|
6
5
|
module Steps
|
7
6
|
class Abstract
|
8
|
-
def initialize(script: Mamiya::Script.new, config: Mamiya::
|
7
|
+
def initialize(script: Mamiya::Script.new, config: Mamiya::Configuration.new, logger: Mamiya::Logger.new, **options)
|
9
8
|
@script, @config, @options = script, config, options
|
10
9
|
@logger = logger[self.class.name.sub(/^Mamiya::Steps::/,'')]
|
11
10
|
end
|
data/lib/mamiya/version.rb
CHANGED
@@ -1,11 +1,19 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
+
require 'tmpdir'
|
2
3
|
|
3
4
|
require 'mamiya/agent/tasks/fetch'
|
4
5
|
require 'mamiya/agent/tasks/notifyable'
|
5
6
|
require 'mamiya/steps/fetch'
|
6
7
|
|
7
8
|
describe Mamiya::Agent::Tasks::Fetch do
|
8
|
-
let(:
|
9
|
+
let!(:tmpdir) { Dir.mktmpdir("mamiya-agent-tasks-fetch-spec") }
|
10
|
+
after { FileUtils.remove_entry_secure tmpdir }
|
11
|
+
|
12
|
+
let(:destination) { File.join(tmpdir, 'destination') }
|
13
|
+
let(:app_destination) { File.join(destination, 'myapp') }
|
14
|
+
|
15
|
+
let(:config) { {packages_dir: destination} }
|
16
|
+
|
9
17
|
let(:agent) { double('agent', config: config) }
|
10
18
|
let(:task_queue) { double('task_queue', enqueue: nil) }
|
11
19
|
|
@@ -21,10 +29,12 @@ describe Mamiya::Agent::Tasks::Fetch do
|
|
21
29
|
|
22
30
|
describe "#execute" do
|
23
31
|
before do
|
32
|
+
FileUtils.mkdir_p(app_destination)
|
33
|
+
|
24
34
|
allow(Mamiya::Steps::Fetch).to receive(:new).with(
|
25
35
|
application: 'myapp',
|
26
36
|
package: 'mypkg',
|
27
|
-
destination:
|
37
|
+
destination: app_destination,
|
28
38
|
config: config,
|
29
39
|
).and_return(step)
|
30
40
|
|
@@ -43,6 +53,21 @@ describe Mamiya::Agent::Tasks::Fetch do
|
|
43
53
|
task.execute
|
44
54
|
end
|
45
55
|
|
56
|
+
context "when destination directory not exists" do
|
57
|
+
before do
|
58
|
+
FileUtils.remove_entry_secure(destination)
|
59
|
+
end
|
60
|
+
it "creates directory" do
|
61
|
+
allow(step).to receive(:run!) do
|
62
|
+
expect(Pathname.new(app_destination)).to be_exist
|
63
|
+
end
|
64
|
+
|
65
|
+
task.execute
|
66
|
+
|
67
|
+
expect(Pathname.new(app_destination)).to be_exist
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
46
71
|
context "when already fetched" do
|
47
72
|
it "does nothing" do
|
48
73
|
allow(step).to receive(:run!).and_raise(Mamiya::Storages::Abstract::AlreadyFetched)
|
data/spec/agent_spec.rb
CHANGED
@@ -117,6 +117,10 @@ describe Mamiya::Agent do
|
|
117
117
|
|
118
118
|
subject(:status) { agent.status }
|
119
119
|
|
120
|
+
it "doesn't include master=true" do
|
121
|
+
expect(status[:master]).to be_nil
|
122
|
+
end
|
123
|
+
|
120
124
|
it "includes version identifier" do
|
121
125
|
expect(status[:version]).to eq Mamiya::VERSION
|
122
126
|
end
|
@@ -129,6 +133,14 @@ describe Mamiya::Agent do
|
|
129
133
|
expect(status[:packages]).to eq agent.existing_packages
|
130
134
|
end
|
131
135
|
|
136
|
+
context "with packages=false" do
|
137
|
+
subject(:status) { agent.status(packages: false) }
|
138
|
+
|
139
|
+
it "doesn't include existing packages" do
|
140
|
+
expect(status.has_key?(:packages)).to be_false
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
132
144
|
describe "(task queue)" do
|
133
145
|
it "includes task_queue" do
|
134
146
|
expect(status[:queues]).to eq({a: {working: nil, queue: []}})
|
@@ -166,11 +178,18 @@ describe Mamiya::Agent do
|
|
166
178
|
|
167
179
|
describe "query responder" do
|
168
180
|
it "responds to 'mamiya:status'" do
|
169
|
-
allow(agent).to receive(:status).and_return("my" => "status")
|
181
|
+
allow(agent).to receive(:status).with(packages: false).and_return("my" => "status")
|
170
182
|
|
171
183
|
response = serf.trigger_query('mamiya:status', '')
|
172
184
|
expect(JSON.parse(response)).to eq("my" => "status")
|
173
185
|
end
|
186
|
+
|
187
|
+
it "responds to 'mamiya:packages'" do
|
188
|
+
allow(agent).to receive(:existing_packages).and_return(%w(pkg1 pkg2))
|
189
|
+
|
190
|
+
response = serf.trigger_query('mamiya:packages', '')
|
191
|
+
expect(JSON.parse(response)).to eq(%w(pkg1 pkg2))
|
192
|
+
end
|
174
193
|
end
|
175
194
|
|
176
195
|
describe "event handler" do
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'tmpdir'
|
3
|
+
|
4
|
+
require 'mamiya/dsl'
|
5
|
+
require 'mamiya/storages'
|
6
|
+
|
7
|
+
require 'mamiya/configuration'
|
8
|
+
|
9
|
+
describe Mamiya::Configuration do
|
10
|
+
subject(:config) { described_class.new }
|
11
|
+
|
12
|
+
it "inherits Mamiya::DSL" do
|
13
|
+
expect(described_class.ancestors).to include(Mamiya::DSL)
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "#storage_class" do
|
17
|
+
before do
|
18
|
+
config.evaluate! do
|
19
|
+
set :storage, type: :foobar, conf: :iguration
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
let(:klass) { Class.new }
|
24
|
+
|
25
|
+
before do
|
26
|
+
allow(Mamiya::Storages).to receive(:find).with(:foobar).and_return(klass)
|
27
|
+
end
|
28
|
+
|
29
|
+
subject(:storage_class) { config.storage_class }
|
30
|
+
|
31
|
+
it "finds class using Storages.find" do
|
32
|
+
expect(storage_class).to eq klass
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/spec/dsl_spec.rb
CHANGED
@@ -95,8 +95,10 @@ describe Mamiya::DSL do
|
|
95
95
|
expect{ dsl.foo }.to raise_error
|
96
96
|
dsl.set :foo, 100
|
97
97
|
expect(dsl.foo).to eq 100
|
98
|
+
expect(dsl[:foo]).to eq 100
|
98
99
|
dsl.set :foo, 200
|
99
100
|
expect(dsl.foo).to eq 200
|
101
|
+
expect(dsl[:foo]).to eq 200
|
100
102
|
end
|
101
103
|
end
|
102
104
|
|
@@ -104,6 +106,7 @@ describe Mamiya::DSL do
|
|
104
106
|
it "sets variable" do
|
105
107
|
dsl.set_default :foo, 100
|
106
108
|
expect(dsl.foo).to eq 100
|
109
|
+
expect(dsl[:foo]).to eq 100
|
107
110
|
end
|
108
111
|
|
109
112
|
context "when already assigned" do
|
@@ -111,6 +114,7 @@ describe Mamiya::DSL do
|
|
111
114
|
dsl.set :foo, 100
|
112
115
|
dsl.set_default :foo, 200
|
113
116
|
expect(dsl.foo).to eq 100
|
117
|
+
expect(dsl[:foo]).to eq 100
|
114
118
|
end
|
115
119
|
end
|
116
120
|
end
|
@@ -16,16 +16,35 @@ describe Mamiya::Master::AgentMonitor do
|
|
16
16
|
described_class.new(master)
|
17
17
|
end
|
18
18
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
}
|
19
|
+
def stub_serf_queries(expected_payload: '', expected_kwargs: {})
|
20
|
+
allow(serf).to receive(:query) do |query, payload, kwargs={}|
|
21
|
+
expect(payload).to eq expected_payload
|
22
|
+
expect(kwargs).to eq expected_kwargs
|
23
|
+
expect(%w(mamiya:status mamiya:packages)).to include(query)
|
24
|
+
|
25
|
+
{'mamiya:status' => status_query_response, 'mamiya:packages' => packages_query_response}[query]
|
27
26
|
end
|
27
|
+
end
|
28
|
+
|
29
|
+
let(:status_query_response) do
|
30
|
+
{
|
31
|
+
"Acks" => ['a'],
|
32
|
+
"Responses" => {
|
33
|
+
'a' => {"foo" => "bar", 'packages' => ['pkg1']}.to_json,
|
34
|
+
},
|
35
|
+
}
|
36
|
+
end
|
37
|
+
|
38
|
+
let(:packages_query_response) do
|
39
|
+
{
|
40
|
+
"Acks" => ['a'],
|
41
|
+
"Responses" => {
|
42
|
+
'a' => ['pkg1','pkg2'].to_json,
|
43
|
+
},
|
44
|
+
}
|
45
|
+
end
|
28
46
|
|
47
|
+
describe "#refresh" do
|
29
48
|
let(:members) do
|
30
49
|
[
|
31
50
|
{
|
@@ -38,7 +57,7 @@ describe Mamiya::Master::AgentMonitor do
|
|
38
57
|
end
|
39
58
|
|
40
59
|
before do
|
41
|
-
|
60
|
+
stub_serf_queries()
|
42
61
|
allow(serf).to receive(:members).and_return(members)
|
43
62
|
end
|
44
63
|
|
@@ -46,8 +65,49 @@ describe Mamiya::Master::AgentMonitor do
|
|
46
65
|
expect {
|
47
66
|
agent_monitor.refresh
|
48
67
|
}.to change {
|
49
|
-
agent_monitor.statuses["a"]
|
50
|
-
}.to(
|
68
|
+
agent_monitor.statuses["a"] && agent_monitor.statuses["a"]['foo']
|
69
|
+
}.to('bar')
|
70
|
+
end
|
71
|
+
|
72
|
+
it "updates status .packages by packages query" do
|
73
|
+
expect {
|
74
|
+
agent_monitor.refresh
|
75
|
+
}.to change {
|
76
|
+
agent_monitor.statuses["a"] && agent_monitor.statuses["a"]['packages']
|
77
|
+
}.to(%w(pkg1 pkg2))
|
78
|
+
end
|
79
|
+
|
80
|
+
context "when packages query unavailable, but available in status query" do
|
81
|
+
let(:packages_query_response) do
|
82
|
+
{
|
83
|
+
"Acks" => ['a'],
|
84
|
+
"Responses" => {
|
85
|
+
},
|
86
|
+
}
|
87
|
+
end
|
88
|
+
|
89
|
+
it "updates status .packages from status" do
|
90
|
+
expect {
|
91
|
+
agent_monitor.refresh
|
92
|
+
}.to change {
|
93
|
+
agent_monitor.statuses["a"] && agent_monitor.statuses["a"]['packages']
|
94
|
+
}.to(%w(pkg1))
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
context "when failed to retrieve package list, but it was available previously in packages query" do
|
99
|
+
before do
|
100
|
+
agent_monitor.refresh
|
101
|
+
packages_query_response['Responses'] = {}
|
102
|
+
end
|
103
|
+
|
104
|
+
it "keeps previous list" do
|
105
|
+
expect {
|
106
|
+
agent_monitor.refresh
|
107
|
+
}.not_to change {
|
108
|
+
agent_monitor.statuses["a"]['packages']
|
109
|
+
}
|
110
|
+
end
|
51
111
|
end
|
52
112
|
|
53
113
|
it "updates #agents" do
|
@@ -80,7 +140,7 @@ describe Mamiya::Master::AgentMonitor do
|
|
80
140
|
end
|
81
141
|
|
82
142
|
context "when some agent returned invalid status" do
|
83
|
-
let(:
|
143
|
+
let(:status_query_response) do
|
84
144
|
{
|
85
145
|
"Acks" => ['a'],
|
86
146
|
"Responses" => {
|
@@ -99,15 +159,15 @@ describe Mamiya::Master::AgentMonitor do
|
|
99
159
|
end
|
100
160
|
|
101
161
|
context "with argument" do
|
102
|
-
it "passes args to serf query" do
|
103
|
-
|
162
|
+
it "passes args to serf query", pending: 'stub_serf_queries cannot handle kwarg' do
|
163
|
+
stub_serf_queries(expected_kwargs: {node: 'foo'})
|
104
164
|
agent_monitor.refresh(node: 'foo')
|
105
165
|
end
|
106
166
|
end
|
107
167
|
end
|
108
168
|
|
109
169
|
describe "(commiting events)" do
|
110
|
-
let(:
|
170
|
+
let(:status_query_response) do
|
111
171
|
{
|
112
172
|
"Acks" => ['a'],
|
113
173
|
"Responses" => {
|
@@ -116,6 +176,14 @@ describe Mamiya::Master::AgentMonitor do
|
|
116
176
|
}
|
117
177
|
end
|
118
178
|
|
179
|
+
let(:packages_query_response) do
|
180
|
+
{
|
181
|
+
"Acks" => ['a'],
|
182
|
+
"Responses" => {
|
183
|
+
},
|
184
|
+
}
|
185
|
+
end
|
186
|
+
|
119
187
|
let(:members) do
|
120
188
|
[
|
121
189
|
{
|
@@ -142,7 +210,7 @@ describe Mamiya::Master::AgentMonitor do
|
|
142
210
|
end
|
143
211
|
|
144
212
|
before do
|
145
|
-
|
213
|
+
stub_serf_queries()
|
146
214
|
allow(serf).to receive(:members).and_return(members)
|
147
215
|
|
148
216
|
agent_monitor.refresh
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mamiya
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.1.
|
4
|
+
version: 0.0.1.alpha21
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Shota Fukumori (sora_h)
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-08-
|
11
|
+
date: 2014-08-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|
@@ -171,6 +171,9 @@ files:
|
|
171
171
|
- docs/sequences/deploy.png
|
172
172
|
- docs/sequences/deploy.uml
|
173
173
|
- example.rb
|
174
|
+
- example/Procfile
|
175
|
+
- example/config.rb
|
176
|
+
- example/deploy.rb
|
174
177
|
- lib/mamiya.rb
|
175
178
|
- lib/mamiya/agent.rb
|
176
179
|
- lib/mamiya/agent/actions.rb
|
@@ -183,7 +186,7 @@ files:
|
|
183
186
|
- lib/mamiya/agent/tasks/notifyable.rb
|
184
187
|
- lib/mamiya/cli.rb
|
185
188
|
- lib/mamiya/cli/client.rb
|
186
|
-
- lib/mamiya/
|
189
|
+
- lib/mamiya/configuration.rb
|
187
190
|
- lib/mamiya/dsl.rb
|
188
191
|
- lib/mamiya/helpers/git.rb
|
189
192
|
- lib/mamiya/logger.rb
|
@@ -215,7 +218,7 @@ files:
|
|
215
218
|
- spec/agent/tasks/fetch_spec.rb
|
216
219
|
- spec/agent/tasks/notifyable_spec.rb
|
217
220
|
- spec/agent_spec.rb
|
218
|
-
- spec/
|
221
|
+
- spec/configuration_spec.rb
|
219
222
|
- spec/dsl_spec.rb
|
220
223
|
- spec/fixtures/dsl_test_load.rb
|
221
224
|
- spec/fixtures/dsl_test_use.rb
|
@@ -274,7 +277,7 @@ test_files:
|
|
274
277
|
- spec/agent/tasks/fetch_spec.rb
|
275
278
|
- spec/agent/tasks/notifyable_spec.rb
|
276
279
|
- spec/agent_spec.rb
|
277
|
-
- spec/
|
280
|
+
- spec/configuration_spec.rb
|
278
281
|
- spec/dsl_spec.rb
|
279
282
|
- spec/fixtures/dsl_test_load.rb
|
280
283
|
- spec/fixtures/dsl_test_use.rb
|
data/lib/mamiya/config.rb
DELETED
@@ -1,57 +0,0 @@
|
|
1
|
-
require 'yaml'
|
2
|
-
require 'mamiya/storages'
|
3
|
-
|
4
|
-
module Mamiya
|
5
|
-
class Config
|
6
|
-
def self.load(file)
|
7
|
-
self.new YAML.load(ERB.new(File.read(file)).result(binding))
|
8
|
-
end
|
9
|
-
|
10
|
-
def initialize(config_hash = {})
|
11
|
-
@config = symbolize_keys_in(config_hash)
|
12
|
-
end
|
13
|
-
|
14
|
-
def [](key)
|
15
|
-
@config[key]
|
16
|
-
end
|
17
|
-
|
18
|
-
def []=(key, value)
|
19
|
-
@config[key] = value
|
20
|
-
end
|
21
|
-
|
22
|
-
def storage_class
|
23
|
-
self[:storage] && Storages.find(self[:storage][:type])
|
24
|
-
end
|
25
|
-
|
26
|
-
def deploy_to_for_app(app)
|
27
|
-
# TODO: test
|
28
|
-
app = app.to_sym
|
29
|
-
|
30
|
-
if self[:apps] && self[:applications][app]
|
31
|
-
Pathname.new(self[:applications][app][:deploy_to])
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
def releases_path_for_app(app)
|
36
|
-
# TODO: test
|
37
|
-
deploy_to_for_app(app).join('releases')
|
38
|
-
end
|
39
|
-
|
40
|
-
private
|
41
|
-
|
42
|
-
def symbolize_keys_in(hash)
|
43
|
-
Hash[hash.map { |k, v|
|
44
|
-
case v
|
45
|
-
when Hash
|
46
|
-
v = symbolize_keys_in(v)
|
47
|
-
when Array
|
48
|
-
if v.find { |_| _.kind_of?(Hash) }
|
49
|
-
v = v.map { |_| _.kind_of?(Hash) ? symbolize_keys_in(_) : _ }
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
[k.to_sym, v]
|
54
|
-
}]
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
data/spec/config_spec.rb
DELETED
@@ -1,50 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'mamiya/storages'
|
3
|
-
|
4
|
-
require 'mamiya/config'
|
5
|
-
|
6
|
-
describe Mamiya::Config do
|
7
|
-
let(:source) do
|
8
|
-
{
|
9
|
-
"test" => {
|
10
|
-
"a" => ["b" => {"c" => {"d" => "e"}}]
|
11
|
-
},
|
12
|
-
:test2 => :hello
|
13
|
-
}
|
14
|
-
end
|
15
|
-
subject(:config) { described_class.new(source) }
|
16
|
-
|
17
|
-
describe ".load" do
|
18
|
-
let(:fixture_path) { File.join(__dir__, 'fixtures', 'test.yml') }
|
19
|
-
|
20
|
-
subject(:config) { described_class.load(fixture_path) }
|
21
|
-
|
22
|
-
it { should be_a(described_class) }
|
23
|
-
|
24
|
-
it "loads configuration from file" do
|
25
|
-
expect(config[:a][:e]).to eq "f"
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
it "symbolizes keys" do
|
30
|
-
expect(config[:test][:a][0][:b][:c][:d]).to eq "e"
|
31
|
-
expect(config[:test2]).to eq :hello
|
32
|
-
end
|
33
|
-
|
34
|
-
describe "#storage_class" do
|
35
|
-
let(:source) do
|
36
|
-
{storage: {type: :foobar, conf: :iguration}}
|
37
|
-
end
|
38
|
-
let(:klass) { Class.new }
|
39
|
-
|
40
|
-
before do
|
41
|
-
allow(Mamiya::Storages).to receive(:find).with(:foobar).and_return(klass)
|
42
|
-
end
|
43
|
-
|
44
|
-
subject(:storage_class) { config.storage_class }
|
45
|
-
|
46
|
-
it "finds class using Storages.find" do
|
47
|
-
expect(storage_class).to eq klass
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|