mamiya 0.0.1.alpha8 → 0.0.1.alpha9
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 +1 -0
- data/docs/cli.md +78 -0
- data/lib/mamiya/agent/fetcher.rb +45 -17
- data/lib/mamiya/agent.rb +19 -1
- data/lib/mamiya/cli.rb +9 -5
- data/lib/mamiya/master/agent_monitor_handlers.rb +6 -0
- data/lib/mamiya/master.rb +5 -0
- data/lib/mamiya/version.rb +1 -1
- data/mamiya.gemspec +1 -0
- data/spec/agent/fetcher_spec.rb +47 -9
- data/spec/agent_spec.rb +6 -1
- data/spec/master/agent_monitor_spec.rb +4 -2
- data/spec/spec_helper.rb +5 -0
- metadata +17 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3f7822be0f2ea92b439156730db75fc2608820ec
|
4
|
+
data.tar.gz: 34495ba570dab6778304c2f0cc68b2fdc9914477
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a15d9f6afd8b69c60e12e22609fe1e713f5da3d85c1272923b171fc04946655e2cc6c19142e9af7d1b6e44927a80a59ccc79b59644dc15700a8b898da2a48a19
|
7
|
+
data.tar.gz: c3fddda1d60e1e2b348c6c0b635426abc9d265fe9a42bcbb9b22908063a62e41a4e32f536299d5c69f7841b7e99b5625ce995a4f311a00e25c0e30cd12ec2b64
|
data/.gitignore
CHANGED
data/docs/cli.md
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
# Commands
|
2
|
+
|
3
|
+
## Global options
|
4
|
+
|
5
|
+
- `-C`, `--config`: path to configuration file (default: `./config.yml`)
|
6
|
+
- config file won't be required if a command don't need it.
|
7
|
+
- `-S`, `--script`: path to script file (default: `./deploy.rb`)
|
8
|
+
- script file won't be required if a command don't need it.
|
9
|
+
- `-a`, `--app`: Specify application name to operate
|
10
|
+
- `-d`, `--debug`: Enable debug mode
|
11
|
+
- `--color`, `--no-color`: Enable or disable colored output. When the stdout is a terminal, it'll be enabled by default.
|
12
|
+
|
13
|
+
## Storage related commands
|
14
|
+
|
15
|
+
### `list-applications` - list application in storage
|
16
|
+
|
17
|
+
```
|
18
|
+
$ mamiya list-applications -C ./config.yml
|
19
|
+
```
|
20
|
+
|
21
|
+
### `list-packages` - list packages for specified app in storage
|
22
|
+
|
23
|
+
```
|
24
|
+
$ mamiya list-packages -C ./config.yml -a myapp
|
25
|
+
```
|
26
|
+
|
27
|
+
- __Requires:__ configuration file, application name
|
28
|
+
- application name will be retrieved from deploy script when not specified.
|
29
|
+
- __Options:__
|
30
|
+
- `-n`, `--name-only`: Show only names (without heading text)
|
31
|
+
|
32
|
+
### `show` - show package information
|
33
|
+
|
34
|
+
```
|
35
|
+
$ mamiya list-packages -C ./config.yml -a myapp PACKAGE_NAME
|
36
|
+
```
|
37
|
+
|
38
|
+
- __Requires:__ configuration file, application name, package name
|
39
|
+
- application name will be retrieved from deploy script when not specified.
|
40
|
+
- __Options:__
|
41
|
+
- `-f`, `--format`: Choose output format from `pp`, `json`, or `yaml`. Default: `pp`.
|
42
|
+
|
43
|
+
## Build, pushing and fetching packages
|
44
|
+
|
45
|
+
### `build` - build package using script
|
46
|
+
|
47
|
+
```
|
48
|
+
$ mamiya build --script ./deploy.rb --source source_dir --destination dest_dir
|
49
|
+
```
|
50
|
+
|
51
|
+
- __Requires:__ application name, source, destination, deploy script
|
52
|
+
- source, description, and app name will be taken from deploy script, if omitted
|
53
|
+
- __Options:__
|
54
|
+
- `-f`, `--source`, `--build-from`: directory for package source.
|
55
|
+
- `-t`, `--destination`, `--build-to`: directory to save built packages.
|
56
|
+
- `-P`, `--skip-prepare-build`: Skip prepare build phase of deploy script.
|
57
|
+
|
58
|
+
### `push` - push built package to the storage
|
59
|
+
|
60
|
+
### `fetch`
|
61
|
+
|
62
|
+
## Package related commands
|
63
|
+
|
64
|
+
### `extract`
|
65
|
+
|
66
|
+
## `client` - API client for `mamiya master`
|
67
|
+
|
68
|
+
### `list-applications`
|
69
|
+
|
70
|
+
### `list-packages`
|
71
|
+
|
72
|
+
### `show-package`
|
73
|
+
|
74
|
+
### `list-agents`
|
75
|
+
|
76
|
+
### `show-agent`
|
77
|
+
|
78
|
+
### `show-distribution`
|
data/lib/mamiya/agent/fetcher.rb
CHANGED
@@ -11,52 +11,63 @@ module Mamiya
|
|
11
11
|
GRACEFUL_TIMEOUT = 60
|
12
12
|
|
13
13
|
def initialize(config, logger: Mamiya::Logger.new)
|
14
|
-
@
|
15
|
-
@
|
14
|
+
@worker_thread = nil
|
15
|
+
@queueing_thread = nil
|
16
|
+
@external_queue = Queue.new
|
17
|
+
@internal_queue = Queue.new
|
16
18
|
|
17
19
|
@config = config
|
18
20
|
@destination = config[:packages_dir]
|
19
21
|
@keep_packages = config[:keep_packages]
|
20
22
|
@current_job = nil
|
23
|
+
@pending_jobs = []
|
21
24
|
|
22
25
|
@logger = logger['fetcher']
|
23
|
-
@working = nil
|
24
26
|
end
|
25
27
|
|
26
|
-
attr_reader :
|
28
|
+
attr_reader :worker_thread
|
29
|
+
attr_reader :queueing_thread
|
27
30
|
attr_reader :current_job
|
31
|
+
attr_reader :pending_jobs
|
28
32
|
attr_writer :cleanup_hook
|
29
33
|
|
30
34
|
def enqueue(app, package, before: nil, &callback)
|
31
|
-
@
|
35
|
+
@external_queue << [app, package, before, callback]
|
32
36
|
end
|
33
37
|
|
34
38
|
def queue_size
|
35
|
-
@
|
39
|
+
@internal_queue.size
|
36
40
|
end
|
37
41
|
|
38
42
|
def start!
|
43
|
+
stop!
|
39
44
|
@logger.info 'Starting...'
|
40
45
|
|
41
|
-
@
|
42
|
-
@
|
46
|
+
@worker_thread = Thread.new(&method(:main_loop))
|
47
|
+
@worker_thread.abort_on_exception = true
|
48
|
+
|
49
|
+
@queueing_thread = Thread.new(&method(:queueing_loop))
|
50
|
+
@queueing_thread.abort_on_exception = true
|
43
51
|
end
|
44
52
|
|
45
53
|
def stop!(graceful = false)
|
46
|
-
|
54
|
+
{@external_queue => @queueing_thread, @internal_queue => @worker_thread}.each do |q, th|
|
55
|
+
next unless th
|
56
|
+
if graceful
|
57
|
+
q << :suicide
|
58
|
+
th.join(GRACEFUL_TIMEOUT)
|
59
|
+
end
|
47
60
|
|
48
|
-
|
49
|
-
@queue << :suicide
|
50
|
-
@thread.join(GRACEFUL_TIMEOUT)
|
61
|
+
th.kill if th.alive?
|
51
62
|
end
|
52
|
-
|
53
|
-
@thread.kill if @thread.alive?
|
54
63
|
ensure
|
55
|
-
@
|
64
|
+
@worker_thread = nil
|
65
|
+
@queueing_thread = nil
|
56
66
|
end
|
57
67
|
|
58
68
|
def running?
|
59
|
-
@
|
69
|
+
@worker_thread && @worker_thread.alive? && \
|
70
|
+
@queueing_thread && @queueing_thread.alive?
|
60
71
|
end
|
61
72
|
|
62
73
|
def working?
|
@@ -88,15 +99,31 @@ module Mamiya
|
|
88
99
|
private
|
89
100
|
|
90
101
|
def main_loop
|
91
|
-
while order = @
|
102
|
+
while order = @internal_queue.pop
|
92
103
|
break if order == :suicide
|
104
|
+
@pending_jobs.delete(order)
|
93
105
|
handle_order(*order)
|
94
106
|
end
|
95
107
|
end
|
96
108
|
|
109
|
+
def queueing_loop
|
110
|
+
while order = @external_queue.pop
|
111
|
+
break if order == :suicide
|
112
|
+
@pending_jobs << order
|
113
|
+
@internal_queue << order
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
97
117
|
def handle_order(app, package, before_hook = nil, callback = nil)
|
98
118
|
@current_job = [app, package]
|
99
119
|
@logger.info "fetching #{app}:#{package}"
|
120
|
+
|
121
|
+
if @config[:fetch_sleep]
|
122
|
+
wait = rand(@config[:fetch_sleep])
|
123
|
+
@logger.debug "Sleeping #{wait} before starting fetch"
|
124
|
+
sleep wait
|
125
|
+
end
|
126
|
+
|
100
127
|
# TODO: Limit apps by configuration
|
101
128
|
|
102
129
|
destination = File.join(@destination, app)
|
@@ -113,6 +140,7 @@ module Mamiya
|
|
113
140
|
config: @config,
|
114
141
|
).run!
|
115
142
|
|
143
|
+
@current_job = nil
|
116
144
|
callback.call if callback
|
117
145
|
|
118
146
|
@logger.info "fetched #{app}:#{package}"
|
data/lib/mamiya/agent.rb
CHANGED
@@ -18,6 +18,8 @@ module Mamiya
|
|
18
18
|
@serf = init_serf
|
19
19
|
@events_only = events_only
|
20
20
|
|
21
|
+
@terminate = false
|
22
|
+
|
21
23
|
@logger = logger['agent']
|
22
24
|
end
|
23
25
|
|
@@ -35,15 +37,30 @@ module Mamiya
|
|
35
37
|
logger.info "Started."
|
36
38
|
|
37
39
|
loop do
|
38
|
-
|
40
|
+
if @terminate
|
41
|
+
terminate
|
42
|
+
return
|
43
|
+
end
|
44
|
+
sleep 1
|
39
45
|
end
|
40
46
|
end
|
41
47
|
|
48
|
+
def stop!
|
49
|
+
@terminate = true
|
50
|
+
end
|
51
|
+
|
42
52
|
def start
|
43
53
|
serf_start
|
44
54
|
fetcher_start
|
45
55
|
end
|
46
56
|
|
57
|
+
def terminate
|
58
|
+
serf.stop!
|
59
|
+
fetcher.stop!
|
60
|
+
ensure
|
61
|
+
@terminate = false
|
62
|
+
end
|
63
|
+
|
47
64
|
def update_tags!
|
48
65
|
serf.tags['mamiya'] = ','.tap do |status|
|
49
66
|
status.concat('fetching,') if fetcher.working?
|
@@ -63,6 +80,7 @@ module Mamiya
|
|
63
80
|
s[:fetcher] = {
|
64
81
|
fetching: fetcher.current_job,
|
65
82
|
pending: fetcher.queue_size,
|
83
|
+
pending_jobs: fetcher.pending_jobs.map{ |_| _[0,2] },
|
66
84
|
}
|
67
85
|
|
68
86
|
s[:packages] = self.existing_packages
|
data/lib/mamiya/cli.rb
CHANGED
@@ -179,8 +179,8 @@ module Mamiya
|
|
179
179
|
prepare_agent_behavior!
|
180
180
|
merge_serf_option!
|
181
181
|
|
182
|
-
agent = Agent.new(config, logger: logger)
|
183
|
-
agent.run!
|
182
|
+
@agent = Agent.new(config, logger: logger)
|
183
|
+
@agent.run!
|
184
184
|
end
|
185
185
|
|
186
186
|
desc "master", "Start master"
|
@@ -192,8 +192,8 @@ module Mamiya
|
|
192
192
|
prepare_agent_behavior!
|
193
193
|
merge_serf_option!
|
194
194
|
|
195
|
-
agent = Master.new(config, logger: logger)
|
196
|
-
agent.run!
|
195
|
+
@agent = Master.new(config, logger: logger)
|
196
|
+
@agent.run!
|
197
197
|
end
|
198
198
|
|
199
199
|
# def worker
|
@@ -216,9 +216,13 @@ module Mamiya
|
|
216
216
|
end
|
217
217
|
|
218
218
|
trap(:HUP) do
|
219
|
-
$stderr.puts "hi"
|
220
219
|
logger.reopen
|
221
220
|
end
|
221
|
+
|
222
|
+
trap(:TERM) do
|
223
|
+
puts "Received SIGTERM..."
|
224
|
+
@agent.stop! if @agent
|
225
|
+
end
|
222
226
|
end
|
223
227
|
|
224
228
|
def config(dont_raise_error = false)
|
@@ -6,11 +6,17 @@ module Mamiya
|
|
6
6
|
def fetch_result__ack(status, payload, event)
|
7
7
|
status['fetcher'] ||= {}
|
8
8
|
status['fetcher']['pending'] = payload['pending']
|
9
|
+
|
10
|
+
status['fetcher']['pending_jobs'] ||= []
|
11
|
+
status['fetcher']['pending_jobs'] << [payload['application'], payload['package']]
|
9
12
|
end
|
10
13
|
|
11
14
|
def fetch_result__start(status, payload, event)
|
12
15
|
status['fetcher'] ||= {}
|
13
16
|
status['fetcher']['fetching'] = [payload['application'], payload['package']]
|
17
|
+
|
18
|
+
status['fetcher']['pending_jobs'] ||= []
|
19
|
+
status['fetcher']['pending_jobs'].delete [payload['application'], payload['package']]
|
14
20
|
end
|
15
21
|
|
16
22
|
def fetch_result__error(status, payload, event)
|
data/lib/mamiya/master.rb
CHANGED
data/lib/mamiya/version.rb
CHANGED
data/mamiya.gemspec
CHANGED
data/spec/agent/fetcher_spec.rb
CHANGED
@@ -6,6 +6,7 @@ require 'fileutils'
|
|
6
6
|
require 'mamiya/agent/fetcher'
|
7
7
|
require 'mamiya/steps/fetch'
|
8
8
|
|
9
|
+
|
9
10
|
describe Mamiya::Agent::Fetcher do
|
10
11
|
let!(:tmpdir) { Dir.mktmpdir('mamiya-agent-fetcher-spec') }
|
11
12
|
after { FileUtils.remove_entry_secure(tmpdir) if File.exist?(tmpdir) }
|
@@ -18,22 +19,22 @@ describe Mamiya::Agent::Fetcher do
|
|
18
19
|
|
19
20
|
describe "lifecycle" do
|
20
21
|
it "can start and stop" do
|
21
|
-
expect(fetcher.
|
22
|
+
expect(fetcher.worker_thread).to be_nil
|
22
23
|
expect(fetcher).not_to be_running
|
23
24
|
|
24
25
|
fetcher.start!
|
25
26
|
|
26
27
|
expect(fetcher).to be_running
|
27
|
-
expect(fetcher.
|
28
|
-
expect(fetcher.
|
29
|
-
th = fetcher.
|
28
|
+
expect(fetcher.worker_thread).to be_a(Thread)
|
29
|
+
expect(fetcher.worker_thread).to be_alive
|
30
|
+
th = fetcher.worker_thread
|
30
31
|
|
31
32
|
fetcher.stop!
|
32
33
|
|
33
|
-
|
34
|
+
20.times { break unless th.alive?; sleep 0.1 }
|
34
35
|
expect(th).not_to be_alive
|
35
36
|
|
36
|
-
expect(fetcher.
|
37
|
+
expect(fetcher.worker_thread).to be_nil
|
37
38
|
expect(fetcher).not_to be_running
|
38
39
|
end
|
39
40
|
|
@@ -92,6 +93,33 @@ describe Mamiya::Agent::Fetcher do
|
|
92
93
|
end
|
93
94
|
end
|
94
95
|
|
96
|
+
describe "#pending_jobs" do
|
97
|
+
before do
|
98
|
+
step = double('fetch-step')
|
99
|
+
allow(step).to receive(:run!)
|
100
|
+
allow(Mamiya::Steps::Fetch).to receive(:new).with(
|
101
|
+
application: 'myapp',
|
102
|
+
package: 'package',
|
103
|
+
destination: File.join(tmpdir, 'myapp'),
|
104
|
+
config: config,
|
105
|
+
).and_return(step)
|
106
|
+
end
|
107
|
+
|
108
|
+
it "shows remaining jobs" do
|
109
|
+
fetcher.start!; fetcher.worker_thread.kill
|
110
|
+
|
111
|
+
expect {
|
112
|
+
fetcher.enqueue('myapp', 'package')
|
113
|
+
fetcher.stop!(:graceful)
|
114
|
+
}.to change { fetcher.pending_jobs } \
|
115
|
+
.from([]).to([['myapp', 'package', nil, nil]])
|
116
|
+
|
117
|
+
fetcher.start!; fetcher.stop!(:graceful)
|
118
|
+
|
119
|
+
expect(fetcher.pending_jobs).to be_empty
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
95
123
|
describe "mainloop" do
|
96
124
|
before do
|
97
125
|
allow(step).to receive(:run!)
|
@@ -122,6 +150,7 @@ describe Mamiya::Agent::Fetcher do
|
|
122
150
|
received = true
|
123
151
|
|
124
152
|
fetcher.enqueue('myapp', 'package') do |succeeded|
|
153
|
+
expect(fetcher.working?).to be_false
|
125
154
|
received = succeeded
|
126
155
|
end
|
127
156
|
|
@@ -141,11 +170,11 @@ describe Mamiya::Agent::Fetcher do
|
|
141
170
|
expect(fetcher.current_job).to be_nil
|
142
171
|
|
143
172
|
received = false
|
144
|
-
fetcher.enqueue
|
145
|
-
received = true
|
173
|
+
fetcher.enqueue 'myapp', 'package', before: proc { |error|
|
146
174
|
expect(fetcher.working?).to be_true
|
147
175
|
expect(fetcher.current_job).to eq %w(myapp package)
|
148
|
-
|
176
|
+
received = true
|
177
|
+
}
|
149
178
|
|
150
179
|
fetcher.stop!(:graceful)
|
151
180
|
expect(received).to be_true
|
@@ -153,6 +182,15 @@ describe Mamiya::Agent::Fetcher do
|
|
153
182
|
expect(fetcher.current_job).to be_nil
|
154
183
|
end
|
155
184
|
|
185
|
+
context "with config.fetch_sleep" do
|
186
|
+
it "calls sleep" do
|
187
|
+
config[:fetch_sleep] = 1
|
188
|
+
expect(fetcher).to receive(:sleep)
|
189
|
+
fetcher.enqueue 'myapp', 'package'
|
190
|
+
fetcher.stop!(:graceful)
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
156
194
|
context "with before hook" do
|
157
195
|
it "calls callback" do
|
158
196
|
run = false
|
data/spec/agent_spec.rb
CHANGED
@@ -111,7 +111,8 @@ describe Mamiya::Agent do
|
|
111
111
|
allow(agent).to receive(:existing_packages).and_return("app" => ["pkg"])
|
112
112
|
allow(fetcher).to receive(:queue_size).and_return(42)
|
113
113
|
allow(fetcher).to receive(:working?).and_return(false)
|
114
|
-
|
114
|
+
allow(fetcher).to receive(:current_job).and_return(nil)
|
115
|
+
allow(fetcher).to receive(:pending_jobs).and_return([['app', 'pkg2', nil, nil]])
|
115
116
|
end
|
116
117
|
|
117
118
|
subject(:status) { agent.status }
|
@@ -129,6 +130,10 @@ describe Mamiya::Agent do
|
|
129
130
|
expect(status[:fetcher][:pending]).to eq 42
|
130
131
|
end
|
131
132
|
|
133
|
+
it "includes pendings job" do
|
134
|
+
expect(status[:fetcher][:pending_jobs]).to eq([['app', 'pkg2']])
|
135
|
+
end
|
136
|
+
|
132
137
|
it "shows fetching status" do
|
133
138
|
expect(status[:fetcher][:fetching]).to be_nil
|
134
139
|
end
|
@@ -157,20 +157,22 @@ describe Mamiya::Master::AgentMonitor do
|
|
157
157
|
end
|
158
158
|
|
159
159
|
it "updates pending" do
|
160
|
-
commit('mamiya:fetch-result:ack', pending: 72)
|
160
|
+
commit('mamiya:fetch-result:ack', pending: 72, application: 'foo', package: 'bar')
|
161
161
|
expect(new_status["fetcher"]["pending"]).to eq 72
|
162
|
+
expect(new_status["fetcher"]["pending_jobs"]).to eq [%w(foo bar)]
|
162
163
|
end
|
163
164
|
end
|
164
165
|
|
165
166
|
describe ":start" do
|
166
167
|
let(:status) do
|
167
|
-
{fetcher: {fetching: nil, pending:
|
168
|
+
{fetcher: {fetching: nil, pending: 1, pending_jobs: [%w(app pkg)]}}
|
168
169
|
end
|
169
170
|
|
170
171
|
it "updates fetching" do
|
171
172
|
commit('mamiya:fetch-result:start',
|
172
173
|
application: 'app', package: 'pkg', pending: 0)
|
173
174
|
expect(new_status["fetcher"]["fetching"]).to eq ['app', 'pkg']
|
175
|
+
expect(new_status["fetcher"]["pending_jobs"]).to be_empty
|
174
176
|
end
|
175
177
|
end
|
176
178
|
|
data/spec/spec_helper.rb
CHANGED
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.alpha9
|
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-06-
|
11
|
+
date: 2014-06-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|
@@ -136,6 +136,20 @@ dependencies:
|
|
136
136
|
- - ">="
|
137
137
|
- !ruby/object:Gem::Version
|
138
138
|
version: '0'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: simplecov
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - "~>"
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: 0.7.1
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - "~>"
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: 0.7.1
|
139
153
|
description: Deploy tool using tarballs and serf for lot of servers
|
140
154
|
email:
|
141
155
|
- her@sorah.jp
|
@@ -153,6 +167,7 @@ files:
|
|
153
167
|
- Rakefile
|
154
168
|
- bin/mamiya
|
155
169
|
- config.example.yml
|
170
|
+
- docs/cli.md
|
156
171
|
- docs/sequences/deploy.png
|
157
172
|
- docs/sequences/deploy.uml
|
158
173
|
- example.rb
|