mamiya 0.2.1 → 0.2.2
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 +9 -15
- data/docs/quick_start.md +212 -0
- data/lib/mamiya/cli/client.rb +3 -5
- data/lib/mamiya/storages/s3.rb +16 -1
- data/lib/mamiya/version.rb +1 -1
- data/spec/storages/s3_spec.rb +19 -3
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3fff2664bac4156374129f9094fe5fc7459d3b8b
|
4
|
+
data.tar.gz: efe0195812cbb482507dae05cacbb05cf8ca57a1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ed7ec72684c57cd099a95e2c66bca126637dd8837eb5c66ea2b9b74fc6a289b87acf041359289319ff79684ed3e6e3ebd56266d3facf1d14b21dd80cebb86083
|
7
|
+
data.tar.gz: aa23567e2219203fb190e5436398c5ae934baceb0ced7dcb7e4e1c226cfeb83c404c32fbb617d358fa37e9e31657556352e8f89caaf9a4384e02ed9aec1206b1
|
data/README.md
CHANGED
@@ -2,23 +2,17 @@
|
|
2
2
|
|
3
3
|
[](https://travis-ci.org/sorah/mamiya)
|
4
4
|
|
5
|
-
Mamiya allows you to deploy using without ssh -- using tarballs, some storages (S3, etc), and [Serf](http://www.serfdom.io/).
|
6
5
|
|
7
|
-
##
|
6
|
+
## What's mamiya?
|
8
7
|
|
9
|
-
(
|
8
|
+
Mamiya allows you to deploy without ssh -- using tarballs, some storages (S3, etc), and [Serf](http://www.serfdom.io/).
|
9
|
+
Build application package on CI or somewhere, then distribute earlier (before you say "Deploy!"). You can switch to a new application quickly, when you're saying "deploy."
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
4. Write deploy script for your own
|
17
|
-
- how to build package, how to prepare release, how to release, etc.
|
18
|
-
5. Build then push package
|
19
|
-
- `mamiya build`
|
20
|
-
- `mamiya push path/to/package.tar.gz`
|
21
|
-
6. Time to deploy: `mamiya client deploy -a app package`
|
11
|
+
Mamiya uses similar directory structure with Capistrano 'deploy_to' -- you can try this easy.
|
12
|
+
|
13
|
+
## Quick Start
|
14
|
+
|
15
|
+
See [./docs/quick_start.md](./docs/quick_start.md).
|
22
16
|
|
23
17
|
### Example configuration
|
24
18
|
|
@@ -30,7 +24,7 @@ Try Mamiya in your local machine: `foreman start`
|
|
30
24
|
Existing major deploy tools (capistrano, mina, ...) use SSH to operate servers.
|
31
25
|
But connecting to lot of servers via SSH makes deployment slow.
|
32
26
|
|
33
|
-
|
27
|
+
Mamiya solves such problem by using [Serf](http://www.serfdom.io/) and tarball on one storage (Amazon S3).
|
34
28
|
|
35
29
|
Also, I'm planning to allow to distribute files before the deploy command. I guess this can skip or shorten
|
36
30
|
file transferring phase in deploy.
|
data/docs/quick_start.md
ADDED
@@ -0,0 +1,212 @@
|
|
1
|
+
# Quick Start
|
2
|
+
|
3
|
+
## What's mamiya?
|
4
|
+
|
5
|
+
Mamiya allows you to deploy using without ssh -- using tarballs, some storages (S3, etc), and [Serf](http://www.serfdom.io/).
|
6
|
+
Build application package on CI or somewhere, then distribute earlier (before you say "Deploy!"). You can switch to an new application quickly, when you're saying "deploy."
|
7
|
+
|
8
|
+
Also, this free you from SSH and RSync problems.
|
9
|
+
|
10
|
+
## Concepts
|
11
|
+
|
12
|
+
- __Package__ is a tarball contains your application.
|
13
|
+
- __Storage__ is a place to store package.
|
14
|
+
- __Script__ is a Ruby script that defines how to deploy (prepare, restart, etc) your application.
|
15
|
+
|
16
|
+
- __CI (or, somewhere)__ builds packages and push them on _Storage_
|
17
|
+
- __Master__ controls the cluster of _Agents_
|
18
|
+
- __Agent__ receives deployment and do it.
|
19
|
+
|
20
|
+
## Prepare master and agent
|
21
|
+
|
22
|
+
Run `sudo gem install mamiya` to install mamiya on your systems.
|
23
|
+
|
24
|
+
(TODO: write init.d/systemd/upstart script for easier boot up)
|
25
|
+
|
26
|
+
### Master
|
27
|
+
|
28
|
+
On a server for master node; it'll controll the cluster:
|
29
|
+
|
30
|
+
#### Configure
|
31
|
+
|
32
|
+
typical configuration for the master here:
|
33
|
+
|
34
|
+
``` ruby
|
35
|
+
# /etc/mamiya/config.rb
|
36
|
+
|
37
|
+
set :storage, {
|
38
|
+
type: :s3,
|
39
|
+
bucket: 'YOUR-S3-BUCKET-NAME',
|
40
|
+
region: 'ap-northeast-1', # set it to your region
|
41
|
+
access_key_id: '...',
|
42
|
+
secret_access_key: '...',
|
43
|
+
}
|
44
|
+
|
45
|
+
set :serf, {
|
46
|
+
agent: {
|
47
|
+
bind: "0.0.0.0:7760",
|
48
|
+
rpc_addr: "127.0.0.1:7762",
|
49
|
+
}
|
50
|
+
}
|
51
|
+
|
52
|
+
set :web, {
|
53
|
+
port: 7761,
|
54
|
+
}
|
55
|
+
```
|
56
|
+
|
57
|
+
#### Run it
|
58
|
+
|
59
|
+
```
|
60
|
+
mamiya master -c /etc/mamiya/config.rb
|
61
|
+
```
|
62
|
+
|
63
|
+
### Agent
|
64
|
+
|
65
|
+
On a server for agent node; where the package will be deployed:
|
66
|
+
|
67
|
+
#### Configure
|
68
|
+
|
69
|
+
typical configuration for the agents here:
|
70
|
+
|
71
|
+
``` ruby
|
72
|
+
# /etc/mamiya/config.rb
|
73
|
+
|
74
|
+
set :storage, {
|
75
|
+
type: :s3,
|
76
|
+
bucket: 'YOUR-S3-BUCKET-NAME',
|
77
|
+
region: 'ap-northeast-1', # set it to your region
|
78
|
+
access_key_id: '...',
|
79
|
+
secret_access_key: '...',
|
80
|
+
}
|
81
|
+
|
82
|
+
set :serf, {
|
83
|
+
agent: {
|
84
|
+
bind: "0.0.0.0:7760",
|
85
|
+
rpc_addr: "127.0.0.1:7762",
|
86
|
+
join: 'YOUR-MASTER-HOST:7760', # set it to your master host
|
87
|
+
}
|
88
|
+
}
|
89
|
+
|
90
|
+
set :web, {
|
91
|
+
port: 7761,
|
92
|
+
}
|
93
|
+
|
94
|
+
# Where should the application go. :myapp is a Symbol to identify application.
|
95
|
+
applications[:myapp] = {deploy_to: '/home/app/myapp'}
|
96
|
+
|
97
|
+
# Where should Mamiya store packages, pre-releases temporarily.
|
98
|
+
set :packages_dir, '/tmp/mamiya/packages'
|
99
|
+
set :prereleases_dir, '/tmp/mamiya/prereleases'
|
100
|
+
|
101
|
+
# And how many you want to keep them?
|
102
|
+
set :keep_packages, 3
|
103
|
+
set :keep_prereleases, 3
|
104
|
+
|
105
|
+
# Label your agent. Block will be called every time when referencing labels.
|
106
|
+
# (Recommend to implement thread or timeout for periodically fetch...)
|
107
|
+
labels do
|
108
|
+
%i(app production active)
|
109
|
+
end
|
110
|
+
```
|
111
|
+
|
112
|
+
#### Run it
|
113
|
+
|
114
|
+
```
|
115
|
+
mamiya master -c /etc/mamiya/config.rb
|
116
|
+
```
|
117
|
+
|
118
|
+
### Confirm both working
|
119
|
+
|
120
|
+
Use `mamiya client` command family to communicate with master process. By default `http://localhost:7761/` is used. You can change by `-m`, `--master` option or `$MAMIYA_MASTER_URL` environment variable.
|
121
|
+
|
122
|
+
```
|
123
|
+
master $ mamiya client list-agents
|
124
|
+
AGENT_NAME alive
|
125
|
+
```
|
126
|
+
|
127
|
+
## Prepare deploy script
|
128
|
+
|
129
|
+
_Script_ should have required operations and configurations for an application being deployed.
|
130
|
+
|
131
|
+
Script is used for package building and deployments. It'll be copied into a package during package build, then deliver, used on agents.
|
132
|
+
|
133
|
+
```
|
134
|
+
set :application, 'myapp'
|
135
|
+
|
136
|
+
# Using for package build
|
137
|
+
set :exclude_from_package, ['tmp', 'log', 'spec', '.sass-cache']
|
138
|
+
set :dereference_symlinks, true
|
139
|
+
set :build_from, "/tmp/build_from"
|
140
|
+
set :build_to, "./builds"
|
141
|
+
# set :package_under, 'dir'
|
142
|
+
|
143
|
+
# You may use helpers here
|
144
|
+
# set :repository, '...'
|
145
|
+
# use :git, exclude_git_clean_targets: true
|
146
|
+
|
147
|
+
# Procedure for build
|
148
|
+
build 'write built at' do
|
149
|
+
# build something...
|
150
|
+
File.write('built_at', "#{Time.now}\n")
|
151
|
+
end
|
152
|
+
|
153
|
+
# Step `prepare` on agents,
|
154
|
+
prepare 'write prepared_at' do
|
155
|
+
File.write release_path.join('prepared_at'), Time.now
|
156
|
+
end
|
157
|
+
|
158
|
+
# You can declare multiples. Run by order defined.
|
159
|
+
prepare 'bundle stuff' do
|
160
|
+
run 'bundle', 'install'
|
161
|
+
end
|
162
|
+
|
163
|
+
# Step `release` run when Release is required. Usually for restarting app process, etc.
|
164
|
+
# Also these step declaration accepts labels for `only` and `except` key to limit agents to run on.
|
165
|
+
# (Labels can be set by agent's configuration)
|
166
|
+
release 'reload unicorn', only [:app] do
|
167
|
+
run 'pkill', '-HUP', '-f', 'unicorn'
|
168
|
+
end
|
169
|
+
```
|
170
|
+
|
171
|
+
## Build your first package and push it
|
172
|
+
|
173
|
+
Have all agents and master node run? Okay, let's build your first package!
|
174
|
+
|
175
|
+
```
|
176
|
+
$ mamiya build -S ./deploy.rb
|
177
|
+
11/18 09:37:01 INFO [Build] Running script.before_build
|
178
|
+
11/18 09:37:01 INFO [Build] Running script.prepare_build
|
179
|
+
11/18 09:37:01 INFO [Build] Running script.build
|
180
|
+
11/18 09:37:01 INFO [Build] Copying script files
|
181
|
+
11/18 09:37:01 INFO [Build] Packed.
|
182
|
+
11/18 09:37:01 INFO [Build] Running script.after_build
|
183
|
+
11/18 09:37:01 INFO [Build] DONE: 20141118093701-myapp built at .../builds/20141118093701-myapp.tar.gz
|
184
|
+
```
|
185
|
+
|
186
|
+
(`-S`,` --script` specifies where the script is. More options available; see `mamiya help build`)
|
187
|
+
|
188
|
+
Great! You can unpack using `tar xf` to confirm what has packed, if you want.
|
189
|
+
|
190
|
+
You have to push it onto storage to make available for agents.
|
191
|
+
|
192
|
+
```
|
193
|
+
$ mamiya push -C ./config.rb
|
194
|
+
11/18 09:42:43 INFO [Push] Pushing builds/20141118093701-myapp.tar.gz to storage(app=myapp)...
|
195
|
+
11/18 09:42:43 INFO [Push] DONE!
|
196
|
+
```
|
197
|
+
|
198
|
+
(`-C`, `--config` specifies where configuration file is... to find `:storage` configuration.)
|
199
|
+
|
200
|
+
## Deploy it
|
201
|
+
|
202
|
+
`mamiya client deploy <PACKAGE>` prepares the package then release it after all nodes get ready.
|
203
|
+
|
204
|
+
```
|
205
|
+
$ export MAMIYA_APP=myapp
|
206
|
+
$ mamiya client list-packages
|
207
|
+
20141118093701-myapp
|
208
|
+
$ mamiya client deploy 20141118093701-myapp
|
209
|
+
```
|
210
|
+
|
211
|
+
(You can use `-a`, `--application` option instead of `$MAMIYA_APP`)
|
212
|
+
|
data/lib/mamiya/cli/client.rb
CHANGED
@@ -295,19 +295,17 @@ not distributed: #{dist['not_distributed_count']} agents
|
|
295
295
|
|
296
296
|
if type == :deploy
|
297
297
|
do_prep = -> do
|
298
|
-
puts "
|
298
|
+
puts " * sending prepare request"
|
299
299
|
prepare(package)
|
300
300
|
end
|
301
301
|
|
302
|
-
|
303
|
-
|
304
|
-
puts " * Wait until prepared"
|
302
|
+
puts "=> Wait agents to have prepared"
|
305
303
|
puts ""
|
306
304
|
|
307
305
|
i = 0
|
308
306
|
loop do
|
309
307
|
i += 1
|
310
|
-
do_prep[] if i % 25 == 0
|
308
|
+
do_prep[] if i == 2 || i % 25 == 0
|
311
309
|
|
312
310
|
s = pkg_status(package, :short)
|
313
311
|
puts ""
|
data/lib/mamiya/storages/s3.rb
CHANGED
@@ -6,6 +6,18 @@ require 'json'
|
|
6
6
|
module Mamiya
|
7
7
|
module Storages
|
8
8
|
class S3 < Mamiya::Storages::Abstract
|
9
|
+
class MultipleObjectsDeletionError < StandardError
|
10
|
+
attr_accessor :errors
|
11
|
+
|
12
|
+
def initialize(errors)
|
13
|
+
message = errors.map do |error|
|
14
|
+
"#{error.code}: #{error.message} (key=#{error.key})"
|
15
|
+
end.join(', ')
|
16
|
+
super(message)
|
17
|
+
@errors = errors
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
9
21
|
def self.find(config={})
|
10
22
|
s3 = initiate_s3_with_config(config)
|
11
23
|
Hash[s3.list_objects(bucket: config[:bucket], delimiter: '/').common_prefixes.map { |prefix|
|
@@ -96,7 +108,10 @@ module Mamiya
|
|
96
108
|
}.compact
|
97
109
|
raise NotFound if objs_to_delete.empty?
|
98
110
|
|
99
|
-
s3.delete_objects(bucket: @config[:bucket], delete: {objects: objs_to_delete})
|
111
|
+
result = s3.delete_objects(bucket: @config[:bucket], delete: {objects: objs_to_delete})
|
112
|
+
unless result.errors.empty?
|
113
|
+
raise MultipleObjectsDeletionError.new(result.errors)
|
114
|
+
end
|
100
115
|
end
|
101
116
|
|
102
117
|
def self.initiate_s3_with_config(config) # :nodoc:
|
data/lib/mamiya/version.rb
CHANGED
data/spec/storages/s3_spec.rb
CHANGED
@@ -250,6 +250,7 @@ describe Mamiya::Storages::S3 do
|
|
250
250
|
|
251
251
|
describe "#remove(package_name)" do
|
252
252
|
let(:package_name) { 'test' }
|
253
|
+
let(:s3_delete_response) { double('response for POST /?delete', errors: []) }
|
253
254
|
subject(:remove) { storage.remove(package_name) }
|
254
255
|
|
255
256
|
before do
|
@@ -257,7 +258,7 @@ describe Mamiya::Storages::S3 do
|
|
257
258
|
end
|
258
259
|
|
259
260
|
it "removes specified package from S3" do
|
260
|
-
expect(s3).to receive(:delete_objects).with(bucket: 'testbucket', delete: {objects: [{key: 'myapp/test.tar.gz'}, {key: 'myapp/test.json'}]})
|
261
|
+
expect(s3).to receive(:delete_objects).with(bucket: 'testbucket', delete: {objects: [{key: 'myapp/test.tar.gz'}, {key: 'myapp/test.json'}]}).and_return(s3_delete_response)
|
261
262
|
remove
|
262
263
|
end
|
263
264
|
|
@@ -265,7 +266,7 @@ describe Mamiya::Storages::S3 do
|
|
265
266
|
let(:package_name) { 'test.tar.gz' }
|
266
267
|
|
267
268
|
it "removes specified package from S3" do
|
268
|
-
expect(s3).to receive(:delete_objects).with(bucket: 'testbucket', delete: {objects: [{key: 'myapp/test.tar.gz'}, {key: 'myapp/test.json'}]})
|
269
|
+
expect(s3).to receive(:delete_objects).with(bucket: 'testbucket', delete: {objects: [{key: 'myapp/test.tar.gz'}, {key: 'myapp/test.json'}]}).and_return(s3_delete_response)
|
269
270
|
remove
|
270
271
|
end
|
271
272
|
end
|
@@ -274,7 +275,7 @@ describe Mamiya::Storages::S3 do
|
|
274
275
|
let(:package_name) { 'test.json' }
|
275
276
|
|
276
277
|
it "removes specified package from S3" do
|
277
|
-
expect(s3).to receive(:delete_objects).with(bucket: 'testbucket', delete: {objects: [{key: 'myapp/test.tar.gz'}, {key: 'myapp/test.json'}]})
|
278
|
+
expect(s3).to receive(:delete_objects).with(bucket: 'testbucket', delete: {objects: [{key: 'myapp/test.tar.gz'}, {key: 'myapp/test.json'}]}).and_return(s3_delete_response)
|
278
279
|
remove
|
279
280
|
end
|
280
281
|
end
|
@@ -288,6 +289,21 @@ describe Mamiya::Storages::S3 do
|
|
288
289
|
expect { storage.remove('test') }.to raise_error(Mamiya::Storages::Abstract::NotFound)
|
289
290
|
end
|
290
291
|
end
|
292
|
+
|
293
|
+
context "when delete_objects fails" do
|
294
|
+
let(:errors) do
|
295
|
+
[
|
296
|
+
double('Aws::S3::Errors::InteranlError', code: 'InteranlError', message: 'Internal Error', key: 'myapp/test.tar.gz'),
|
297
|
+
double('Aws::S3::Errors::AccessDenied', code: 'AccessDenied', message: 'Access Denied', key: 'myapp/test.json'),
|
298
|
+
]
|
299
|
+
end
|
300
|
+
let(:s3_delete_response) { double('response for POST /?delete', errors: errors) }
|
301
|
+
|
302
|
+
it "raises error" do
|
303
|
+
expect(s3).to receive(:delete_objects).with(bucket: 'testbucket', delete: {objects: [{key: 'myapp/test.tar.gz'}, {key: 'myapp/test.json'}]}).and_return(s3_delete_response)
|
304
|
+
expect { remove }.to raise_error(Mamiya::Storages::S3::MultipleObjectsDeletionError, /Access Denied/)
|
305
|
+
end
|
306
|
+
end
|
291
307
|
end
|
292
308
|
|
293
309
|
describe ".find" do
|
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.2.
|
4
|
+
version: 0.2.2
|
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-10
|
11
|
+
date: 2014-12-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|
@@ -183,6 +183,7 @@ files:
|
|
183
183
|
- docs/internal/serf_events.md
|
184
184
|
- docs/internal/serf_queries.md
|
185
185
|
- docs/internal/tasks.md
|
186
|
+
- docs/quick_start.md
|
186
187
|
- docs/upgrading.md
|
187
188
|
- example/.gitignore
|
188
189
|
- example/Procfile
|
@@ -297,7 +298,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
297
298
|
version: '0'
|
298
299
|
requirements: []
|
299
300
|
rubyforge_project:
|
300
|
-
rubygems_version: 2.
|
301
|
+
rubygems_version: 2.4.1
|
301
302
|
signing_key:
|
302
303
|
specification_version: 4
|
303
304
|
summary: Fast deploy tool using tarballs and serf
|