dkcomposer 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE.txt +21 -0
- data/README.md +39 -0
- data/lib/dkcomposer/config.rb +14 -0
- data/lib/dkcomposer/dockercompose.rb +108 -0
- data/lib/dkcomposer/dockerfile.rb +16 -0
- data/lib/dkcomposer/ext.rb +52 -0
- data/lib/dkcomposer/helper.rb +43 -0
- data/lib/dkcomposer/image.rb +127 -0
- data/lib/dkcomposer/network.rb +52 -0
- data/lib/dkcomposer/service.rb +82 -0
- data/lib/dkcomposer/stack.rb +131 -0
- data/lib/dkcomposer/version.rb +3 -0
- data/lib/dkcomposer/volume.rb +53 -0
- data/lib/dkcomposer.rb +19 -0
- metadata +86 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: b9bd97a7ebf76383b93245586590b73dbc743d7f
|
4
|
+
data.tar.gz: 654dc986487f79bdb10bbc66cd70ea6becefa75e
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ac4b66b47b6f6f91375b37b8cbfef5a7f3ab606336cba249e05b98d657421d3c5c0dc500eaf4aa0d38ab0697bcb5829c20c3bf34c0544ddabb612c3b43395108
|
7
|
+
data.tar.gz: 81e634e67ccf4de31ea1882ed5326d93f562357da2b5f6ade7320d4cb6c1c9bd15d9356f0fea42bd74406326aa25eaa22e215725216d823518620772ab7823b8
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2017 shaoyang
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
# Dkcomposer
|
2
|
+
|
3
|
+
Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/dkcomposer`. To experiment with that code, run `bin/console` for an interactive prompt.
|
4
|
+
|
5
|
+
TODO: Delete this and the text above, and describe your gem
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
gem 'dkcomposer'
|
13
|
+
```
|
14
|
+
|
15
|
+
And then execute:
|
16
|
+
|
17
|
+
$ bundle
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
|
21
|
+
$ gem install dkcomposer
|
22
|
+
|
23
|
+
## Usage
|
24
|
+
|
25
|
+
TODO: Write usage instructions here
|
26
|
+
|
27
|
+
## Development
|
28
|
+
|
29
|
+
After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
30
|
+
|
31
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
32
|
+
|
33
|
+
## Contributing
|
34
|
+
|
35
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/shao4phone@gmail.com/dkcomposer.
|
36
|
+
|
37
|
+
## License
|
38
|
+
|
39
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module DkComposer
|
2
|
+
CONFIG = {
|
3
|
+
image: {},
|
4
|
+
service: {},
|
5
|
+
stack: {},
|
6
|
+
volume: {},
|
7
|
+
network: {}
|
8
|
+
}.freeze
|
9
|
+
IMAGE = CONFIG[:image]
|
10
|
+
SERVICE = CONFIG[:service]
|
11
|
+
STACK = CONFIG[:stack]
|
12
|
+
VOLUME = CONFIG[:volume]
|
13
|
+
NETWORK = CONFIG[:network]
|
14
|
+
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
module DkComposer
|
2
|
+
module Composefile
|
3
|
+
module Service
|
4
|
+
KEYWORDS = {
|
5
|
+
image: :string,
|
6
|
+
environment: :hash,
|
7
|
+
ports: :array,
|
8
|
+
links: :array,
|
9
|
+
depends_on: :array,
|
10
|
+
healthcheck: :hash,
|
11
|
+
command: :string,
|
12
|
+
extra_hosts: :array,
|
13
|
+
volumes: :array,
|
14
|
+
networks: :array,
|
15
|
+
version: :string,
|
16
|
+
stdin_open: :string,
|
17
|
+
privileged: :string,
|
18
|
+
hostname: :string,
|
19
|
+
domainname: :string,
|
20
|
+
container_name: :string,
|
21
|
+
cap_add: :array,
|
22
|
+
tty: :string
|
23
|
+
}.freeze
|
24
|
+
def method_missing(method, *params, **opts, &block)
|
25
|
+
if KEYWORDS.key?(method)
|
26
|
+
@fields ||= {}
|
27
|
+
case KEYWORDS[method]
|
28
|
+
when :array
|
29
|
+
@fields[method] = params.flatten
|
30
|
+
when :hash
|
31
|
+
@fields[method] = if params.empty?
|
32
|
+
opts.stringfy_bool_value
|
33
|
+
else
|
34
|
+
params.map { |x| x.split('=') }.to_h.stringfy_bool_value
|
35
|
+
end
|
36
|
+
else
|
37
|
+
v, = params
|
38
|
+
@fields[method] = v
|
39
|
+
end
|
40
|
+
else
|
41
|
+
super
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
module Volume
|
47
|
+
KEYWORDS = {
|
48
|
+
driver: :string,
|
49
|
+
driver_opts: :hash,
|
50
|
+
external: :string,
|
51
|
+
lables: :hash
|
52
|
+
}.freeze
|
53
|
+
def method_missing(method, *params, **opts, &block)
|
54
|
+
if KEYWORDS.key?(method)
|
55
|
+
@fields ||= {}
|
56
|
+
case KEYWORDS[method]
|
57
|
+
when :array
|
58
|
+
@fields[method] = params
|
59
|
+
when :hash
|
60
|
+
@fields[method] = if params.empty?
|
61
|
+
opts.stringfy_bool_value
|
62
|
+
else
|
63
|
+
params.map { |x| x.split('=') }.to_h.stringfy_bool_value
|
64
|
+
end
|
65
|
+
else
|
66
|
+
v, = params
|
67
|
+
@fields[method] = v
|
68
|
+
end
|
69
|
+
else
|
70
|
+
super
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
module Network
|
76
|
+
KEYWORDS = {
|
77
|
+
driver: :string,
|
78
|
+
driver_opts: :hash,
|
79
|
+
attachable: :string,
|
80
|
+
enable_ipv6: :string,
|
81
|
+
ipam: :hash,
|
82
|
+
internal: :string,
|
83
|
+
external: :hash,
|
84
|
+
lables: :hash
|
85
|
+
}.freeze
|
86
|
+
def method_missing(method, *params, **opts, &block)
|
87
|
+
if KEYWORDS.key?(method)
|
88
|
+
@fields ||= {}
|
89
|
+
case KEYWORDS[method]
|
90
|
+
when :array
|
91
|
+
@fields[method] = params
|
92
|
+
when :hash
|
93
|
+
@fields[method] = if params.empty?
|
94
|
+
opts.stringfy_bool_value
|
95
|
+
else
|
96
|
+
params.map { |x| x.split('=') }.to_h.stringfy_bool_value
|
97
|
+
end
|
98
|
+
else
|
99
|
+
v, = params
|
100
|
+
@fields[method] = v
|
101
|
+
end
|
102
|
+
else
|
103
|
+
super
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module DkComposer
|
2
|
+
module Dockerfile
|
3
|
+
KEYWORDS = %i[from run cmd label maintainer
|
4
|
+
expose env add copy entrypoint
|
5
|
+
volume user arg onbuild workdir
|
6
|
+
stopsignal healthcheck shell].freeze
|
7
|
+
def method_missing(method, *params, &block)
|
8
|
+
if KEYWORDS.include?(method)
|
9
|
+
@actions ||= []
|
10
|
+
@actions << [method, *params]
|
11
|
+
else
|
12
|
+
super
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
class Hash
|
2
|
+
def stringfy_key
|
3
|
+
ret = collect do |k, v|
|
4
|
+
key = k.to_s
|
5
|
+
value = v.is_a?(Hash) ? v.stringfy_key : v
|
6
|
+
[key, value]
|
7
|
+
end
|
8
|
+
Hash[ret]
|
9
|
+
end
|
10
|
+
|
11
|
+
def symbolize_key
|
12
|
+
ret = collect do |k, v|
|
13
|
+
key = k.to_sym
|
14
|
+
value = v.is_a?(Hash) ? v.symbolize_key : v
|
15
|
+
[key, value]
|
16
|
+
end
|
17
|
+
Hash[ret]
|
18
|
+
end
|
19
|
+
|
20
|
+
def stringfy_bool_value
|
21
|
+
each_with_object({}) do |(k, v), r|
|
22
|
+
next r[k] = v.stringfy_bool_value if v.is_a?(Hash)
|
23
|
+
next r[k] = v.to_s if v == true || v == false
|
24
|
+
r[k] = v
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def to_flatten_s
|
29
|
+
to_a.map do |k, v|
|
30
|
+
value = v
|
31
|
+
value = "\"#{v}\"" if value.is_a?(String)
|
32
|
+
value = v.to_flatten_s if value.is_a?(Hash)
|
33
|
+
"#{k}:#{value}"
|
34
|
+
end.join(',')
|
35
|
+
end
|
36
|
+
end
|
37
|
+
class Symbol
|
38
|
+
def to_colon_s
|
39
|
+
":#{self}"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
class String
|
44
|
+
def to_quote_s
|
45
|
+
%("#{self}")
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def desc(short, long)
|
50
|
+
@desc ||= []
|
51
|
+
@desc << [short, long]
|
52
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module DkComposer
|
2
|
+
module Helper
|
3
|
+
attr_accessor :build_path, :shortdesc, :longdesc
|
4
|
+
def config(**opts)
|
5
|
+
opts.each do |(key, value)|
|
6
|
+
if value.is_a?(Array)
|
7
|
+
send(key, *value)
|
8
|
+
else
|
9
|
+
send(key, value)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def shortdesc
|
15
|
+
@shortdesc ||= @name
|
16
|
+
end
|
17
|
+
|
18
|
+
def longdesc
|
19
|
+
@longdesc ||= @name
|
20
|
+
end
|
21
|
+
|
22
|
+
def deep_clone
|
23
|
+
Marshal.load(Marshal.dump(self))
|
24
|
+
end
|
25
|
+
|
26
|
+
def build_path(path = nil)
|
27
|
+
path ? @build_path = path : (@build_path ||= '.')
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def tempfile(content, *opts)
|
33
|
+
tempfile = Tempfile.new(*opts)
|
34
|
+
tempfile.write(content)
|
35
|
+
tempfile.rewind
|
36
|
+
tempfile.path.split('/').last
|
37
|
+
end
|
38
|
+
|
39
|
+
def run_command(command)
|
40
|
+
system(command)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,127 @@
|
|
1
|
+
module DkComposer
|
2
|
+
class Image
|
3
|
+
include Dockerfile
|
4
|
+
include Helper
|
5
|
+
attr_accessor :from, :actions, :name, :repos, :tag
|
6
|
+
def initialize(name)
|
7
|
+
@name = name
|
8
|
+
@actions = []
|
9
|
+
@repos = []
|
10
|
+
@tag = 'latest'
|
11
|
+
end
|
12
|
+
|
13
|
+
def from(param = nil)
|
14
|
+
return @from unless param
|
15
|
+
@from = if param.is_a? Symbol
|
16
|
+
puts "WARNING: There is no image definition named: :#{param}! Pls require the def file " unless IMAGE.key?(param)
|
17
|
+
IMAGE[param].repo
|
18
|
+
else
|
19
|
+
param
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def repo
|
24
|
+
repos.first
|
25
|
+
end
|
26
|
+
|
27
|
+
def repos(*values)
|
28
|
+
if values.empty?
|
29
|
+
return ["#{name}:#{tag || 'latest'}"] if @repos.empty?
|
30
|
+
@repos
|
31
|
+
else
|
32
|
+
@repos.concat values
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def tag(values = nil)
|
37
|
+
if values
|
38
|
+
@tag = values
|
39
|
+
|
40
|
+
else
|
41
|
+
@tag || 'latest'
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def use(*params)
|
46
|
+
return @use if params.empty?
|
47
|
+
@use = params
|
48
|
+
params.each do |image_name|
|
49
|
+
puts "WARNING: There is no image definition named: :#{image_name}! Pls require the def file " unless IMAGE.key?(image_name)
|
50
|
+
|
51
|
+
@actions << ['', "#>>>>>>>>>>>>>#{image_name} begin<<<<<<<<<<<<<<<<<<<"]
|
52
|
+
@actions.concat IMAGE[image_name].actions
|
53
|
+
@actions << ['', "#>>>>>>>>>>>>>#{image_name} end<<<<<<<<<<<<<<<<<<<<<"]
|
54
|
+
@actions << ['', ' ']
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def pull
|
59
|
+
repos.each do |repo|
|
60
|
+
pull_cmd = "docker pull #{repo}"
|
61
|
+
run_command(pull_cmd)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def push
|
66
|
+
repos.each do |repo|
|
67
|
+
push_cmd = "docker push #{repo}"
|
68
|
+
run_command(push_cmd)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def build(path = build_path)
|
73
|
+
dockerfile = tempfile(to_docker_file, 'Dockerfile', path)
|
74
|
+
build_cmd = [
|
75
|
+
"pushd #{path}",
|
76
|
+
"docker build -f #{dockerfile} #{repos.map { |repo| '-t ' + repo }.join(' ')} .",
|
77
|
+
'popd'
|
78
|
+
].join('&&')
|
79
|
+
run_command(build_cmd)
|
80
|
+
end
|
81
|
+
|
82
|
+
def to_docker_file
|
83
|
+
return '' if actions.empty? && @from.nil?
|
84
|
+
actions.clone.unshift([:from, @from]).map do |instruct, *params|
|
85
|
+
"#{instruct.to_s.upcase} #{params.join(' ')}"
|
86
|
+
end.join("\n")
|
87
|
+
end
|
88
|
+
|
89
|
+
def to_s
|
90
|
+
ret = <<-DUMP
|
91
|
+
image(:#{@name}) do
|
92
|
+
from "#{@from}"
|
93
|
+
repos #{@repos.map { |r| "'#{r}'" }.join(',')}
|
94
|
+
tag :#{@tag}
|
95
|
+
#{actions.map(&:flatten).map { |a| a.join(' ') }.join("\n")}
|
96
|
+
end
|
97
|
+
DUMP
|
98
|
+
ret
|
99
|
+
end
|
100
|
+
|
101
|
+
def full_name
|
102
|
+
"#{@name}:#{tag}"
|
103
|
+
end
|
104
|
+
alias dump to_s
|
105
|
+
def self.create(name, *params, **opts, &block)
|
106
|
+
if name.is_a?(String)
|
107
|
+
opts[:repos] ||= []
|
108
|
+
opts[:repos].unshift(name)
|
109
|
+
end
|
110
|
+
|
111
|
+
ret = Image.new(name)
|
112
|
+
ret.config(opts)
|
113
|
+
ret.instance_exec(*params, &block) if block
|
114
|
+
ret
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def image(name, *params, **opts, &block)
|
120
|
+
ret = DkComposer::Image.create(name, *params, **opts, &block)
|
121
|
+
shortdesc, longdesc = (@desc || []).pop
|
122
|
+
ret.shortdesc = shortdesc
|
123
|
+
ret.longdesc = longdesc
|
124
|
+
DkComposer::IMAGE[ret.full_name.to_sym] = ret
|
125
|
+
DkComposer::IMAGE[name] = DkComposer::IMAGE["#{name}:latest".to_sym]
|
126
|
+
ret
|
127
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module DkComposer
|
2
|
+
class Network
|
3
|
+
include Composefile::Network
|
4
|
+
include Helper
|
5
|
+
attr_accessor :name, :fields
|
6
|
+
def initialize(name)
|
7
|
+
@name = name
|
8
|
+
@fields={}
|
9
|
+
end
|
10
|
+
|
11
|
+
def to_h
|
12
|
+
ret={}
|
13
|
+
ret.merge!(@fields)
|
14
|
+
ret={"#{name}":ret}
|
15
|
+
ret.stringfy_key
|
16
|
+
end
|
17
|
+
|
18
|
+
def to_s
|
19
|
+
ret= if @fields.empty?
|
20
|
+
"network :#{name}"
|
21
|
+
else
|
22
|
+
<<-DUMP
|
23
|
+
network(:#{name}) do
|
24
|
+
#{
|
25
|
+
fields.map do |(k,v)|
|
26
|
+
v=v.to_quote_s if v.is_a?(String)
|
27
|
+
v=v.map{|a| "'#{a}'"}.join(",") if v.is_a?(Array)
|
28
|
+
"#{k} #{v.to_s}"
|
29
|
+
end.join("\n")
|
30
|
+
}
|
31
|
+
end
|
32
|
+
DUMP
|
33
|
+
end
|
34
|
+
ret
|
35
|
+
end
|
36
|
+
alias dump to_s
|
37
|
+
|
38
|
+
def self.create(name,*params, **opts, &block)
|
39
|
+
ret = new(name)
|
40
|
+
ret.config(opts)
|
41
|
+
ret.instance_exec(&block) if block
|
42
|
+
ret
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
def network(name,*params, **opts, &block)
|
47
|
+
ret=DkComposer::Network.create(name,*params, **opts, &block)
|
48
|
+
shortdesc, longdesc = (@desc || []).pop
|
49
|
+
ret.shortdesc = shortdesc
|
50
|
+
ret.longdesc = longdesc
|
51
|
+
DkComposer::NETWORK[name] = ret
|
52
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
module DkComposer
|
4
|
+
class Service
|
5
|
+
include Composefile::Service
|
6
|
+
include Helper
|
7
|
+
attr_accessor :image, :name,:fields
|
8
|
+
def initialize(name)
|
9
|
+
@name = name
|
10
|
+
@fields={}
|
11
|
+
end
|
12
|
+
|
13
|
+
|
14
|
+
def image(name, **opt, &block)
|
15
|
+
ret = if IMAGE[name]
|
16
|
+
IMAGE[name].deep_clone
|
17
|
+
else
|
18
|
+
Image.create(name)
|
19
|
+
end
|
20
|
+
ret.config(opt)
|
21
|
+
ret.instance_exec(&block) if block
|
22
|
+
@image = ret
|
23
|
+
ret
|
24
|
+
end
|
25
|
+
|
26
|
+
def to_h
|
27
|
+
ret={image: @image.repo}
|
28
|
+
ret.merge!(@fields)
|
29
|
+
ret={"#{name}":ret}
|
30
|
+
ret.stringfy_key
|
31
|
+
end
|
32
|
+
|
33
|
+
def run
|
34
|
+
s=stack(:tmp_stack)
|
35
|
+
s.config service: self.name
|
36
|
+
s.run("-d")
|
37
|
+
end
|
38
|
+
|
39
|
+
def to_yaml
|
40
|
+
to_h.to_yaml
|
41
|
+
end
|
42
|
+
|
43
|
+
def to_s
|
44
|
+
image_name=if @image.name.is_a?(Symbol)
|
45
|
+
@image.name.to_colon_s
|
46
|
+
else
|
47
|
+
%Q{"#{@image.name}"}
|
48
|
+
end
|
49
|
+
ret=<<-DUMP
|
50
|
+
service(:#{name}) do
|
51
|
+
image #{image_name}
|
52
|
+
#{
|
53
|
+
fields.map do |(k,v)|
|
54
|
+
v=v.to_quote_s if v.is_a?(String)
|
55
|
+
v=v.map{|a| "\"#{a}\""}.join(",") if v.is_a?(Array)
|
56
|
+
v=v.to_flatten_s if v.is_a?(Hash)
|
57
|
+
"#{k} #{v.to_s}"
|
58
|
+
end.join("\n")
|
59
|
+
}
|
60
|
+
end
|
61
|
+
DUMP
|
62
|
+
ret
|
63
|
+
end
|
64
|
+
alias dump to_s
|
65
|
+
|
66
|
+
def self.create(name,*params,**opts, &block)
|
67
|
+
ret = Service.new(name)
|
68
|
+
ret.config opts
|
69
|
+
ret.instance_exec(*params,&block) if block
|
70
|
+
ret
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
def service(name,*params,**opts, &block)
|
75
|
+
ret=DkComposer::Service.create(name,*params,**opts,&block)
|
76
|
+
shortdesc, longdesc = (@desc || []).pop
|
77
|
+
ret.shortdesc = shortdesc
|
78
|
+
ret.longdesc = longdesc
|
79
|
+
|
80
|
+
DkComposer::SERVICE[name] = ret
|
81
|
+
ret
|
82
|
+
end
|
@@ -0,0 +1,131 @@
|
|
1
|
+
module DkComposer
|
2
|
+
class Stack
|
3
|
+
include Helper
|
4
|
+
attr_accessor :name, :services, :version, :volumes, :networks
|
5
|
+
def initialize(name)
|
6
|
+
@name = name
|
7
|
+
@services = []
|
8
|
+
@volumes = {}
|
9
|
+
@networks = {}
|
10
|
+
@version = '2'
|
11
|
+
end
|
12
|
+
|
13
|
+
def service(name, **opts, &block)
|
14
|
+
ret = if SERVICE[name]
|
15
|
+
SERVICE[name].deep_clone
|
16
|
+
else
|
17
|
+
Service.create(name)
|
18
|
+
end
|
19
|
+
ret.config(opts)
|
20
|
+
ret.instance_exec(&block) if block
|
21
|
+
@services << ret
|
22
|
+
ret
|
23
|
+
end
|
24
|
+
|
25
|
+
def volume(name, **opts, &block)
|
26
|
+
ret = if VOLUME[name]
|
27
|
+
VOLUME[name].deep_clone
|
28
|
+
else
|
29
|
+
Volume.create(name)
|
30
|
+
end
|
31
|
+
ret.config(opts)
|
32
|
+
ret.instance_exec(&block) if block
|
33
|
+
@volumes[name] = ret
|
34
|
+
ret
|
35
|
+
end
|
36
|
+
|
37
|
+
def network(name, **opts, &block)
|
38
|
+
ret = if NETWORK[name]
|
39
|
+
NETWORK[name].deep_clone
|
40
|
+
else
|
41
|
+
Network.create(name)
|
42
|
+
end
|
43
|
+
ret.config(opts)
|
44
|
+
ret.instance_exec(&block) if block
|
45
|
+
@networks[name] = ret
|
46
|
+
ret
|
47
|
+
end
|
48
|
+
|
49
|
+
def version(value = nil)
|
50
|
+
value ? @version = value : @version
|
51
|
+
end
|
52
|
+
|
53
|
+
def run(*opts, path: build_path)
|
54
|
+
composefile = tempfile(to_yaml, 'docker-compose.yml', path)
|
55
|
+
up_cmd = [
|
56
|
+
"pushd #{path}",
|
57
|
+
"docker-compose -f #{composefile} up #{opts.join(' ')}",
|
58
|
+
'popd'
|
59
|
+
].join('&&')
|
60
|
+
run_command(up_cmd)
|
61
|
+
end
|
62
|
+
|
63
|
+
def to_h
|
64
|
+
ret = {
|
65
|
+
version: @version,
|
66
|
+
volumes: @volumes.each_with_object({}) do |(_, v), r|
|
67
|
+
r.merge! v.to_h
|
68
|
+
end.stringfy_key,
|
69
|
+
networks: @networks.each_with_object({}) do |(_, v), r|
|
70
|
+
r.merge! v.to_h
|
71
|
+
end.stringfy_key,
|
72
|
+
services: @services.each_with_object({}) do |s, r|
|
73
|
+
r.merge! s.to_h
|
74
|
+
end
|
75
|
+
}
|
76
|
+
ret
|
77
|
+
end
|
78
|
+
|
79
|
+
def to_yaml
|
80
|
+
Hash[to_h.collect { |k, v| [k.to_s, v] }].to_yaml
|
81
|
+
end
|
82
|
+
|
83
|
+
def self.create(name, *params, **opts, &block)
|
84
|
+
ret = Stack.new(name)
|
85
|
+
ret.config(opts)
|
86
|
+
ret.instance_exec(*params, &block) if block
|
87
|
+
ret
|
88
|
+
end
|
89
|
+
|
90
|
+
def to_s
|
91
|
+
ret = <<-DUMP
|
92
|
+
stack(:#{name}, version: '#{version}') do
|
93
|
+
#{@volumes.map { |(_, v)| v.to_s }.join("\n")}
|
94
|
+
#{@networks.map { |(_, v)| v.to_s }.join("\n")}
|
95
|
+
#{@services.map(&:to_s).join("\n")}
|
96
|
+
end
|
97
|
+
DUMP
|
98
|
+
ret
|
99
|
+
end
|
100
|
+
alias dump to_s
|
101
|
+
|
102
|
+
def from_h(h)
|
103
|
+
version h[:version]
|
104
|
+
|
105
|
+
h[:volumes].each do |k, v|
|
106
|
+
volume(k, v || {})
|
107
|
+
end
|
108
|
+
h[:networks].each do |k, v|
|
109
|
+
network(k, v || {})
|
110
|
+
end
|
111
|
+
|
112
|
+
h[:services].each do |k, v|
|
113
|
+
service(k, v)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
def self.load_compose_file(file, name = :auto_generated)
|
118
|
+
opts = YAML.load_file(file)
|
119
|
+
ret = create(name)
|
120
|
+
ret.from_h(opts.symbolize_key)
|
121
|
+
ret
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
def stack(name, *params, **opts, &block)
|
126
|
+
ret = DkComposer::Stack.create(name, *params, **opts, &block)
|
127
|
+
shortdesc, longdesc = (@desc || []).pop
|
128
|
+
ret.shortdesc = shortdesc
|
129
|
+
ret.longdesc = longdesc
|
130
|
+
DkComposer::STACK[name] = ret
|
131
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module DkComposer
|
2
|
+
|
3
|
+
class Volume
|
4
|
+
include Composefile::Volume
|
5
|
+
include Helper
|
6
|
+
attr_accessor :name, :fields
|
7
|
+
def initialize(name)
|
8
|
+
@name = name
|
9
|
+
@fields={}
|
10
|
+
end
|
11
|
+
|
12
|
+
def to_h
|
13
|
+
ret={}
|
14
|
+
ret.merge!(@fields)
|
15
|
+
ret={"#{name}":ret}
|
16
|
+
ret.stringfy_key.stringfy_bool_value
|
17
|
+
end
|
18
|
+
|
19
|
+
def to_s
|
20
|
+
ret= if @fields.empty?
|
21
|
+
"volume :#{name}"
|
22
|
+
else
|
23
|
+
<<-DUMP
|
24
|
+
volume(:#{name}) do
|
25
|
+
#{
|
26
|
+
fields.map do |(k,v)|
|
27
|
+
v=v.to_quote_s if v.is_a?(String)
|
28
|
+
v=v.map{|a| "'#{a}'"}.join(",") if v.is_a?(Array)
|
29
|
+
"#{k} #{v.to_s}"
|
30
|
+
end.join("\n")
|
31
|
+
}
|
32
|
+
end
|
33
|
+
DUMP
|
34
|
+
end
|
35
|
+
ret
|
36
|
+
end
|
37
|
+
alias dump to_s
|
38
|
+
|
39
|
+
def self.create(name,*params, **opts, &block)
|
40
|
+
ret = new(name)
|
41
|
+
ret.config(opts)
|
42
|
+
ret.instance_exec(*params,&block) if block
|
43
|
+
ret
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
def volume(name,*params, **opts, &block)
|
48
|
+
ret=DkComposer::Volume.create(name,*params, **opts, &block)
|
49
|
+
shortdesc, longdesc = (@desc || []).pop
|
50
|
+
ret.shortdesc = shortdesc
|
51
|
+
ret.longdesc = longdesc
|
52
|
+
DkComposer::VOLUME[name] = ret
|
53
|
+
end
|
data/lib/dkcomposer.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'dkcomposer/version'
|
2
|
+
require 'tempfile'
|
3
|
+
require 'pry-byebug'
|
4
|
+
require 'yaml'
|
5
|
+
|
6
|
+
require 'dkcomposer/dockercompose'
|
7
|
+
require 'dkcomposer/ext'
|
8
|
+
require 'dkcomposer/config'
|
9
|
+
require 'dkcomposer/helper'
|
10
|
+
require 'dkcomposer/dockerfile'
|
11
|
+
require 'dkcomposer/image'
|
12
|
+
require 'dkcomposer/service'
|
13
|
+
require 'dkcomposer/stack'
|
14
|
+
require 'dkcomposer/volume'
|
15
|
+
require 'dkcomposer/network'
|
16
|
+
|
17
|
+
module Dkcomposer
|
18
|
+
# Your code goes here...
|
19
|
+
end
|
metadata
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: dkcomposer
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- shaoyang
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-11-24 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.15'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.15'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
description: dkcomposer
|
42
|
+
email:
|
43
|
+
- shao4phone@gmail.com
|
44
|
+
executables: []
|
45
|
+
extensions: []
|
46
|
+
extra_rdoc_files: []
|
47
|
+
files:
|
48
|
+
- LICENSE.txt
|
49
|
+
- README.md
|
50
|
+
- lib/dkcomposer.rb
|
51
|
+
- lib/dkcomposer/config.rb
|
52
|
+
- lib/dkcomposer/dockercompose.rb
|
53
|
+
- lib/dkcomposer/dockerfile.rb
|
54
|
+
- lib/dkcomposer/ext.rb
|
55
|
+
- lib/dkcomposer/helper.rb
|
56
|
+
- lib/dkcomposer/image.rb
|
57
|
+
- lib/dkcomposer/network.rb
|
58
|
+
- lib/dkcomposer/service.rb
|
59
|
+
- lib/dkcomposer/stack.rb
|
60
|
+
- lib/dkcomposer/version.rb
|
61
|
+
- lib/dkcomposer/volume.rb
|
62
|
+
homepage: http://github.com/shaoyangyu
|
63
|
+
licenses:
|
64
|
+
- MIT
|
65
|
+
metadata: {}
|
66
|
+
post_install_message:
|
67
|
+
rdoc_options: []
|
68
|
+
require_paths:
|
69
|
+
- lib
|
70
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '0'
|
75
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
76
|
+
requirements:
|
77
|
+
- - ">="
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: '0'
|
80
|
+
requirements: []
|
81
|
+
rubyforge_project:
|
82
|
+
rubygems_version: 2.6.11
|
83
|
+
signing_key:
|
84
|
+
specification_version: 4
|
85
|
+
summary: dkcomposer
|
86
|
+
test_files: []
|