swarm_cluster_cli_ope 0.1.6 → 0.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/Gemfile.lock +1 -1
- data/README.md +8 -2
- data/lib/swarm_cluster_cli_ope/cli.rb +165 -120
- data/lib/swarm_cluster_cli_ope/configuration.rb +92 -25
- data/lib/swarm_cluster_cli_ope/sync_configs/base.rb +35 -0
- data/lib/swarm_cluster_cli_ope/sync_configs/copy.rb +35 -0
- data/lib/swarm_cluster_cli_ope/sync_configs/rsync.rb +74 -0
- data/lib/swarm_cluster_cli_ope/sync_configs/sqlite3.rb +8 -0
- data/lib/swarm_cluster_cli_ope/version.rb +1 -1
- metadata +7 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 473cc11423d57b9b40b361184587b1acdda0d14751b12266740eb98e1f1c7caa
|
4
|
+
data.tar.gz: 542e14fb88a4d40c34209853678e80fc0d2bddc90745aa9bd6eaee666e7fcf03
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 90fe0e391b0aa2eb12f1564153905db9fd294aa2817094da62dc1a7da7c3c663f7f94f99996d5f3c1e7818f1d8d214d2c1286fdefbe9eedfb932c3abdf224586
|
7
|
+
data.tar.gz: 24e26ab924509fbc0df1d03a67c59ec5d62d544a8cc0709f757012c2dcb6fd8915a049ad82ccec49316f19b4cdb65c1bac9f4c62e3a1c4231f5de7c316bbcbc1
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -36,6 +36,9 @@ FILE di configurazione base:
|
|
36
36
|
3 DEBUG
|
37
37
|
|
38
38
|
|
39
|
+
### ENV differenti
|
40
|
+
Tutti i comandi possono essere accompagnati con -e, per scopparli nel relativo ENVIRONMENT
|
41
|
+
|
39
42
|
### Configuratione di un progetto
|
40
43
|
Si occupa di generare nel progetto il file di configurazione in cui impostare impostazioni specifiche di progetto
|
41
44
|
quali stack_name (.swarm_cluster_project)
|
@@ -98,11 +101,14 @@ nel file di configurazione creato nella home aggiungere la chiave "dev_mode":1 p
|
|
98
101
|
|
99
102
|
### Abbiamo due tasks swarm di simulazione
|
100
103
|
```shell script
|
101
|
-
docker stack deploy -c test_folder/test_1/
|
104
|
+
docker stack deploy -c test_folder/test_1/docker-compose.yml test1
|
105
|
+
docker stack deploy -c test_folder/test_1/docker-compose.yml test1_staging
|
102
106
|
docker stack deploy -c test_folder/test_2/docker_compose.yml test2
|
103
107
|
```
|
104
108
|
|
105
|
-
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version
|
109
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version
|
110
|
+
number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git
|
111
|
+
commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
106
112
|
|
107
113
|
|
108
114
|
## License
|
@@ -11,6 +11,9 @@ module SwarmClusterCliOpe
|
|
11
11
|
true
|
12
12
|
end
|
13
13
|
|
14
|
+
class_option :environment, required: false, type: :string, aliases: [:e],
|
15
|
+
desc: "Esegue tutte le operazioni nell'env scelto, il file di configurazione dovrà avere il nome: #{Configuration.cfgs_project_file_name}.ENV"
|
16
|
+
|
14
17
|
desc "install", "Creazione della configurazione base della gemma"
|
15
18
|
|
16
19
|
def install
|
@@ -40,7 +43,9 @@ module SwarmClusterCliOpe
|
|
40
43
|
desc "config", "Visualizza le configurazioni mergiate (HOME + Project configuration[#{Configuration.cfgs_project_file_name}])"
|
41
44
|
|
42
45
|
def config
|
43
|
-
|
46
|
+
cfgs.env(options[:environment]) do
|
47
|
+
puts JSON.pretty_generate(cfgs.merged_configurations)
|
48
|
+
end
|
44
49
|
end
|
45
50
|
|
46
51
|
|
@@ -54,88 +59,93 @@ module SwarmClusterCliOpe
|
|
54
59
|
end
|
55
60
|
|
56
61
|
desc "services", "lista dei servizi per uno stack"
|
57
|
-
option :stack_name, required: false, type: :string
|
62
|
+
option :stack_name, required: false, type: :string
|
58
63
|
|
59
64
|
def services
|
60
|
-
|
61
|
-
|
65
|
+
cfgs.env(options[:environment]) do |cfgs|
|
66
|
+
stack_name = options[:stack_name] || cfgs.stack_name
|
67
|
+
Models::Service.all(stack_name: stack_name).each do |s|
|
68
|
+
puts s.name
|
69
|
+
end
|
62
70
|
end
|
63
71
|
end
|
64
72
|
|
65
73
|
desc "mc SERVICE_NAME", "Apre MC tra la cartella attuale e il container (potrebbe dar luogo a degli errori, ma funziona)"
|
66
|
-
option :stack_name, required: false, type: :string
|
74
|
+
option :stack_name, required: false, type: :string
|
67
75
|
|
68
76
|
def mc(service_name)
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
begin
|
78
|
-
container = Models::Container.find_by_service_name(service_name, stack_name: options[:stack_name])
|
79
|
-
|
80
|
-
server = container.node.hostname
|
81
|
-
|
82
|
-
# Creo container ssh
|
83
|
-
# DOCKER_HOST=ssh://swarm_node_1 docker run --rm -d -p 12222:22 \
|
84
|
-
# --volumes-from sistemi-test_swarm_cluster_cli_wordpress.1.zbbz1xxh4vzzccndvs973jnuc \
|
85
|
-
# sickp/alpine-sshd:7.5
|
86
|
-
#
|
87
|
-
cmd = container.docker_command
|
88
|
-
cmd.base_suffix_command = ''
|
89
|
-
shell_operation = cmd.command do |c|
|
90
|
-
c.add("run --rm -d -p 42222:22 --volumes-from #{container.id} sickp/alpine-sshd:7.5")
|
77
|
+
cfgs.env(options[:environment]) do |cfgs|
|
78
|
+
stack_name = options[:stack_name] || cfgs.stack_name
|
79
|
+
# Disabilito output della libreria
|
80
|
+
MakeMakefile::Logging.instance_variable_set(:@logfile, File::NULL)
|
81
|
+
unless find_executable 'mc'
|
82
|
+
puts "Non hai installato MC"
|
83
|
+
exit 0
|
91
84
|
end
|
92
85
|
|
93
|
-
|
94
|
-
|
95
|
-
puts "Container generato con id:#{id_container}"
|
96
|
-
|
97
|
-
# eseguo tunnel verso nodo e container ssh
|
98
|
-
socket_ssh_path = "/tmp/socket_ssh_#{id_container}"
|
99
|
-
# ssh -f -N -T -M -S <path-to-socket> -L 13333:0.0.0.0:42222 <server>
|
100
|
-
cmd_tunnel = ["ssh", "-f -N -T -M", "-S #{socket_ssh_path}", "-L 13333:0.0.0.0:42222", server].join(" ")
|
101
|
-
puts "Apro tunnel"
|
102
|
-
puts cmd_tunnel
|
103
|
-
system(cmd_tunnel)
|
104
|
-
|
105
|
-
# apro MC
|
106
|
-
# mc . sftp://root:root@0.0.0.0:13333
|
107
|
-
mc_cmd = "mc . sftp://root:root@0.0.0.0:13333"
|
108
|
-
puts "Apro MC"
|
109
|
-
puts mc_cmd
|
110
|
-
system(mc_cmd)
|
111
|
-
ensure
|
112
|
-
if socket_ssh_path
|
113
|
-
# chiudo tunnel
|
114
|
-
# ssh -S <path-to-socket> -O exit <server>
|
115
|
-
close_tunnel_cmd = "ssh -S #{socket_ssh_path} -O exit #{server}"
|
116
|
-
puts "Chiudo tunnel"
|
117
|
-
# say close_tunnel_cmd
|
118
|
-
ShellCommandExecution.new(close_tunnel_cmd).execute
|
119
|
-
end
|
86
|
+
begin
|
87
|
+
container = Models::Container.find_by_service_name(service_name, stack_name: stack_name)
|
120
88
|
|
121
|
-
|
122
|
-
|
123
|
-
#
|
124
|
-
|
125
|
-
|
89
|
+
server = container.node.hostname
|
90
|
+
|
91
|
+
# Creo container ssh
|
92
|
+
# DOCKER_HOST=ssh://swarm_node_1 docker run --rm -d -p 12222:22 \
|
93
|
+
# --volumes-from sistemi-test_swarm_cluster_cli_wordpress.1.zbbz1xxh4vzzccndvs973jnuc \
|
94
|
+
# sickp/alpine-sshd:7.5
|
95
|
+
#
|
126
96
|
cmd = container.docker_command
|
127
97
|
cmd.base_suffix_command = ''
|
128
|
-
|
129
|
-
c.add("
|
98
|
+
shell_operation = cmd.command do |c|
|
99
|
+
c.add("run --rm -d -p 42222:22 --volumes-from #{container.id} sickp/alpine-sshd:7.5")
|
100
|
+
end
|
101
|
+
|
102
|
+
puts "Creazione container #{shell_operation.string_command}"
|
103
|
+
id_container = shell_operation.execute.raw_result[:stdout]
|
104
|
+
puts "Container generato con id:#{id_container}"
|
105
|
+
|
106
|
+
# eseguo tunnel verso nodo e container ssh
|
107
|
+
socket_ssh_path = "/tmp/socket_ssh_#{id_container}"
|
108
|
+
# ssh -f -N -T -M -S <path-to-socket> -L 13333:0.0.0.0:42222 <server>
|
109
|
+
cmd_tunnel = ["ssh", "-f -N -T -M", "-S #{socket_ssh_path}", "-L 13333:0.0.0.0:42222", server].join(" ")
|
110
|
+
puts "Apro tunnel"
|
111
|
+
puts cmd_tunnel
|
112
|
+
system(cmd_tunnel)
|
113
|
+
|
114
|
+
# apro MC
|
115
|
+
# mc . sftp://root:root@0.0.0.0:13333
|
116
|
+
mc_cmd = "mc . sftp://root:root@0.0.0.0:13333"
|
117
|
+
puts "Apro MC"
|
118
|
+
puts mc_cmd
|
119
|
+
system(mc_cmd)
|
120
|
+
ensure
|
121
|
+
if socket_ssh_path
|
122
|
+
# chiudo tunnel
|
123
|
+
# ssh -S <path-to-socket> -O exit <server>
|
124
|
+
close_tunnel_cmd = "ssh -S #{socket_ssh_path} -O exit #{server}"
|
125
|
+
puts "Chiudo tunnel"
|
126
|
+
# say close_tunnel_cmd
|
127
|
+
ShellCommandExecution.new(close_tunnel_cmd).execute
|
130
128
|
end
|
131
|
-
stop_ssh_container.execute
|
132
|
-
end
|
133
129
|
|
130
|
+
if id_container
|
131
|
+
# cancello container
|
132
|
+
# docker stop #{id_container}
|
133
|
+
puts "Spengo container di appoggio"
|
134
|
+
puts "docker stop #{id_container}"
|
135
|
+
cmd = container.docker_command
|
136
|
+
cmd.base_suffix_command = ''
|
137
|
+
stop_ssh_container = cmd.command do |c|
|
138
|
+
c.add("stop #{id_container}")
|
139
|
+
end
|
140
|
+
stop_ssh_container.execute
|
141
|
+
end
|
142
|
+
|
143
|
+
end
|
134
144
|
end
|
135
145
|
end
|
136
146
|
|
137
147
|
desc "cp SRC DEST", "Copia la sorgente in destinazione"
|
138
|
-
option :stack_name, required: false, type: :string
|
148
|
+
option :stack_name, required: false, type: :string
|
139
149
|
long_desc <<-LONGDESC
|
140
150
|
SRC e DEST possono essere un servizio, solo uno di essi può essere un servizio (TODO)
|
141
151
|
Per identificare che sia un servizio controllo se nella stringa è presete il :
|
@@ -144,46 +154,73 @@ module SwarmClusterCliOpe
|
|
144
154
|
LONGDESC
|
145
155
|
|
146
156
|
def cp(src, dest)
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
157
|
+
cfgs.env(options[:environment]) do |cfgs|
|
158
|
+
|
159
|
+
cfgs.stack_name = options[:stack_name] || cfgs.stack_name
|
160
|
+
|
161
|
+
#identifico quale dei due è il servizio e quale la path
|
162
|
+
if src.match(/^(.*)\:/)
|
163
|
+
service_name = Regexp.last_match[1]
|
164
|
+
remote = src.match(/\:(.*)$/)[1]
|
165
|
+
local = dest
|
166
|
+
execute = :pull
|
167
|
+
else
|
168
|
+
service_name = dest.match(/^(.*)\:/)[1]
|
169
|
+
remote = dest.match(/\:(.*)$/)[1]
|
170
|
+
local = src
|
171
|
+
execute = :push
|
172
|
+
end
|
173
|
+
|
174
|
+
|
175
|
+
cmd = SyncConfigs::Copy.new(cfgs, {
|
176
|
+
service: service_name,
|
177
|
+
how: 'copy',
|
178
|
+
configs: {
|
179
|
+
local: local,
|
180
|
+
remote: remote
|
181
|
+
}
|
182
|
+
})
|
183
|
+
|
184
|
+
puts "COMPLETATO" if cmd.send(execute)
|
185
|
+
|
154
186
|
end
|
155
|
-
puts "COMPLETATO" if ris
|
156
187
|
end
|
157
188
|
|
158
189
|
|
159
190
|
desc "configure_project STACK_NAME", "Genera il file di configurazione del progetto contenente il nome dello stack"
|
160
191
|
|
161
192
|
def configure_project(stack_name)
|
162
|
-
cfgs.
|
163
|
-
|
193
|
+
cfgs.env(options[:environment]) do |c|
|
194
|
+
c.stack_name = stack_name
|
195
|
+
c.save_project_cfgs
|
196
|
+
end
|
164
197
|
end
|
165
198
|
|
199
|
+
|
166
200
|
desc "service_shell SERVICE_NAME", "apre una shell [default bash] dentro al container"
|
167
|
-
option :stack_name, required: false, type: :string
|
201
|
+
option :stack_name, required: false, type: :string
|
168
202
|
option :shell, required: false, type: :string, default: 'bash'
|
169
203
|
|
170
204
|
def service_shell(service_name)
|
171
|
-
|
205
|
+
cfgs.env(options[:environment]) do |cfgs|
|
206
|
+
stack_name = options[:stack_name] || cfgs.stack_name
|
207
|
+
container = Models::Container.find_by_service_name(service_name, stack_name: stack_name)
|
172
208
|
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
209
|
+
cmd = container.docker_command
|
210
|
+
cmd.base_suffix_command = ''
|
211
|
+
shell_operation = cmd.command do |c|
|
212
|
+
c.add("exec -it #{container.id} #{options[:shell]}")
|
213
|
+
end
|
178
214
|
|
179
|
-
|
180
|
-
|
181
|
-
|
215
|
+
say "Stai entrando della shell in #{options[:shell]} del container #{stack_name}->#{container.name}[#{container.id}]"
|
216
|
+
system(shell_operation.string_command)
|
217
|
+
say "Shell chiusa"
|
218
|
+
end
|
182
219
|
end
|
183
220
|
|
184
221
|
|
185
222
|
desc "rsync_binded_from", "esegue un rsync dalla cartella bindata (viene sincronizzato il contenuto)"
|
186
|
-
option :stack_name, required: false, type: :string
|
223
|
+
option :stack_name, required: false, type: :string
|
187
224
|
option :service_name, required: true, type: :string
|
188
225
|
option :binded_container_folders, required: true, type: :string, desc: "path della cartella bindata all'interno del container da sincronizzare"
|
189
226
|
option :local_folder, required: true, type: :string, desc: "path della cartella dove sincronizzare il comando"
|
@@ -195,7 +232,7 @@ module SwarmClusterCliOpe
|
|
195
232
|
end
|
196
233
|
|
197
234
|
desc "rsync_binded_to", "esegue un rsync verso la cartella bindata"
|
198
|
-
option :stack_name, required: false, type: :string
|
235
|
+
option :stack_name, required: false, type: :string
|
199
236
|
option :service_name, required: true, type: :string
|
200
237
|
option :binded_container_folders, required: true, type: :string, desc: "path della cartella bindata all'interno del container da sincronizzare"
|
201
238
|
option :local_folder, required: true, type: :string, desc: "path della cartella dove sincronizzare il comando"
|
@@ -206,46 +243,54 @@ module SwarmClusterCliOpe
|
|
206
243
|
end
|
207
244
|
end
|
208
245
|
|
246
|
+
desc "stack_pull", "Si occupa di scaricare,utilizzando le configurazioni presenti, i dati dallo stack remoto"
|
247
|
+
long_desc <<-LONGDESC
|
248
|
+
le configurazioni sono contenute nell'array: sync_configs. \n
|
249
|
+
ogni configurazione è composta da: \n
|
250
|
+
{ \n
|
251
|
+
service:"" \n
|
252
|
+
how:"" \n
|
253
|
+
configs:{ }\n
|
254
|
+
}\n
|
255
|
+
- service è il nome del servizio\n
|
256
|
+
- how è il come sincronizzare, definendo la tipologia:\n
|
257
|
+
- pg -> DB\n TODO
|
258
|
+
- mysql -> DB\n TODO
|
259
|
+
- sqlite3 -> DB\n
|
260
|
+
- rsync -> RSYNC\n
|
261
|
+
- configs: è un hash con le configurazioni per ogni tipo di sincronizzazione\n
|
262
|
+
LONGDESC
|
209
263
|
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
container = Models::Container.find_by_service_name(options[:service_name], stack_name: options[:stack_name])
|
216
|
-
|
217
|
-
if container.nil?
|
218
|
-
say "Container non trovato con #{options[:stack_name]}@##{options[:service_name]}"
|
219
|
-
exit 0
|
264
|
+
def stack_pull
|
265
|
+
cfgs.env(options[:environment]) do |cfgs|
|
266
|
+
cfgs.sync_configurations.each do |sync|
|
267
|
+
sync.pull
|
268
|
+
end
|
220
269
|
end
|
270
|
+
end
|
221
271
|
|
272
|
+
private
|
222
273
|
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
end
|
274
|
+
def rsync_binded(direction: :down, options: {})
|
275
|
+
cfgs.env(options[:environment]) do |cfgs|
|
276
|
+
cfgs.stack_name = options[:stack_name] || cfgs.stack_name
|
277
|
+
sync = SyncConfigs::Rsync.new(cfgs, {
|
278
|
+
service: options[:service_name],
|
279
|
+
how: 'rsync',
|
280
|
+
configs: {
|
281
|
+
local: options[:local_folder],
|
282
|
+
remote: options[:binded_container_folders]
|
283
|
+
}
|
284
|
+
})
|
285
|
+
|
286
|
+
if direction == :down
|
287
|
+
sync.pull
|
288
|
+
end
|
289
|
+
if direction == :up
|
290
|
+
sync.push
|
291
|
+
end
|
242
292
|
|
243
|
-
cmd = ShellCommandExecution.new(cmd)
|
244
293
|
|
245
|
-
say "Comando da eseguire:"
|
246
|
-
say " #{cmd.string_command}"
|
247
|
-
if yes?("Confermare il comando?[y,yes]")
|
248
|
-
cmd.execute
|
249
294
|
end
|
250
295
|
end
|
251
296
|
end
|
@@ -15,6 +15,9 @@ module SwarmClusterCliOpe
|
|
15
15
|
#@return [String] nome dello stack con cui lavoriamo
|
16
16
|
attr_accessor :stack_name
|
17
17
|
|
18
|
+
#@return [String] in che enviroment siamo, altrimenti siamo nel default
|
19
|
+
attr_accessor :environment
|
20
|
+
|
18
21
|
NoBaseConfigurations = Class.new(Error)
|
19
22
|
|
20
23
|
##
|
@@ -25,6 +28,19 @@ module SwarmClusterCliOpe
|
|
25
28
|
@_managers = self.nodes.select { |n| read_managers_cache_list.include?(n.name) }.collect { |c| Manager.new(name: c.name.to_s, connection_uri: c.connection_uri) }
|
26
29
|
end
|
27
30
|
|
31
|
+
##
|
32
|
+
# Serve per entrare nell'env corretto.
|
33
|
+
# passando l'env, tutto quello eseguito nello yield sarà gestito in quell'env.
|
34
|
+
# Verrà controllato quindi che esista il relativo file di configurazion
|
35
|
+
def env(enviroment = nil)
|
36
|
+
unless enviroment.nil?
|
37
|
+
@environment = enviroment.to_s.to_sym
|
38
|
+
end
|
39
|
+
logger.info { "ENV: #{@environment ? @environment : "BASE"}" }
|
40
|
+
yield self
|
41
|
+
@environment = nil
|
42
|
+
end
|
43
|
+
|
28
44
|
##
|
29
45
|
# Esegue un refresh della lista dei manager, ciclando su tutti i nodi, e scrivendo in /tmp un file temporaneo con
|
30
46
|
# con la lista dei nomi dei managers
|
@@ -48,8 +64,10 @@ module SwarmClusterCliOpe
|
|
48
64
|
#
|
49
65
|
# @return [Array<SwarmClusterCliOpe::Node>]
|
50
66
|
def nodes
|
51
|
-
|
52
|
-
|
67
|
+
@_nodes ||= Hash.new do |hash, key|
|
68
|
+
hash[key] = self.merged_configurations[:connections_maps].collect { |m, c| Node.new(name: m.to_s, connection_uri: c) }
|
69
|
+
end
|
70
|
+
@_nodes[environment]
|
53
71
|
end
|
54
72
|
|
55
73
|
##
|
@@ -58,22 +76,31 @@ module SwarmClusterCliOpe
|
|
58
76
|
# @param [Array<SwarmClusterCliOpe::Node>]
|
59
77
|
# @return [Configuration]
|
60
78
|
def nodes=(objs)
|
61
|
-
|
79
|
+
nodes[environment] = objs
|
62
80
|
self
|
63
81
|
end
|
64
82
|
|
65
83
|
# @return [String,NilClass] nome dello stack del progetto se configurato
|
66
84
|
def stack_name
|
67
|
-
return @stack_name if @stack_name
|
68
85
|
return nil unless self.class.exist_base?
|
69
|
-
@stack_name
|
86
|
+
@stack_name ||= Hash.new do |hash, key|
|
87
|
+
hash[key] = merged_configurations[:stack_name] if merged_configurations.key?(:stack_name)
|
88
|
+
end
|
89
|
+
@stack_name[environment]
|
90
|
+
end
|
91
|
+
|
92
|
+
##
|
93
|
+
# Imposta il nome dello stack
|
94
|
+
def stack_name=(objs)
|
95
|
+
stack_name #lo richiamo per fargli generare la variabile di classe
|
96
|
+
@stack_name[environment] = objs
|
70
97
|
end
|
71
98
|
|
72
99
|
##
|
73
100
|
# Livello di logging
|
74
101
|
# @return [Integer]
|
75
102
|
def logger_level
|
76
|
-
|
103
|
+
merged_configurations[:log_level].to_s || "0"
|
77
104
|
rescue SwarmClusterCliOpe::Configuration::NoBaseConfigurations
|
78
105
|
# quando andiamo in errore durante l'installazione per avere le informazioni per il logger.
|
79
106
|
# Usiamo lo standard
|
@@ -85,7 +112,7 @@ module SwarmClusterCliOpe
|
|
85
112
|
# @return [TrueClass, FalseClass]
|
86
113
|
def development_mode?
|
87
114
|
return false unless self.class.exist_base?
|
88
|
-
|
115
|
+
merged_configurations.key?(:dev_mode)
|
89
116
|
end
|
90
117
|
|
91
118
|
##
|
@@ -110,8 +137,8 @@ module SwarmClusterCliOpe
|
|
110
137
|
##
|
111
138
|
# Si occupa del salvataggio delle configurazioni di progetto, se abbiamo lo stack_name
|
112
139
|
def save_project_cfgs
|
113
|
-
if
|
114
|
-
File.open(File.join(FileUtils.pwd, self.class.cfgs_project_file_name), "wb") do |f|
|
140
|
+
if stack_name
|
141
|
+
File.open(File.join(FileUtils.pwd, self.class.cfgs_project_file_name(with_env: @environment)), "wb") do |f|
|
115
142
|
f.write({
|
116
143
|
stack_name: stack_name
|
117
144
|
}.to_json)
|
@@ -136,13 +163,31 @@ module SwarmClusterCliOpe
|
|
136
163
|
nodes.find { |c| c.id == node_id }
|
137
164
|
end
|
138
165
|
|
166
|
+
##
|
167
|
+
# Elenco di tutte le configurazioni di sincronizzazione
|
168
|
+
def sync_configurations
|
169
|
+
merged_configurations[:sync_configs].collect do |c|
|
170
|
+
|
171
|
+
case c[:how]
|
172
|
+
when 'sqlite3'
|
173
|
+
SyncConfigs::Sqlite3.new(self, c)
|
174
|
+
when 'rsync'
|
175
|
+
SyncConfigs::Rsync.new(self, c)
|
176
|
+
else
|
177
|
+
logger.error { "CONFIGURAIONE NON PREVISTA: #{c[:how]}" }
|
178
|
+
end
|
179
|
+
|
180
|
+
end.compact
|
181
|
+
end
|
182
|
+
|
139
183
|
private
|
140
184
|
|
141
185
|
##
|
142
186
|
# nome del file in cui salvare le configurazioni di progetto
|
143
187
|
# @return [String]
|
144
|
-
|
145
|
-
|
188
|
+
# @param [nil|String] with_env nome dell'env da cercare
|
189
|
+
def self.cfgs_project_file_name(with_env: nil)
|
190
|
+
".swarm_cluster_project#{with_env ? ".#{with_env}" : ""}"
|
146
191
|
end
|
147
192
|
|
148
193
|
##
|
@@ -150,7 +195,7 @@ module SwarmClusterCliOpe
|
|
150
195
|
# quindi ogni ora si autoripulisce e con un md5 delle configurazioni di base
|
151
196
|
# @return [String]
|
152
197
|
def swarm_manager_cache_path
|
153
|
-
md5 = Digest::MD5.hexdigest(self.
|
198
|
+
md5 = Digest::MD5.hexdigest(self.merged_configurations.to_json)
|
154
199
|
file_name = Time.now.strftime(".swarm_cluster_cli_manager_cache-%Y%m%d%H-#{md5}")
|
155
200
|
File.join("/tmp", file_name)
|
156
201
|
end
|
@@ -164,29 +209,51 @@ module SwarmClusterCliOpe
|
|
164
209
|
JSON.parse(File.read(self.base_cfg_path)).deep_symbolize_keys
|
165
210
|
end
|
166
211
|
|
212
|
+
public
|
213
|
+
|
167
214
|
## Cerca le configurazioni di progetto e le mergia se sono presenti
|
168
215
|
# @return [Hash]
|
169
|
-
def
|
170
|
-
return @_merged_configurations if @_merged_configurations
|
216
|
+
def merged_configurations
|
217
|
+
return @_merged_configurations[@environment] if @_merged_configurations
|
218
|
+
|
219
|
+
@_merged_configurations = Hash.new do |hash, key|
|
220
|
+
folder = FileUtils.pwd
|
221
|
+
default_file = looped_file(folder, self.class.cfgs_project_file_name)
|
222
|
+
enviroment_file = looped_file(folder, self.class.cfgs_project_file_name(with_env: key))
|
223
|
+
|
224
|
+
project_cfgs = {}
|
225
|
+
unless default_file.nil?
|
226
|
+
project_cfgs = JSON.parse(File.read(default_file)).deep_symbolize_keys
|
227
|
+
end
|
228
|
+
|
229
|
+
unless enviroment_file.nil?
|
230
|
+
project_cfgs.merge!(JSON.parse(File.read(enviroment_file)).deep_symbolize_keys)
|
231
|
+
end
|
232
|
+
|
233
|
+
logger.debug { "CONFIGS[#{@environment}]: #{project_cfgs.inspect}" }
|
234
|
+
hash[key] = self.class.read_base.merge(project_cfgs)
|
235
|
+
end
|
236
|
+
|
237
|
+
@_merged_configurations[@environment]
|
238
|
+
|
239
|
+
end
|
240
|
+
|
241
|
+
private
|
242
|
+
|
243
|
+
def looped_file(start_folder, file)
|
171
244
|
project_file = nil
|
172
|
-
folder = FileUtils.pwd
|
173
245
|
loop do
|
174
246
|
|
175
|
-
if File.exist?(File.join(
|
176
|
-
project_file = File.join(
|
247
|
+
if File.exist?(File.join(start_folder, file))
|
248
|
+
project_file = File.join(start_folder, file)
|
177
249
|
end
|
178
250
|
|
179
251
|
break unless project_file.nil?
|
180
|
-
break if
|
181
|
-
|
182
|
-
end
|
183
|
-
|
184
|
-
project_cfgs = {}
|
185
|
-
unless project_file.nil?
|
186
|
-
project_cfgs = JSON.parse(File.read(project_file)).deep_symbolize_keys
|
252
|
+
break if start_folder == '/'
|
253
|
+
start_folder = File.expand_path("..", start_folder)
|
187
254
|
end
|
188
255
|
|
189
|
-
|
256
|
+
project_file
|
190
257
|
end
|
191
258
|
|
192
259
|
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module SwarmClusterCliOpe
|
2
|
+
module SyncConfigs
|
3
|
+
class Base < Thor::Shell::Basic
|
4
|
+
|
5
|
+
#@return [String] nome del servizio dello stack
|
6
|
+
attr_accessor :service
|
7
|
+
|
8
|
+
# @param [Hash] configs
|
9
|
+
# @param [Continuation] stack_cfgs
|
10
|
+
def initialize(stack_cfgs, configs)
|
11
|
+
super()
|
12
|
+
@configs = configs
|
13
|
+
|
14
|
+
@service = configs[:service]
|
15
|
+
@stack_cfgs = stack_cfgs
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
delegate :stack_name, to: :@stack_cfgs
|
20
|
+
|
21
|
+
##
|
22
|
+
# Funzione che dobbiamo sovrascrivere per identificare cosa fare quando scarichiamo i dati
|
23
|
+
def pull
|
24
|
+
raise "TO OVERRIDE"
|
25
|
+
end
|
26
|
+
|
27
|
+
##
|
28
|
+
# Funzione che dobbiamo sovrascrivere per identificare cosa fare quando carichiamo i dati
|
29
|
+
def push
|
30
|
+
raise "TO OVERRIDE"
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module SwarmClusterCliOpe
|
2
|
+
module SyncConfigs
|
3
|
+
class Copy < Base
|
4
|
+
|
5
|
+
# @return [String]
|
6
|
+
def local_folder
|
7
|
+
@configs[:configs][:local]
|
8
|
+
end
|
9
|
+
|
10
|
+
# @return [String]
|
11
|
+
def remote_folder
|
12
|
+
@configs[:configs][:remote]
|
13
|
+
end
|
14
|
+
|
15
|
+
# @return [TrueClass, FalseClass]
|
16
|
+
def push
|
17
|
+
container.copy_in(local_folder,remote_folder)
|
18
|
+
end
|
19
|
+
|
20
|
+
# @return [TrueClass, FalseClass]
|
21
|
+
def pull
|
22
|
+
container.copy_out(remote_folder,local_folder)
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
private
|
27
|
+
# @return [SwarmClusterCliOpe::Models::Container]
|
28
|
+
def container
|
29
|
+
Models::Container.find_by_service_name(service, stack_name: stack_name)
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
module SwarmClusterCliOpe
|
2
|
+
module SyncConfigs
|
3
|
+
class Rsync < Base
|
4
|
+
|
5
|
+
|
6
|
+
# @return [String]
|
7
|
+
def local_folder
|
8
|
+
@configs[:configs][:local]
|
9
|
+
end
|
10
|
+
|
11
|
+
# @return [String]
|
12
|
+
def remote_folder
|
13
|
+
@configs[:configs][:remote]
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
# @return [SwarmClusterCliOpe::ShellCommandResponse]
|
18
|
+
def push
|
19
|
+
execute(direction: :up)
|
20
|
+
end
|
21
|
+
|
22
|
+
# @return [SwarmClusterCliOpe::ShellCommandResponse]
|
23
|
+
def pull
|
24
|
+
execute(direction: :down)
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
private
|
29
|
+
def execute(direction: :down)
|
30
|
+
|
31
|
+
# trovo il container del servizio
|
32
|
+
container = Models::Container.find_by_service_name(service, stack_name: stack_name)
|
33
|
+
|
34
|
+
if container.nil?
|
35
|
+
say "Container non trovato con #{stack_name}@##{service}"
|
36
|
+
exit 0
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
# trovo la cartella bindata e la relativa cartella sul nodo
|
41
|
+
volume = container.mapped_volumes.find { |v| v.destination == remote_folder and v.is_binded? }
|
42
|
+
if volume.nil?
|
43
|
+
say "Non ho trovato il volume bindato con questa destinazione all'interno del container #{remote_folder}"
|
44
|
+
exit 0
|
45
|
+
end
|
46
|
+
|
47
|
+
#costruisco il comando rsync fra cartella del nodo e cartella sul pc
|
48
|
+
cmd = ["rsync", "-zr", "--delete"]
|
49
|
+
if direction == :down
|
50
|
+
cmd << "#{volume.ssh_connection_path}/."
|
51
|
+
# creo la cartella in locale se non esiste
|
52
|
+
FileUtils.mkdir_p(local_folder)
|
53
|
+
cmd << local_folder
|
54
|
+
end
|
55
|
+
if direction == :up
|
56
|
+
cmd << "#{local_folder}/."
|
57
|
+
cmd << volume.ssh_connection_path
|
58
|
+
end
|
59
|
+
|
60
|
+
cmd = ShellCommandExecution.new(cmd)
|
61
|
+
|
62
|
+
say "Comando da eseguire:"
|
63
|
+
say " #{cmd.string_command}"
|
64
|
+
if yes?("Confermare il comando?[y,yes]")
|
65
|
+
cmd.execute
|
66
|
+
end
|
67
|
+
|
68
|
+
|
69
|
+
end
|
70
|
+
|
71
|
+
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: swarm_cluster_cli_ope
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: '0.2'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Marino Bonetti
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-07-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|
@@ -107,6 +107,10 @@ files:
|
|
107
107
|
- lib/swarm_cluster_cli_ope/node.rb
|
108
108
|
- lib/swarm_cluster_cli_ope/shell_command_execution.rb
|
109
109
|
- lib/swarm_cluster_cli_ope/shell_command_response.rb
|
110
|
+
- lib/swarm_cluster_cli_ope/sync_configs/base.rb
|
111
|
+
- lib/swarm_cluster_cli_ope/sync_configs/copy.rb
|
112
|
+
- lib/swarm_cluster_cli_ope/sync_configs/rsync.rb
|
113
|
+
- lib/swarm_cluster_cli_ope/sync_configs/sqlite3.rb
|
110
114
|
- lib/swarm_cluster_cli_ope/version.rb
|
111
115
|
- lib/swarm_cluster_cli_ope/worker.rb
|
112
116
|
- swarm_cluster_cli_ope.gemspec
|
@@ -133,7 +137,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
133
137
|
- !ruby/object:Gem::Version
|
134
138
|
version: '0'
|
135
139
|
requirements: []
|
136
|
-
rubygems_version: 3.0.
|
140
|
+
rubygems_version: 3.0.8
|
137
141
|
signing_key:
|
138
142
|
specification_version: 4
|
139
143
|
summary: WIP Gemma per la gestione del cluster swarm
|