dry-stack 0.0.88 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/dry-stack/command_compose.rb +4 -5
- data/lib/dry-stack/command_line.rb +11 -5
- data/lib/dry-stack/command_swarm_deploy.rb +14 -20
- data/lib/dry-stack/stack.rb +28 -28
- data/lib/version.rb +1 -1
- metadata +2 -5
- data/bin/stack.drs +0 -33
- data/bin/stack1.drs +0 -1
- data/bin/stack2.drs +0 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 571e75a339b0f3ad9ffb0c4d5816e4de8451b2ec3f7b3bf7a31030eef31dd176
|
4
|
+
data.tar.gz: 13b9b28f6d78a75f5d08e718743b89c4f466d2134e0ca36a89e268f557b46d90
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 32a9c2c618aeacc2efdd3892bcb1b708e3a071b6cc3a975b9e81464dbe703e374205397de4d158f6218c11898db7401d0f21f45a397878ce0153c9a9446a86d3
|
7
|
+
data.tar.gz: 5f7450cef3b2d997d1a53b0b906384282529747ccd373b9c693fbc40fae5d1e33562657833cacd7e8f0c0e60d824ae552807a3b3227333d6e4e166dd808d56d7
|
@@ -1,14 +1,13 @@
|
|
1
1
|
require_relative 'command_line'
|
2
2
|
|
3
3
|
Dry::CommandLine::COMMANDS[:to_compose] = Class.new do
|
4
|
-
def run(stack, params,
|
5
|
-
raise "none or one deploy name may be specified: #{args}" unless args.empty? || args.size == 1
|
4
|
+
def run(stack, params, _args, _extra)
|
6
5
|
_params = stack.options.merge params
|
7
|
-
|
8
|
-
|
6
|
+
yaml = stack.to_compose(_params ).lines[1..].join
|
7
|
+
$stdout.puts yaml
|
9
8
|
|
10
9
|
# substitute ENV variables
|
11
|
-
_params[:'no-env'] ? $stdout.puts(yaml) : system("echo \"#{yaml.gsub("`", '\\\`')}\"")
|
10
|
+
# _params[:'no-env'] ? $stdout.puts(yaml) : system("echo \"#{yaml.gsub("`", '\\\`')}\"")
|
12
11
|
end
|
13
12
|
|
14
13
|
def help = ['Print stack in docker compose format',
|
@@ -37,7 +37,9 @@ module Dry
|
|
37
37
|
raise 'Invalid .env file'
|
38
38
|
end
|
39
39
|
|
40
|
-
def safe_eval(
|
40
|
+
def safe_eval(drs, params)
|
41
|
+
Dry::Stack(params[:name], params[:configuration]) { eval drs, self.binding }
|
42
|
+
end
|
41
43
|
|
42
44
|
def run(args)
|
43
45
|
params = {}
|
@@ -68,9 +70,12 @@ module Dry
|
|
68
70
|
o.on('', '--name STACK_NAME', 'Define stack name')
|
69
71
|
o.on('', '--ingress', 'Generate ingress labels') { true }
|
70
72
|
o.on('', '--traefik', 'Generate traefik labels') { true }
|
71
|
-
o.on('', '--
|
72
|
-
o.on('', '--
|
73
|
-
o.on('-n', '--no-env', '
|
73
|
+
o.on('', '--traefik-tls', 'Generate traefik tls labels') { true }
|
74
|
+
o.on('', '--host-sed /from/to/', 'Sed ingress host /\\*/dev.*/')
|
75
|
+
o.on('-n', '--no-env', 'Deprecated') { $stderr.puts 'warning: deprecated option: -n' } # TODO: remove
|
76
|
+
o.on('-c', '--configuration name', 'Configuration name')
|
77
|
+
COMMANDS.values.select{_1.options(o) if _1.respond_to? :options }
|
78
|
+
|
74
79
|
o.on('-h', '--help') { puts o; exit }
|
75
80
|
o.parse! args, into: params
|
76
81
|
|
@@ -82,7 +87,8 @@ module Dry
|
|
82
87
|
stack_text = File.read(params[:stack]) if params[:stack]
|
83
88
|
stack_text ||= STDIN.read unless $stdin.tty?
|
84
89
|
|
85
|
-
|
90
|
+
|
91
|
+
safe_eval stack_text, params # isolate context
|
86
92
|
|
87
93
|
Stack.last_stack.name = params[:name] if params[:name]
|
88
94
|
COMMANDS[command.to_sym].run Stack.last_stack, params, args, extra
|
@@ -1,41 +1,35 @@
|
|
1
1
|
require_relative 'command_line'
|
2
2
|
|
3
3
|
Dry::CommandLine::COMMANDS[:swarm_deploy] = Class.new do
|
4
|
+
def options(parser)
|
5
|
+
parser.on('-x', '--context-endpoint host', 'Docker context host. Created if not exists')
|
6
|
+
end
|
7
|
+
|
4
8
|
def run(stack, params, args, extra)
|
5
|
-
unless args.empty?
|
6
|
-
c_name = args[0].to_sym
|
7
|
-
raise "deploy config not found: #{args[0]}" unless stack.swarm_deploy.key? args[0].to_sym
|
8
|
-
context = stack.swarm_deploy[args[0].to_sym]
|
9
|
-
end
|
10
9
|
_params = stack.options.merge params
|
11
10
|
stack.name = _params[:name] if _params[:name]
|
12
11
|
|
13
|
-
if context
|
14
|
-
name =
|
15
|
-
|
12
|
+
if params[:'context-endpoint']
|
13
|
+
name = params[:'context-endpoint'].gsub( /[\/.:@]/,'_').gsub( '__','_')
|
14
|
+
name = "dry-#{name}".to_sym
|
15
|
+
endpoint = params[:'context-endpoint']
|
16
16
|
contexts = {}
|
17
|
-
exec_o_lines
|
17
|
+
exec_o_lines 'docker context ls --format json' do |line|
|
18
18
|
ctx = JSON.parse line, symbolize_names: true
|
19
19
|
contexts[ctx[:Name].to_sym] = ctx # {"Current":false,"Description":"","DockerEndpoint":"ssh://root@x.x.x.x","Error":"","Name":"prod-swarm"}
|
20
20
|
end
|
21
21
|
|
22
|
-
if contexts[name] && contexts[name][:DockerEndpoint] !=
|
23
|
-
raise "context '#{name}' has different host value: #{contexts[name][:DockerEndpoint]} != #{
|
22
|
+
if contexts[name] && contexts[name][:DockerEndpoint] != endpoint
|
23
|
+
raise "context '#{name}' has different host value: #{contexts[name][:DockerEndpoint]} != #{endpoint}"
|
24
24
|
end
|
25
25
|
|
26
|
-
exec_i "docker context create #{name} --docker host=#{
|
26
|
+
exec_i "docker context create #{name} --docker host=#{endpoint}" unless contexts[name]
|
27
27
|
|
28
28
|
ENV['DOCKER_CONTEXT'] = name.to_s
|
29
|
-
stack.name = context[:stack_name] || stack.name
|
30
|
-
context[:environment].each do |k,v|
|
31
|
-
ENV[k.to_s] = v.to_s
|
32
|
-
end
|
33
29
|
end
|
34
30
|
|
35
31
|
# substitute ENV variables
|
36
|
-
yaml = stack.to_compose(_params
|
37
|
-
yaml = _params[:'no-env'] ? yaml : `echo \"#{yaml.gsub("`", '\\\`')}\"`
|
38
|
-
system " echo \"#{yaml.gsub("`", '\\\`')}\"" if _params[:v]
|
32
|
+
yaml = stack.to_compose(_params).lines[1..].join
|
39
33
|
# system " echo \"#{yaml.gsub("`", '\\\`')}\" | docker stack deploy -c - #{stack.name} --prune --resolve-image changed"
|
40
34
|
|
41
35
|
# --prune --resolve-image changed
|
@@ -48,7 +42,7 @@ Dry::CommandLine::COMMANDS[:swarm_deploy] = Class.new do
|
|
48
42
|
end
|
49
43
|
|
50
44
|
def help = ['Call docker stack deploy & add config readme w/ description',
|
51
|
-
'[... swarm_deploy
|
45
|
+
'[... swarm_deploy -- --prune --resolve-image changed]']
|
52
46
|
|
53
47
|
end.new
|
54
48
|
|
data/lib/dry-stack/stack.rb
CHANGED
@@ -39,9 +39,10 @@ module Dry
|
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
42
|
-
def Stack(name = nil, &)
|
42
|
+
def Stack(name = nil, configuration = nil, &)
|
43
43
|
Stack.last_stack = Stack.new name
|
44
44
|
Stack.last_stack.instance_exec(&) if block_given?
|
45
|
+
Stack.last_stack.apply_configuration configuration if configuration
|
45
46
|
end
|
46
47
|
|
47
48
|
class ServiceFunction
|
@@ -61,13 +62,8 @@ module Dry
|
|
61
62
|
def ingress(ing) = ((@service[:ingress] ||=[]) << ing).flatten!
|
62
63
|
end
|
63
64
|
|
64
|
-
class
|
65
|
-
def initialize(
|
66
|
-
def env(variables)= @swarm[:environment].merge! variables
|
67
|
-
def options(variables)= @swarm[:options].merge! variables
|
68
|
-
def context_host(host)= @swarm[:context_host] = host
|
69
|
-
def context_name(name)= @swarm[:context_name] = name
|
70
|
-
def stack_name(name)= @swarm[:stack_name] = name
|
65
|
+
class ConfigurationFunction
|
66
|
+
def initialize(configuration, &); @configuration = configuration; instance_exec(&) end
|
71
67
|
end
|
72
68
|
|
73
69
|
class Stack
|
@@ -75,12 +71,13 @@ module Dry
|
|
75
71
|
class << self
|
76
72
|
attr_accessor :last_stack
|
77
73
|
end
|
78
|
-
attr_accessor :name, :options, :description, :
|
74
|
+
attr_accessor :name, :options, :description, :configuration
|
79
75
|
|
80
|
-
def Stack(
|
81
|
-
|
82
|
-
|
83
|
-
|
76
|
+
def Stack(...) = Dry::Stack(...)
|
77
|
+
|
78
|
+
# def self.new(*args, &block)
|
79
|
+
# super
|
80
|
+
# end
|
84
81
|
|
85
82
|
def initialize(name)
|
86
83
|
@name = name || 'stack'
|
@@ -97,7 +94,7 @@ module Dry
|
|
97
94
|
@labels = {}
|
98
95
|
@configs = {}
|
99
96
|
@logging = {}
|
100
|
-
@
|
97
|
+
@configurations = {}
|
101
98
|
end
|
102
99
|
|
103
100
|
def expand_hash(hash)
|
@@ -123,12 +120,13 @@ module Dry
|
|
123
120
|
end
|
124
121
|
end
|
125
122
|
|
126
|
-
def
|
127
|
-
|
128
|
-
|
123
|
+
def apply_configuration(configuration)
|
124
|
+
raise "Configuration not found: #{configuration}" unless @configurations[configuration.to_sym]
|
125
|
+
@configurations[configuration.to_sym][:block_function].call @configurations[configuration.to_sym]
|
126
|
+
end
|
129
127
|
|
130
|
-
|
131
|
-
|
128
|
+
def to_compose(opts = @options)
|
129
|
+
@name = @options[:name] || @name
|
132
130
|
|
133
131
|
compose = {
|
134
132
|
# name: @name.to_s, # https://docs.docker.com/compose/compose-file/#name-top-level-element
|
@@ -323,8 +321,8 @@ module Dry
|
|
323
321
|
end
|
324
322
|
|
325
323
|
def Options(opts)
|
326
|
-
warn 'WARN: Options command is used for testing purpose.\
|
327
|
-
|
324
|
+
# warn 'WARN: Options command is used for testing purpose.\
|
325
|
+
# Not recommended in real life configurations.' unless $0 =~ /rspec/
|
328
326
|
@options.merge! opts
|
329
327
|
end
|
330
328
|
|
@@ -333,7 +331,9 @@ module Dry
|
|
333
331
|
end
|
334
332
|
|
335
333
|
def Ingress(services)
|
336
|
-
|
334
|
+
services.each do |name, ing|
|
335
|
+
@ingress[name] = ((@ingress[name] || [] ) | [ing]).flatten
|
336
|
+
end
|
337
337
|
end
|
338
338
|
|
339
339
|
def Config(name, opts)
|
@@ -382,12 +382,12 @@ module Dry
|
|
382
382
|
yield if block_given?
|
383
383
|
end
|
384
384
|
|
385
|
-
def
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
385
|
+
def Configuration(name, opts = {}, &)
|
386
|
+
configuration = @configurations[name.to_sym] ||= { }
|
387
|
+
configuration.merge! opts
|
388
|
+
configuration.merge! block_function: ->(*args){
|
389
|
+
self.instance_exec(&) if block_given?
|
390
|
+
}
|
391
391
|
end
|
392
392
|
|
393
393
|
end
|
data/lib/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dry-stack
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Artyom B
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-07-
|
11
|
+
date: 2024-07-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -102,9 +102,6 @@ extensions: []
|
|
102
102
|
extra_rdoc_files: []
|
103
103
|
files:
|
104
104
|
- bin/dry-stack
|
105
|
-
- bin/stack.drs
|
106
|
-
- bin/stack1.drs
|
107
|
-
- bin/stack2.drs
|
108
105
|
- lib/dry-stack.rb
|
109
106
|
- lib/dry-stack/apache_specific_md5.rb
|
110
107
|
- lib/dry-stack/command_compose.rb
|
data/bin/stack.drs
DELETED
@@ -1,33 +0,0 @@
|
|
1
|
-
Description <<~DSC
|
2
|
-
|
3
|
-
DSC
|
4
|
-
|
5
|
-
Options name: 'stack_name', traefik: true
|
6
|
-
SwarmDeploy :sky_gates do
|
7
|
-
context_host 'ssh://root@10.0.0.1'
|
8
|
-
stack_name 'remote_stack'
|
9
|
-
env REGISTRY_HOST: '10.100.0.2:5000'
|
10
|
-
end
|
11
|
-
Ingress admin: [
|
12
|
-
{host: 'backend.*'},
|
13
|
-
{host: 'admin.*', path: '/api', port: 4000}
|
14
|
-
]
|
15
|
-
|
16
|
-
Deploy [:admin, :operator], labels: [
|
17
|
-
'traefik.http.middlewares.%{service-name}_auth.basicauth.users=admin:$$apr1$$i7hdbc9g$$Rkocxo9snhmuESvUg0TTv/',
|
18
|
-
"traefik.http.routers.%{service-name}.middlewares=%{service-name}_auth"
|
19
|
-
]
|
20
|
-
|
21
|
-
PublishPorts admin: 4000, operator: 4001, navigator: 4002, reports: 7000 # mode: ingress, protocol: tcp
|
22
|
-
|
23
|
-
Service :admin, image: 'frontend', env: {APP: 'admin'}, ports: 5000
|
24
|
-
Service :operator, image: 'frontend', env: {APP: 'operator'}, ports: 5000
|
25
|
-
Service :navigator, image: 'frontend', env: {APP: 'navigator'}, ports: 5000
|
26
|
-
|
27
|
-
Service :backend, image: 'backend', ports: 3000 do
|
28
|
-
env APP_PORT: 3000, NODE_ENV: 'development', SKIP_GZ: true, DB_URL: '$DB_URL'
|
29
|
-
end
|
30
|
-
|
31
|
-
Service :reports, image: 'reports:0.1', env: {DB_URL: '$DB_URL'}, ports: 7000
|
32
|
-
|
33
|
-
Network :default, attachable: true
|
data/bin/stack1.drs
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
Service :reports, image: 'reports', ports: 7000, env: {DB_URL: '$DB_URL'}
|
data/bin/stack2.drs
DELETED
@@ -1,8 +0,0 @@
|
|
1
|
-
PublishPorts reports: 7000
|
2
|
-
Ingress reports: {host: 'reports.*', protocol: :http, port: 7000}
|
3
|
-
Deploy admin: { replica: 2, 'resources.limits': { cpus: 4, memory: '500M' } }
|
4
|
-
|
5
|
-
Service :admin, image: '$REGISTRY_HOST/frontend', env: { APP: 'admin' }, ports: 5000
|
6
|
-
Service :reports, image: '$REGISTRY_HOST/reports', env: { DB_URL: '$DB_URL' }
|
7
|
-
|
8
|
-
Network :default, attachable: true
|