capistrano-container 0.0.5 → 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +27 -24
- data/capistrano-container.gemspec +2 -2
- data/lib/capistrano/container.rb +4 -9
- data/lib/capistrano/container/instance.rb +57 -52
- data/lib/capistrano/container/manager.rb +41 -36
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b9b6ae24727c2feb732526e24c24c3424e419cbc
|
4
|
+
data.tar.gz: 752f1343ceb509c3afc74df3a44d2c38be3987ca
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f530de0e25adcb551771e64281aacbe2faa01f289a68128bff94f27829dce434feefffcc59d0db866b1f4ef73ae6cf9b536df342d522cdfc34d954189c9802dc
|
7
|
+
data.tar.gz: ba74dde5e0ee280aced46d21f891994cd24e7f5e56fb4c1243df717a0ccabaff8ebd6cdb3c72dd1c87eda43d375c9492755cf0e242fbf9d45fa32ecec48292f1
|
data/README.md
CHANGED
@@ -2,15 +2,15 @@
|
|
2
2
|
|
3
3
|
Helps managing [docker](https://www.docker.com/) container and files inside docker container for Capistrano 3.x.
|
4
4
|
|
5
|
-
This project is in an early stage but helps me
|
5
|
+
This project is in an early stage but helps me a lot dealing with my container deployments and keeps my code clean. It is not only meant for docker, but at the moment there is only support for docker, feel free to contribute =)
|
6
6
|
|
7
|
-
This gem does not handle Dockerfiles
|
7
|
+
This gem does not handle Dockerfiles (build, push, etc.) but handles docker container on your dev or staging system.
|
8
8
|
|
9
|
-
|
9
|
+
The container implementation auto detects if it should run on local or remote docker-engine (see below).
|
10
10
|
|
11
11
|
## Installation
|
12
12
|
|
13
|
-
Add this lines to your application's Gemfile
|
13
|
+
Add this lines to your application's `Gemfile`:
|
14
14
|
|
15
15
|
```ruby
|
16
16
|
gem 'capistrano', '>= 3.0.0'
|
@@ -25,7 +25,7 @@ Or install it yourself as:
|
|
25
25
|
|
26
26
|
$ gem install capistrano-container
|
27
27
|
|
28
|
-
Dont forget to require the module in your Capfile
|
28
|
+
Dont forget to require the module in your `Capfile`:
|
29
29
|
|
30
30
|
```ruby
|
31
31
|
require 'capistrano/container'
|
@@ -33,12 +33,12 @@ require 'capistrano/container'
|
|
33
33
|
|
34
34
|
## Usage
|
35
35
|
### definition
|
36
|
-
|
36
|
+
Define and register a container by doing the following in your `deploy.rb` (or `[stage].rb`):
|
37
37
|
|
38
38
|
```ruby
|
39
39
|
...
|
40
40
|
|
41
|
-
server
|
41
|
+
server 'www.example.com', user: 'root', roles: %w{web}
|
42
42
|
|
43
43
|
container 'db', roles: %w{db},
|
44
44
|
container_id: 'website_company_beta_db',
|
@@ -51,15 +51,15 @@ container 'php', roles: %w{php},
|
|
51
51
|
...
|
52
52
|
```
|
53
53
|
|
54
|
-
This registers two container (db, php) for the server www.example.com.
|
54
|
+
This registers two container (db, php) for the server www.example.com. You can use the container roles later to filter container like the way you filter server in capistrano (`on([:role]) do ...` expresion).
|
55
55
|
|
56
|
-
The container id is optional. If not set, the container id
|
56
|
+
The container id is optional. If its not set, the container id equals to the name you gave the container as first argument. The container id will be used later to run commands like `container.upload` or `container.execute` (with `docker exec [container_id] [command]`).
|
57
57
|
|
58
|
-
If you define a container, the role `:container_host` will be added to the given hosts, so you can filter hosts that are running container. Also a container specific role will be added
|
58
|
+
If you define a container, the role `:container_host` will be added to the given hosts, so you can filter hosts that are running that specific container. Also a container specific role will be added. For a container like `container 'php', roles: %w{php}, ...` the host get a role named `:container_php`.
|
59
59
|
|
60
60
|
|
61
61
|
### commandline tasks
|
62
|
-
There are
|
62
|
+
There are generic container tasks you can run on local or remote host (you will be asked for `container_id` sometimes).
|
63
63
|
|
64
64
|
```ruby
|
65
65
|
cap container:all # show all docker containers
|
@@ -79,7 +79,7 @@ cap container:unpause # unpause a docker container
|
|
79
79
|
cap container:update_docker # update docker
|
80
80
|
```
|
81
81
|
|
82
|
-
|
82
|
+
Also individual tasks will be created for every container you define in your `deploy.rb`:
|
83
83
|
|
84
84
|
```ruby
|
85
85
|
cap container:php:delete # delete a docker container
|
@@ -97,12 +97,12 @@ cap container:php:unpause # unpause a docker container
|
|
97
97
|
```
|
98
98
|
|
99
99
|
### ruby tasks
|
100
|
-
You can
|
100
|
+
You can run the pre defined tasks on your container like these:
|
101
101
|
|
102
102
|
```ruby
|
103
103
|
after :deploy, :updated do
|
104
|
-
on roles :web do
|
105
|
-
# do your application restarts
|
104
|
+
on roles :web do |host|
|
105
|
+
# do your plain old host application restarts
|
106
106
|
end
|
107
107
|
|
108
108
|
on_container_roles :php do |container, host|
|
@@ -110,18 +110,18 @@ after :deploy, :updated do
|
|
110
110
|
end
|
111
111
|
end
|
112
112
|
```
|
113
|
-
This filters container
|
113
|
+
This snipped filters container by the role `:php` and invokes the task `container:#{container.name}:restart`.
|
114
114
|
|
115
|
-
|
115
|
+
Available container accessors:
|
116
116
|
```ruby
|
117
117
|
container = container_by_name :db
|
118
118
|
container = container_by_roles :php
|
119
119
|
container = container_by_id 'website_company_beta_db'
|
120
120
|
```
|
121
121
|
|
122
|
-
Note that you have to use
|
122
|
+
Note that you have to use these commands inside a SSHKit context, means inside a `on roles :container_host do` block for example.
|
123
123
|
|
124
|
-
A container
|
124
|
+
A container provides the following methods:
|
125
125
|
```ruby
|
126
126
|
# tests if the container has a specific role
|
127
127
|
def has_role?(role)
|
@@ -132,13 +132,13 @@ A container has the following methods:
|
|
132
132
|
# the container specific role, for a container named php `:container_php`
|
133
133
|
def container_role
|
134
134
|
|
135
|
-
# uploads a local file to
|
135
|
+
# uploads a local file to local or remote running container (with docker cp)
|
136
136
|
def upload!(src, target)
|
137
137
|
|
138
|
-
#
|
138
|
+
# downloads a local or remote container file to your local host
|
139
139
|
def download!(src, target)
|
140
140
|
|
141
|
-
# executes a command on the docker container
|
141
|
+
# executes a command on the local or remote docker container(with docker exec)
|
142
142
|
def execute(command)
|
143
143
|
|
144
144
|
# invokes a container specific task
|
@@ -146,13 +146,16 @@ A container has the following methods:
|
|
146
146
|
```
|
147
147
|
|
148
148
|
### local stage detection
|
149
|
-
Local stage per default is named
|
149
|
+
Local stage per default is named `:local`. If you wish to change insert `set :local_stage_name, :my_local` in your `deploy.rb`.
|
150
150
|
|
151
151
|
## TODO
|
152
|
-
*
|
152
|
+
* integration tests(travis).
|
153
153
|
* Implement adapter pattern for other container manager.
|
154
154
|
|
155
155
|
## Changes
|
156
|
+
### Version 0.0.6
|
157
|
+
* use clean module namespaces
|
158
|
+
|
156
159
|
### Version 0.0.5
|
157
160
|
* container now auto detect if they should execute, download and upload on local or remote host.
|
158
161
|
|
@@ -4,8 +4,8 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
4
|
|
5
5
|
Gem::Specification.new do |spec|
|
6
6
|
spec.name = 'capistrano-container'
|
7
|
-
spec.version = '0.0.
|
8
|
-
spec.date = '
|
7
|
+
spec.version = '0.0.6'
|
8
|
+
spec.date = '2018-02-03'
|
9
9
|
spec.summary = 'Helps managing docker container and files inside docker container for Capistrano 3.x'
|
10
10
|
spec.description = spec.summary
|
11
11
|
spec.authors = ['Tom Hanoldt']
|
data/lib/capistrano/container.rb
CHANGED
@@ -1,14 +1,9 @@
|
|
1
1
|
require_relative 'tasks/container.rb'
|
2
|
+
require_relative 'container/instance.rb'
|
3
|
+
require_relative 'container/manager.rb'
|
4
|
+
require_relative 'container/mixins.rb'
|
2
5
|
|
3
|
-
|
4
|
-
module Container
|
5
|
-
require_relative 'container/instance.rb'
|
6
|
-
require_relative 'container/manager.rb'
|
7
|
-
require_relative 'container/mixins.rb'
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
$container_manager = Manager.new
|
6
|
+
$container_manager = Capistrano::Container::Manager.new
|
12
7
|
|
13
8
|
module Capistrano
|
14
9
|
module DSL
|
@@ -1,77 +1,82 @@
|
|
1
1
|
require 'securerandom'
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
@dsl = nil
|
10
|
-
@name = name
|
11
|
-
@config = {shared_on_host: '/tmp'}.merge(config)
|
12
|
-
end
|
3
|
+
module Capistrano
|
4
|
+
module Container
|
5
|
+
class Instance
|
6
|
+
attr_reader :name
|
7
|
+
attr_reader :config
|
8
|
+
attr_writer :dsl
|
13
9
|
|
14
|
-
|
15
|
-
|
10
|
+
def initialize(name, config)
|
11
|
+
@dsl = nil
|
12
|
+
@name = name
|
13
|
+
@config = {shared_on_host: '/tmp'}.merge(config)
|
14
|
+
end
|
16
15
|
|
17
|
-
|
16
|
+
def has_role?(role)
|
17
|
+
return false unless @config.key? :roles
|
18
18
|
|
19
|
-
|
20
|
-
end
|
19
|
+
role = role.to_s if role.is_a? Symbol
|
21
20
|
|
22
|
-
|
23
|
-
|
21
|
+
@config[:roles].include? role
|
22
|
+
end
|
24
23
|
|
25
|
-
|
26
|
-
|
24
|
+
def container_id
|
25
|
+
return @name unless @config.key? :container_id
|
27
26
|
|
28
|
-
|
29
|
-
|
30
|
-
end
|
27
|
+
@config[:container_id]
|
28
|
+
end
|
31
29
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
return
|
36
|
-
end
|
30
|
+
def container_role
|
31
|
+
"container_#{@name}".to_sym
|
32
|
+
end
|
37
33
|
|
38
|
-
|
34
|
+
def upload!(src, target)
|
35
|
+
if @dsl.local_stage?
|
36
|
+
self.cp(src, "#{container_id}:#{target}")
|
37
|
+
return
|
38
|
+
end
|
39
39
|
|
40
|
-
|
40
|
+
tmp = "#{@config[:shared_on_host]}/capistrano-docker.#{SecureRandom.uuid}.tmp"
|
41
41
|
|
42
|
-
|
42
|
+
@dsl.upload!(src, tmp)
|
43
43
|
|
44
|
-
|
45
|
-
end
|
44
|
+
self.cp(tmp, "#{container_id}:#{target}")
|
46
45
|
|
47
|
-
|
48
|
-
|
49
|
-
self.cp("#{container_id}:#{src}", target)
|
50
|
-
return
|
51
|
-
end
|
46
|
+
@dsl.execute("rm -rf #{tmp}")
|
47
|
+
end
|
52
48
|
|
53
|
-
|
49
|
+
def download!(src, target)
|
50
|
+
if @dsl.local_stage?
|
51
|
+
self.cp("#{container_id}:#{src}", target)
|
52
|
+
return
|
53
|
+
end
|
54
54
|
|
55
|
-
|
55
|
+
tmp = "#{@config[:shared_on_host]}/capistrano-docker.#{SecureRandom.uuid}.tmp"
|
56
56
|
|
57
|
-
|
57
|
+
self.cp("#{container_id}:#{src}", tmp)
|
58
58
|
|
59
|
-
|
60
|
-
end
|
59
|
+
@dsl.download!(tmp, target)
|
61
60
|
|
62
|
-
|
63
|
-
|
61
|
+
@dsl.execute("rm -rf #{tmp}")
|
62
|
+
end
|
64
63
|
|
65
|
-
|
66
|
-
|
64
|
+
def execute(command)
|
65
|
+
command = "docker exec -i #{container_id} sh -c '#{command.gsub("'", "\'")}'"
|
67
66
|
|
68
|
-
|
69
|
-
|
67
|
+
@dsl.execute_local_or_remote(command)
|
68
|
+
end
|
70
69
|
|
71
|
-
|
72
|
-
|
70
|
+
def cp(src, target)
|
71
|
+
command = "docker cp #{src} #{target}"
|
72
|
+
|
73
|
+
@dsl.execute_local_or_remote(command)
|
74
|
+
end
|
75
|
+
|
76
|
+
def invoke(task_name)
|
77
|
+
@dsl.invoke "container:#{@name}:#{task_name}"
|
78
|
+
end
|
79
|
+
end
|
73
80
|
|
74
|
-
def invoke(task_name)
|
75
|
-
@dsl.invoke "container:#{@name}:#{task_name}"
|
76
81
|
end
|
77
82
|
end
|
@@ -1,55 +1,60 @@
|
|
1
1
|
require 'rake/dsl_definition'
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
module Capistrano
|
4
|
+
module Container
|
5
|
+
class Manager
|
6
|
+
include Rake::DSL
|
5
7
|
|
6
|
-
|
7
|
-
|
8
|
-
|
8
|
+
def initialize()
|
9
|
+
@container = {}
|
10
|
+
end
|
9
11
|
|
10
|
-
|
11
|
-
|
12
|
+
def add(name, config)
|
13
|
+
@container[name.to_sym] = container = Instance.new(name, config)
|
12
14
|
|
13
|
-
|
15
|
+
config[:server].map!{ |ip| server(ip) }
|
14
16
|
|
15
|
-
|
16
|
-
|
17
|
-
|
17
|
+
config[:server].each do |server|
|
18
|
+
server.add_roles [:container_host, container.container_role]
|
19
|
+
end
|
18
20
|
|
19
|
-
|
21
|
+
self.create_container_tasks(container)
|
20
22
|
|
21
|
-
|
22
|
-
|
23
|
+
container
|
24
|
+
end
|
23
25
|
|
24
|
-
|
25
|
-
|
26
|
-
|
26
|
+
def by_name(name)
|
27
|
+
@container[name.to_sym]
|
28
|
+
end
|
27
29
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
30
|
+
def by_id(id)
|
31
|
+
@container.each do |name, instance|
|
32
|
+
return instance if instance.container_id == id
|
33
|
+
end
|
34
|
+
end
|
33
35
|
|
34
|
-
|
35
|
-
|
36
|
+
def by_roles(roles)
|
37
|
+
roles = Array(roles)
|
36
38
|
|
37
|
-
|
39
|
+
return @container.values if roles.include? :all
|
38
40
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
41
|
+
tmp = {}
|
42
|
+
roles.each do |role|
|
43
|
+
@container.each do |name, instance|
|
44
|
+
tmp[name] = instance if instance.has_role? role
|
45
|
+
end
|
46
|
+
end
|
47
|
+
tmp.values
|
43
48
|
end
|
44
|
-
end
|
45
|
-
tmp.values
|
46
|
-
end
|
47
49
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
50
|
+
def create_container_tasks(container)
|
51
|
+
namespace :container do
|
52
|
+
namespace container.name do
|
53
|
+
Mixins.define_tasks(container)
|
54
|
+
end
|
55
|
+
end
|
52
56
|
end
|
53
57
|
end
|
58
|
+
|
54
59
|
end
|
55
60
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: capistrano-container
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tom Hanoldt
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-02-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: capistrano
|
@@ -92,7 +92,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
92
92
|
version: '0'
|
93
93
|
requirements: []
|
94
94
|
rubyforge_project:
|
95
|
-
rubygems_version: 2.
|
95
|
+
rubygems_version: 2.6.14
|
96
96
|
signing_key:
|
97
97
|
specification_version: 4
|
98
98
|
summary: Helps managing docker container and files inside docker container for Capistrano
|