swarm_cluster_cli_ope 0.2.1 → 0.4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: de6a7a1c00385430cb66e44f3fc8c02bac60bc5c930223c9cf56d592205d4963
4
- data.tar.gz: 6e400a291bc159ac2e6149f55fe46cbe7dcdeb84b391ee4d7f93c211d19625d2
3
+ metadata.gz: dcf7eb87d7665ee32ead2dff9a05a3a7abb09587c6ffb0dcea8fa8c1dee8564b
4
+ data.tar.gz: f6f4716e71b2505d0b0e1928679ba92bc572c4382bb165f4ae3a77de5c01abcb
5
5
  SHA512:
6
- metadata.gz: e680840f5518ac667362afde85caca8f10a86bbb77cc122bd53580284e7ee8c6f365bc0b5b0f158eb494a97431765fd9cf057554c6ed20d3e10ef91779cd1dc3
7
- data.tar.gz: 3976388f15a0fe1fd34efe15f2977f3b21d5167c7bbbf3d534c5ab0c10e1b34126110f36e00f186c3cd66b8456929db58585e29a414d6799f1a66b69352e7b31
6
+ metadata.gz: fbe56a69b398f32dfd2ba9ef1328fa3c10f6182f689b38089d8aa3a25e67130ee246459cf84e1b06e688172843b4b64c5aeaaec08fa9856fffd3ab5921625d59
7
+ data.tar.gz: bd0b42b2043c0462914cfe240c59c931554b675001781642674bc82425c4c5df10aeb782acdcdaac4b1727e3e948bda9f93646455e5eaeb80ad91263239ee71f
@@ -1,9 +1,19 @@
1
1
  ## Changelog
2
2
 
3
+ # 0.4
4
+ - implementazione push pull con il comando **stacksync** di pg
5
+ - controllo di versione sul file caricato rispeto a gemma, con conseguente warning
6
+
7
+ # 0.3
8
+ - implementazione push pull con il comando **stacksync** di mysql
9
+
10
+ # 0.2
11
+ - implementazione comando **stacksync** con configurazioni nello stack per eseguire rsync di files e dump di sqlite3
12
+
3
13
  # 0.1.0
4
14
  - rsync dei files da/verso cluster su cartella condivisa
5
15
  - copia files direttamente in container
6
16
  - shell in servizio
7
17
  - mc in servizio
8
18
  - configurazioni globali
9
- - configurazioni di progetto
19
+ - configurazioni di progetto
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- swarm_cluster_cli_ope (0.2.1)
4
+ swarm_cluster_cli_ope (0.4)
5
5
  activesupport
6
6
  open4
7
7
  thor (~> 1.0)
@@ -10,23 +10,23 @@ PATH
10
10
  GEM
11
11
  remote: https://rubygems.org/
12
12
  specs:
13
- activesupport (6.0.3)
13
+ activesupport (6.0.3.3)
14
14
  concurrent-ruby (~> 1.0, >= 1.0.2)
15
15
  i18n (>= 0.7, < 2)
16
16
  minitest (~> 5.1)
17
17
  tzinfo (~> 1.1)
18
18
  zeitwerk (~> 2.2, >= 2.2.2)
19
- concurrent-ruby (1.1.6)
20
- i18n (1.8.2)
19
+ concurrent-ruby (1.1.7)
20
+ i18n (1.8.5)
21
21
  concurrent-ruby (~> 1.0)
22
- minitest (5.14.0)
22
+ minitest (5.14.2)
23
23
  open4 (1.3.4)
24
24
  rake (12.3.3)
25
25
  thor (1.0.1)
26
26
  thread_safe (0.3.6)
27
27
  tzinfo (1.2.7)
28
28
  thread_safe (~> 0.1)
29
- zeitwerk (2.3.0)
29
+ zeitwerk (2.4.0)
30
30
 
31
31
  PLATFORMS
32
32
  ruby
data/README.md CHANGED
@@ -95,17 +95,119 @@ Utilizzare `rsync_binded_from` per scaricare e `rsync_binded_to` per caricare
95
95
  swarm_cli_ope rsync_binded_from --stack-name=STACK_NAME --service_name NOME_SERVIZIO_SENZA_STACK --binded-container-folders CARTELLA_CONTAINER --local-folder CARTELLA_DESTINAZIONE
96
96
  ```
97
97
 
98
+ ### stacksync
99
+ Si occupa di scaricare|caricare,utilizzando le configurazioni presenti, i dati dallo stack remoto
100
+
101
+ Le configurazioni sono contenute nell'array: sync_configs.
102
+
103
+ ogni configurazione è composta da:
104
+
105
+ ```json
106
+ {
107
+ service:""
108
+ how:""
109
+ configs:{ }
110
+ }
111
+ ```
112
+
113
+ - service è il nome del servizio
114
+ - how è il come sincronizzare, definendo la tipologia:
115
+ - pg -> DB TODO
116
+ - mysql -> DB: dump del db con mysqldump
117
+ - sqlite3 -> DB: viene eseguita una copia del file
118
+ - rsync -> RSYNC
119
+ - configs: è un hash con le configurazioni per ogni tipo di sincronizzazione
120
+
121
+ Possibili CFGS per tipologia:
122
+
123
+ - rsync:
124
+ - local: -> path cartella locale
125
+ - remote: -> path cartella remota (contesto del container)
126
+ - sqlite3:
127
+ - local: -> path al file
128
+ - remote: -> path al file remoto (contesto del container)
129
+ - mysql:
130
+ - local: -> hash di configurazioni per il DB locale
131
+ - service: "db" -> nome del servizio nel compose locale, DEFAULT: quello definito sopra
132
+ - mysql_password_env: "MYSQL_PASSWORD" -> variabile ambiente interna al servizio contenente PASSWORD, DEFAULT: MYSQL_PASSWORD
133
+ - mysql_password: "root" -> valore in chiaro, in sostituzione della variabile ambiente, DEFAULT: root
134
+ - mysql_user_env: "MYSQL_USER" -> variabile ambiente interna al servizio contenente USERNAME, DEFAULT: MYSQL_USER
135
+ - mysql_user: "root" -> valore in chiaro, in sostituzione della variabile ambiente, DEFAULT: root
136
+ - database_name_env: "MYSQL_DATABASE" -> variabile ambiente interna al servizio contenente NOME DB, DEFAULT: MYSQL_DATABASE
137
+ - database_name: "nome_db" -> valore in chiaro, in sostituzione della variabile ambiente
138
+ - remote: -> hash di configurazioni per il DB remoto
139
+ - service: "db" -> nome del servizio nel compose locale, DEFAULT: quello definito sopra
140
+ - mysql_password_env: "MYSQL_PASSWORD" -> variabile ambiente interna al servizio contenente PASSWORD, DEFAULT: MYSQL_PASSWORD
141
+ - mysql_password: "root" -> valore in chiaro, in sostituzione della variabile ambiente, DEFAULT: root
142
+ - mysql_user_env: "MYSQL_USER" -> variabile ambiente interna al servizio contenente USERNAME, DEFAULT: MYSQL_USER
143
+ - mysql_user: "root" -> valore in chiaro, in sostituzione della variabile ambiente, DEFAULT: root
144
+ - database_name_env: "MYSQL_DATABASE" -> variabile ambiente interna al servizio contenente NOME DB, DEFAULT: MYSQL_DATABASE
145
+ - database_name: "MYSQL_DATABASE" -> valore in chiaro, in sostituzione della variabile ambiente
146
+ - pg:
147
+ - local: -> hash di configurazioni per il DB locale
148
+ - service: "db" -> nome del servizio nel compose locale, DEFAULT: quello definito sopra
149
+ - pg_password_env: "POSTGRES_USER" -> variabile ambiente interna al servizio contenente PASSWORD, DEFAULT: POSTGRES_PASSWORD
150
+ - pg_password: "" -> valore in chiaro, in sostituzione della variabile ambiente
151
+ - pg_user_env: "POSTGRES_USER" -> variabile ambiente interna al servizio contenente USERNAME, DEFAULT: POSTGRES_USER
152
+ - pg_user: "postgres" -> valore in chiaro, in sostituzione della variabile ambiente, DEFAULT: postgres
153
+ - database_name_env: "POSTGRES_DB" -> variabile ambiente interna al servizio contenente NOME DB, DEFAULT: POSTGRES_DB
154
+ - database_name: "nome_db" -> valore in chiaro, in sostituzione della variabile ambiente
155
+ - remote: -> hash di configurazioni per il DB remoto
156
+ - service: "db" -> nome del servizio nel compose locale, DEFAULT: quello definito sopra
157
+ - pg_password_env: "POSTGRES_USER" -> variabile ambiente interna al servizio contenente PASSWORD, DEFAULT: POSTGRES_PASSWORD
158
+ - pg_password: "" -> valore in chiaro, in sostituzione della variabile ambiente
159
+ - pg_user_env: "POSTGRES_USER" -> variabile ambiente interna al servizio contenente USERNAME, DEFAULT: POSTGRES_USER
160
+ - pg_user: "postgres" -> valore in chiaro, in sostituzione della variabile ambiente, DEFAULT: postgres
161
+ - database_name_env: "POSTGRES_DB" -> variabile ambiente interna al servizio contenente NOME DB, DEFAULT: POSTGRES_DB
162
+ - database_name: "nome_db" -> valore in chiaro, in sostituzione della variabile ambiente
163
+
164
+ #### EXAMPLE:
165
+ Esempio di sincronizzazione di un file sqlite3 e una cartella
166
+
167
+ ```json
168
+ {
169
+ "stack_name": "test1",
170
+ "sync_configs": [
171
+ {
172
+ "service": "second",
173
+ "how": "rsync",
174
+ "configs": {
175
+ "remote": "/test_bind",
176
+ "local": "./uploads"
177
+ }
178
+ },
179
+ {
180
+ "service": "test_sqlite3",
181
+ "how": "sqlite3",
182
+ "configs": {
183
+ "remote": "/cartella_sqlite3/esempio.sqlite3",
184
+ "local": "./development.sqlite3"
185
+ }
186
+ }
187
+ ]
188
+ }
189
+ ```
190
+
191
+
98
192
  ## Development
99
193
 
100
194
  nel file di configurazione creato nella home aggiungere la chiave "dev_mode":1 per collegarsi localmente
101
195
 
102
196
  ### Abbiamo due tasks swarm di simulazione
103
197
  ```shell script
104
- docker stack deploy -c test_folder/test_1/docker-compose.yml test1
198
+ docker stack deploy -c test_folder/test_1/docker-compose.yml test_1_stack
105
199
  docker stack deploy -c test_folder/test_1/docker-compose.yml test1_staging
106
200
  docker stack deploy -c test_folder/test_2/docker_compose.yml test2
107
201
  ```
108
202
 
203
+ Per simulare una sincronizzazione fra locale e remoto di un mysql, lanciamo lo stesso stack anche come compose, in modo
204
+ da trovarci sulla stessa macchina con tutte e due le situazioni
205
+ ```shell script
206
+ docker-compose -f test_folder/test_1/docker-compose-local.yml up -d
207
+ ```
208
+
209
+
210
+
109
211
  To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version
110
212
  number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git
111
213
  commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
@@ -243,7 +243,12 @@ module SwarmClusterCliOpe
243
243
  end
244
244
  end
245
245
 
246
- desc "stacksync DIRECTION", "Si occupa di scaricare|caricare,utilizzando le configurazioni presenti, i dati dallo stack remoto"
246
+ desc "version", "versione della cli"
247
+ def version
248
+ say VERSION
249
+ end
250
+
251
+ desc "stacksync [DIRECTION:pull|push]", "Si occupa di scaricare|caricare,utilizzando le configurazioni presenti, i dati dallo stack remoto"
247
252
  long_desc <<-LONGDESC.gsub("\n", "\x5")
248
253
  le configurazioni sono contenute nell'array: sync_configs.
249
254
  ogni configurazione è composta da:
@@ -255,10 +260,79 @@ module SwarmClusterCliOpe
255
260
  - service è il nome del servizio
256
261
  - how è il come sincronizzare, definendo la tipologia:
257
262
  ---- pg -> DB TODO
258
- ---- mysql -> DB TODO
259
- ---- sqlite3 -> DB
263
+ ---- mysql -> DB dump con mysql
264
+ ---- sqlite3 -> DB: viene eseguita una copia del file
260
265
  ---- rsync -> RSYNC
261
266
  - configs: è un hash con le configurazioni per ogni tipo di sincronizzazione
267
+
268
+ Possibili CFGS per tipologia:
269
+ rsync:
270
+ --local: -> path cartella locale
271
+ --remote: -> path cartella remota (contesto del container)
272
+
273
+ sqlite3:
274
+ --local: -> path al file
275
+ --remote: -> path al file remoto (contesto del container)
276
+
277
+ mysql:
278
+ --local: -> hash di configurazioni per il DB locale
279
+ - service: "db" -> nome del servizio nel compose locale, DEFAULT: quello definito sopra
280
+ - mysql_password_env: "MYSQL_PASSWORD" -> variabile ambiente interna al servizio contenente PASSWORD, DEFAULT: MYSQL_PASSWORD
281
+ - mysql_password: "root" -> valore in chiaro, in sostituzione della variabile ambiente, DEFAULT: root
282
+ - mysql_user_env: "MYSQL_USER" -> variabile ambiente interna al servizio contenente USERNAME, DEFAULT: MYSQL_USER
283
+ - mysql_user: "root" -> valore in chiaro, in sostituzione della variabile ambiente, DEFAULT: root
284
+ - database_name_env: "MYSQL_DATABASE" -> variabile ambiente interna al servizio contenente NOME DB, DEFAULT: MYSQL_DATABASE
285
+ - database_name: "nome_db" -> valore in chiaro, in sostituzione della variabile ambiente
286
+ --remote: -> hash di configurazioni per il DB remoto
287
+ - service: "db" -> nome del servizio nel compose locale, DEFAULT: quello definito sopra
288
+ - mysql_password_env: "MYSQL_PASSWORD" -> variabile ambiente interna al servizio contenente PASSWORD, DEFAULT: MYSQL_PASSWORD
289
+ - mysql_password: "root" -> valore in chiaro, in sostituzione della variabile ambiente, DEFAULT: root
290
+ - mysql_user_env: "MYSQL_USER" -> variabile ambiente interna al servizio contenente USERNAME, DEFAULT: MYSQL_USER
291
+ - mysql_user: "root" -> valore in chiaro, in sostituzione della variabile ambiente, DEFAULT: root
292
+ - database_name_env: "MYSQL_DATABASE" -> variabile ambiente interna al servizio contenente NOME DB, DEFAULT: MYSQL_DATABASE
293
+ - database_name: "MYSQL_DATABASE" -> valore in chiaro, in sostituzione della variabile ambiente
294
+ pg:
295
+ --local: -> hash di configurazioni per il DB locale
296
+ - service: "db" -> nome del servizio nel compose locale, DEFAULT: quello definito sopra
297
+ - pg_password_env: "POSTGRES_USER" -> variabile ambiente interna al servizio contenente PASSWORD, DEFAULT: POSTGRES_PASSWORD
298
+ - pg_password: "" -> valore in chiaro, in sostituzione della variabile ambiente
299
+ - pg_user_env: "POSTGRES_USER" -> variabile ambiente interna al servizio contenente USERNAME, DEFAULT: POSTGRES_USER
300
+ - pg_user: "postgres" -> valore in chiaro, in sostituzione della variabile ambiente, DEFAULT: postgres
301
+ - database_name_env: "POSTGRES_DB" -> variabile ambiente interna al servizio contenente NOME DB, DEFAULT: POSTGRES_DB
302
+ - database_name: "nome_db" -> valore in chiaro, in sostituzione della variabile ambiente
303
+ --remote: -> hash di configurazioni per il DB remoto
304
+ - service: "db" -> nome del servizio nel compose locale, DEFAULT: quello definito sopra
305
+ - pg_password_env: "POSTGRES_USER" -> variabile ambiente interna al servizio contenente PASSWORD, DEFAULT: POSTGRES_PASSWORD
306
+ - pg_password: "" -> valore in chiaro, in sostituzione della variabile ambiente
307
+ - pg_user_env: "POSTGRES_USER" -> variabile ambiente interna al servizio contenente USERNAME, DEFAULT: POSTGRES_USER
308
+ - pg_user: "postgres" -> valore in chiaro, in sostituzione della variabile ambiente, DEFAULT: postgres
309
+ - database_name_env: "POSTGRES_DB" -> variabile ambiente interna al servizio contenente NOME DB, DEFAULT: POSTGRES_DB
310
+ - database_name: "nome_db" -> valore in chiaro, in sostituzione della variabile ambiente
311
+
312
+
313
+ EXAMPLE:
314
+ Esempio di sincronizzazione di un file sqlite3 e una cartella
315
+ {
316
+ "stack_name": "test1",
317
+ "sync_configs": [
318
+ {
319
+ "service": "second",
320
+ "how": "rsync",
321
+ "configs": {
322
+ "remote": "/test_bind",
323
+ "local": "./uploads"
324
+ }
325
+ },
326
+ {
327
+ "service": "test_sqlite3",
328
+ "how": "sqlite3",
329
+ "configs": {
330
+ "remote": "/cartella_sqlite3/esempio.sqlite3",
331
+ "local": "./development.sqlite3"
332
+ }
333
+ }
334
+ ]
335
+ }
262
336
  LONGDESC
263
337
 
264
338
  def stacksync(direction)
@@ -271,8 +345,17 @@ module SwarmClusterCliOpe
271
345
  raise "ONLY [push|pull] action accepted"
272
346
  end
273
347
  cfgs.env(options[:environment]) do |cfgs|
274
- cfgs.sync_configurations.each do |sync|
275
- sync.send(direction)
348
+ sync_cfgs = cfgs.sync_configurations
349
+ if sync_cfgs.empty?
350
+ say "Attenzione, configurazioni di sincronizzazione vuoto. Leggere la documentazione"
351
+ else
352
+ sync_cfgs.each do |sync|
353
+ say "----------->>>>>>"
354
+ say "[ #{sync.class.name} ]"
355
+ sync.send(direction)
356
+ say "COMPLETE"
357
+ say "<<<<<<-----------"
358
+ end
276
359
  end
277
360
  end
278
361
  end
@@ -0,0 +1,12 @@
1
+ module SwarmClusterCliOpe
2
+ module Commands
3
+ class ComposeContainer < Container
4
+
5
+ # Siamo in locale
6
+ def docker_host
7
+ ""
8
+ end
9
+
10
+ end
11
+ end
12
+ end
@@ -9,6 +9,13 @@ module SwarmClusterCliOpe
9
9
  end.execute
10
10
  end
11
11
 
12
+ def exec(container_id,cmd_str)
13
+ self.base_suffix_command = []
14
+ command do |cmd|
15
+ cmd.add("exec #{container_id} #{cmd_str}")
16
+ end.execute
17
+ end
18
+
12
19
  ##
13
20
  # Esegue il ps sui container, possibile filtrare passando nome stack e/o nome servizio
14
21
  # @param [String] service_name
@@ -140,7 +140,8 @@ module SwarmClusterCliOpe
140
140
  if stack_name
141
141
  File.open(File.join(FileUtils.pwd, self.class.cfgs_project_file_name(with_env: @environment)), "wb") do |f|
142
142
  f.write({
143
- stack_name: stack_name
143
+ stack_name: stack_name,
144
+ version: VERSION
144
145
  }.to_json)
145
146
  end
146
147
  end
@@ -163,18 +164,35 @@ module SwarmClusterCliOpe
163
164
  nodes.find { |c| c.id == node_id }
164
165
  end
165
166
 
167
+ ##
168
+ # Indica il nome del progetto locale compose, quella parte di nome che viene attaccata in fronte
169
+ # ad ogni nome di servizio locale, e che come default è il nome della cartella in cui risiede
170
+ # il docker-compose.yml file
171
+ # @return [String]
172
+ def local_compose_project_name
173
+ File.basename(FileUtils.pwd).downcase
174
+ end
175
+
166
176
  ##
167
177
  # Elenco di tutte le configurazioni di sincronizzazione
178
+ # @return [Array]
168
179
  def sync_configurations
169
- merged_configurations[:sync_configs].collect do |c|
180
+ cfgs = merged_configurations[:sync_configs]
181
+ return [] if cfgs.nil? or !cfgs.is_a?(Array)
182
+ cfgs.collect do |c|
170
183
 
171
184
  case c[:how]
172
185
  when 'sqlite3'
173
186
  SyncConfigs::Sqlite3.new(self, c)
174
187
  when 'rsync'
175
188
  SyncConfigs::Rsync.new(self, c)
189
+ when 'mysql'
190
+ SyncConfigs::Mysql.new(self, c)
191
+ when 'pg'
192
+ SyncConfigs::PostGres.new(self, c)
176
193
  else
177
194
  logger.error { "CONFIGURAIONE NON PREVISTA: #{c[:how]}" }
195
+ nil
178
196
  end
179
197
 
180
198
  end.compact
@@ -230,10 +248,16 @@ module SwarmClusterCliOpe
230
248
  project_cfgs.merge!(JSON.parse(File.read(enviroment_file)).deep_symbolize_keys)
231
249
  end
232
250
 
233
- logger.debug { "CONFIGS[#{@environment}]: #{project_cfgs.inspect}" }
234
251
  hash[key] = self.class.read_base.merge(project_cfgs)
235
252
  end
236
253
 
254
+ configuration_version = @_merged_configurations[@environment][:version]
255
+ if Gem::Version.new(configuration_version) > Gem::Version.new(VERSION)
256
+ puts "WARNING: Versione del file di configurazione [#{configuration_version}] più aggiornata della gemma [#{VERSION}], eseguire upgrade
257
+ gem update swarm_cluster_cli_ope"
258
+ exit
259
+ end
260
+
237
261
  @_merged_configurations[@environment]
238
262
 
239
263
  end
@@ -0,0 +1,17 @@
1
+ module SwarmClusterCliOpe
2
+ module Models
3
+ class ComposeContainer < Container
4
+
5
+ # @return [SwarmClusterCliOpe::Models::ComposeContainer]
6
+ def self.find_by_service_name(service_name, stack_name: '')
7
+ res = ShellCommandExecution.new("docker inspect #{[stack_name, service_name, "1"].compact.join("_".strip)}").execute
8
+ self.new(JSON.parse(res.raw_result[:stdout]).first)
9
+ end
10
+
11
+ def mapped_uri_connection
12
+ nil
13
+ end
14
+
15
+ end
16
+ end
17
+ end
@@ -4,7 +4,7 @@ module SwarmClusterCliOpe
4
4
 
5
5
  #@return [String]
6
6
  attr_accessor :name
7
- #@return [String]
7
+ #@return [String] id del container
8
8
  attr_accessor :id
9
9
  #@return [String] nome dell'immagine
10
10
  attr_accessor :image
@@ -51,6 +51,12 @@ module SwarmClusterCliOpe
51
51
  docker_command.cp("#{id}:#{src}", dest).success?
52
52
  end
53
53
 
54
+ ##
55
+ # Esegue il comando passato
56
+ def exec(cmd)
57
+ docker_command.exec(id, cmd)
58
+ end
59
+
54
60
  ##
55
61
  # Ritorna il connection_uri del nodo che ospita il container
56
62
  # @return [String]
@@ -19,7 +19,6 @@ module SwarmClusterCliOpe
19
19
 
20
20
  ##
21
21
  # Containers del servizio
22
-
23
22
  # @return [Array<SwarmClusterCliOpe::Container>]
24
23
  def containers
25
24
  tasks.collect { |t| t.container }
@@ -1,10 +1,13 @@
1
1
  module SwarmClusterCliOpe
2
2
  module SyncConfigs
3
3
  class Base < Thor::Shell::Basic
4
-
4
+ include LoggerConcern
5
5
  #@return [String] nome del servizio dello stack
6
6
  attr_accessor :service
7
7
 
8
+ #@return [Hash] configurazioni di sincro
9
+ attr_accessor :configs
10
+
8
11
  # @param [Hash] configs
9
12
  # @param [Continuation] stack_cfgs
10
13
  def initialize(stack_cfgs, configs)
@@ -30,6 +33,12 @@ module SwarmClusterCliOpe
30
33
  raise "TO OVERRIDE"
31
34
  end
32
35
 
36
+ private
37
+ # @return [SwarmClusterCliOpe::Models::Container]
38
+ def container
39
+ Models::Container.find_by_service_name(service, stack_name: stack_name)
40
+ end
41
+
33
42
  end
34
43
  end
35
44
  end
@@ -0,0 +1,49 @@
1
+ module SwarmClusterCliOpe
2
+ module SyncConfigs
3
+ class BaseDatabase < Base
4
+
5
+ # @return [SwarmClusterCliOpe::SyncConfigs::EnvConfigs]
6
+ def remote
7
+ self.class::EnvConfigs.new(self, @configs[:configs][:remote] || {}, -> { container })
8
+ end
9
+
10
+ # @return [SwarmClusterCliOpe::SyncConfigs::EnvConfigs]
11
+ def local
12
+ self.class::EnvConfigs.new(self, @configs[:configs][:local] || {}, -> { local_container })
13
+ end
14
+
15
+ ##
16
+ # Classe interna che rappresenta le configurazioni del DB
17
+ class EnvConfigs < SwarmClusterCliOpe::SyncConfigs::EnvConfigs
18
+
19
+ end
20
+
21
+ ##
22
+ # Funzione che ricapitola le informazioni utilizzate per eseguire l'operazione
23
+ def resume(direction)
24
+ puts "RESUME - #{direction}
25
+ service: #{service}
26
+ local:
27
+ service_name: #{local.service_name}
28
+ database_name: #{local.database_name}
29
+ username: #{local.username}
30
+ password: #{local.password}
31
+ remote:
32
+ service_name: #{remote.service_name}
33
+ database_name: #{remote.database_name}
34
+ username: #{remote.username}
35
+ password: #{remote.password}"
36
+
37
+ end
38
+
39
+ private
40
+
41
+ def local_container
42
+ # il nome dello stack del compose usiamo come standard il nome della cartella, come lo fà già composer di default
43
+ Models::ComposeContainer.find_by_service_name(local.service_name, stack_name: @stack_cfgs.local_compose_project_name)
44
+ end
45
+
46
+
47
+ end
48
+ end
49
+ end
@@ -14,20 +14,16 @@ module SwarmClusterCliOpe
14
14
 
15
15
  # @return [TrueClass, FalseClass]
16
16
  def push
17
- container.copy_in(local_folder,remote_folder)
17
+ say "#{local_folder} -->> #{remote_folder}" if container.copy_in(local_folder,remote_folder)
18
18
  end
19
19
 
20
20
  # @return [TrueClass, FalseClass]
21
21
  def pull
22
- container.copy_out(remote_folder,local_folder)
22
+ say "#{remote_folder} -->> #{local_folder}" if container.copy_out(remote_folder,local_folder)
23
23
  end
24
24
 
25
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
26
+
31
27
 
32
28
 
33
29
  end
@@ -0,0 +1,78 @@
1
+ module SwarmClusterCliOpe
2
+ module SyncConfigs
3
+ ##
4
+ # Classe per la gestione dell'ambiente differente fra local e remote
5
+ # sono presenti le variabili di classe per definire una minima DSL per poter definire le variabili
6
+ # disponibili e i default da utilizzare
7
+ class EnvConfigs
8
+ # @param [Hash] configs
9
+ # @param [SwarmClusterCliOpe::SyncConfigs::Base] sync_configs
10
+ # @param [Lambda] lambda che ritorna il container Istanza container su cui la
11
+ def initialize(sync_configs, configs, container)
12
+ @configs = configs
13
+ @sync_configs = sync_configs
14
+ @lambda_container = container
15
+ end
16
+
17
+ ##
18
+ # Metodo che richiama la lambda della generazione del container al momento che ne
19
+ # è proprio necessario
20
+ def container
21
+ @container ||= @lambda_container.call
22
+ end
23
+
24
+ # @return [String]
25
+ def service_name
26
+ @configs[:service] || @sync_configs.service
27
+ end
28
+
29
+
30
+ ##
31
+ # Costruisce i metodi che restituiscono i valori delle configurazioni
32
+ #
33
+ # @param [String,Symbol] name -> nome della stringa con cui viene generato il metodo
34
+ # @param [String,Symbol] default_env -> nome env default nel caso non sia passato
35
+ # @param [String,Symbol] configuration_name -> nome della configurazione da utilizzare per estrapolare la configurazione
36
+ # in automatico viene tenuto conto se cercare per la versione
37
+ # con _env o senza....precedenza SENZA
38
+ # @param [nil,String] default_value se non è estrapolato nessun valore, viene utilizzato il valore di default
39
+ def self.define_cfgs(name, default_env:, configuration_name:,default_value:nil)
40
+ configuration_name ||= name
41
+
42
+ define_method(name) do
43
+ return self.instance_variable_get("@#{name}") if self.instance_variable_defined?("@#{name}")
44
+
45
+ #valore restituito direttamente dalla configurazione
46
+ if @configs.key?(configuration_name)
47
+ value = @configs["#{configuration_name}".to_sym] || default_value
48
+ else
49
+ env_var = @configs["#{configuration_name}_env".to_sym] || default_env
50
+ value = find_env_file_variable(env_var) || default_value
51
+ end
52
+ self.instance_variable_set("@#{name}", value)
53
+ end
54
+
55
+ end
56
+
57
+
58
+ private
59
+
60
+ ##
61
+ # Estrae l'env dal container e ne tiene in memoria una copia, in modo da non fare multiple chiamate
62
+ def env
63
+ @env ||= container.exec("env").raw_result[:stdout].split("\n").collect { |v| v.split('=') }.to_h
64
+ end
65
+
66
+ def find_env_file_variable(env_var)
67
+ if env_var.match?(/_FILE$/)
68
+ # dobbiamo controllare la presenza del file e salvarci il contenuto
69
+ nome_file = env[env_var.to_s]
70
+ container.exec("cat #{nome_file}").raw_result[:stdout]
71
+ else
72
+ # env normale, dobbiamo ricavarlo dal container
73
+ env[env_var.to_s]
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,42 @@
1
+ module SwarmClusterCliOpe
2
+ module SyncConfigs
3
+ class Mysql < BaseDatabase
4
+
5
+ # @return [TrueClass, FalseClass]
6
+ def pull
7
+ resume('pull')
8
+ if yes?("Confermare il comando?[y,yes]")
9
+ tmp_file = "/tmp/#{Time.now.to_i}.sql.gz"
10
+ container.exec("bash -c 'mysqldump -u #{remote.username} --password=#{remote.password} #{remote.database_name} | gzip -c -f' > #{tmp_file}")
11
+ local_container.copy_in(tmp_file, tmp_file)
12
+ local_container.exec("bash -c 'zcat #{tmp_file} | mysql -u #{local.username} --password=#{local.password} #{local.database_name}'")
13
+ end
14
+ true
15
+ end
16
+
17
+ # @return [TrueClass, FalseClass]
18
+ def push
19
+ resume('PUSH')
20
+ if yes?("ATTENZIONE !!!!!!PUSH!!!!! - Confermare il comando?[y,yes]")
21
+ tmp_file = "/tmp/#{Time.now.to_i}.sql.gz"
22
+ local_container.exec("bash -c 'mysqldump -u #{local.username} --password=#{local.password} #{local.database_name} | gzip -c -f' > #{tmp_file}")
23
+ container.copy_in(tmp_file, tmp_file)
24
+ container.exec("bash -c 'zcat #{tmp_file} | mysql -u #{remote.username} --password=#{remote.password} #{remote.database_name}'")
25
+ end
26
+ true
27
+ end
28
+
29
+ ##
30
+ # Classe interna che rappresenta le configurazioni del DB
31
+ class EnvConfigs < BaseDatabase::EnvConfigs
32
+
33
+ define_cfgs :database_name, default_env: "MYSQL_DATABASE", configuration_name: :database_name
34
+ define_cfgs :username, default_env: "MYSQL_USER", configuration_name: :mysql_user, default_value: 'root'
35
+ define_cfgs :password, default_env: "MYSQL_PASSWORD", configuration_name: :mysql_password, default_value: 'root'
36
+
37
+ end
38
+
39
+
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,115 @@
1
+ module SwarmClusterCliOpe
2
+ module SyncConfigs
3
+ class PostGres < BaseDatabase
4
+
5
+ # @return [TrueClass, FalseClass]
6
+ def pull
7
+ resume('pull')
8
+
9
+ dump_cmd = dump_cmd(remote.username, remote.password, remote.database_name)
10
+ logger.info{ "DUMP COMMAND: #{dump_cmd.join(' ')}"}
11
+ if yes?("Confermare il comando?[y,yes]")
12
+ tmp_file = "/tmp/#{Time.now.to_i}.sql.gz"
13
+ container.exec("bash -c '#{dump_cmd.join(' ')}' > #{tmp_file}")
14
+ local_container.copy_in(tmp_file, tmp_file)
15
+
16
+ # drop old db and recreate
17
+ drop_cmd = drop_cmd(local.username, local.password, local.database_name)
18
+ logger.info{ "DROP COMMAND: #{drop_cmd.join(' ')}"}
19
+ local_container.exec("bash -c '#{drop_cmd.join(' ')}'")
20
+ create_cmd = create_cmd(local.username, local.password, local.database_name)
21
+ logger.info{ "CREATE COMMAND: #{create_cmd.join(' ')}"}
22
+ local_container.exec("bash -c '#{create_cmd.join(' ')}'")
23
+
24
+ restore_cmd = restore_cmd(local.username, local.password, local.database_name, tmp_file)
25
+ logger.info{ "RESTORE COMMAND: #{restore_cmd.join(' ')}"}
26
+ local_container.exec("bash -c '#{restore_cmd.join(' ')}'")
27
+ end
28
+ true
29
+ end
30
+
31
+ # @return [TrueClass, FalseClass]
32
+ def push
33
+ resume('PUSH')
34
+
35
+ dump_cmd = dump_cmd(local.username, local.password, local.database_name)
36
+ say "DUMP COMMAND: #{dump_cmd.join(' ')}"
37
+ if yes?("ATTENZIONE !!!!!!PUSH!!!!! - Confermare il comando?[y,yes]")
38
+ tmp_file = "/tmp/#{Time.now.to_i}.sql.gz"
39
+ local_container.exec("bash -c '#{dump_cmd.join(' ')}' > #{tmp_file}")
40
+ container.copy_in(tmp_file, tmp_file)
41
+
42
+ # drop old db and recreate
43
+ drop_cmd = drop_cmd(remote.username, remote.password, remote.database_name)
44
+ logger.info{ "DROP COMMAND: #{drop_cmd.join(' ')}"}
45
+ container.exec("bash -c '#{drop_cmd.join(' ')}'")
46
+
47
+ create_cmd = create_cmd(remote.username, remote.password, remote.database_name)
48
+ logger.info{ "CREATE COMMAND: #{create_cmd.join(' ')}"}
49
+ container.exec("bash -c '#{create_cmd.join(' ')}'")
50
+
51
+ restore_cmd = restore_cmd(remote.username, remote.password, remote.database_name, tmp_file)
52
+ say "RESTORE COMMAND: #{restore_cmd.join(' ')}"
53
+ container.exec("bash -c '#{restore_cmd.join(' ')}'")
54
+ end
55
+ true
56
+ end
57
+
58
+ ##
59
+ # Classe interna che rappresenta le configurazioni del DB
60
+ class EnvConfigs < BaseDatabase::EnvConfigs
61
+
62
+ define_cfgs :database_name, default_env: "POSTGRES_DB", configuration_name: :database_name
63
+ define_cfgs :username, default_env: "POSTGRES_USER", configuration_name: :pg_user, default_value: 'postgres'
64
+ define_cfgs :password, default_env: "POSTGRES_PASSWORD", configuration_name: :pg_password
65
+
66
+ end
67
+
68
+ private
69
+
70
+ def create_cmd(username, password, database_name)
71
+ create_cmd = []
72
+ create_cmd << "PGPASSWORD=\"#{password}\""
73
+ create_cmd << 'createdb'
74
+ create_cmd << "--username=#{username}"
75
+ create_cmd << database_name
76
+ end
77
+
78
+ def drop_cmd(username, password, database_name)
79
+ drop_cmd = []
80
+ drop_cmd << "PGPASSWORD=\"#{password}\""
81
+ drop_cmd << 'dropdb'
82
+ drop_cmd << "--username=#{username}"
83
+ drop_cmd << database_name
84
+ drop_cmd
85
+ end
86
+
87
+ def restore_cmd(username, password, database_name, tmp_file)
88
+ restore_cmd = []
89
+ restore_cmd << "PGPASSWORD=\"#{password}\""
90
+ restore_cmd << 'pg_restore'
91
+ restore_cmd << '--no-acl'
92
+ restore_cmd << '--no-owner'
93
+ restore_cmd << "--username=#{username}"
94
+ restore_cmd << "--dbname=#{database_name}"
95
+ restore_cmd << tmp_file
96
+ restore_cmd
97
+ end
98
+
99
+ def dump_cmd(username, password, database_name)
100
+ dump_cmd = []
101
+ dump_cmd << "PGPASSWORD=\"#{password}\""
102
+ dump_cmd << 'pg_dump'
103
+ dump_cmd << '--no-acl'
104
+ dump_cmd << '--no-owner'
105
+ dump_cmd << "--username=#{username}"
106
+ dump_cmd << '--format=custom'
107
+ dump_cmd << '--compress=9'
108
+ dump_cmd << database_name
109
+ dump_cmd
110
+ end
111
+
112
+
113
+ end
114
+ end
115
+ end
@@ -28,9 +28,6 @@ module SwarmClusterCliOpe
28
28
  private
29
29
  def execute(direction: :down)
30
30
 
31
- # trovo il container del servizio
32
- container = Models::Container.find_by_service_name(service, stack_name: stack_name)
33
-
34
31
  if container.nil?
35
32
  say "Container non trovato con #{stack_name}@##{service}"
36
33
  exit 0
@@ -1,3 +1,3 @@
1
1
  module SwarmClusterCliOpe
2
- VERSION = "0.2.1"
2
+ VERSION = "0.4"
3
3
  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.2.1
4
+ version: '0.4'
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-07-03 00:00:00.000000000 Z
11
+ date: 2020-09-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -90,6 +90,7 @@ files:
90
90
  - lib/swarm_cluster_cli_ope.rb
91
91
  - lib/swarm_cluster_cli_ope/cli.rb
92
92
  - lib/swarm_cluster_cli_ope/commands/base.rb
93
+ - lib/swarm_cluster_cli_ope/commands/compose_container.rb
93
94
  - lib/swarm_cluster_cli_ope/commands/container.rb
94
95
  - lib/swarm_cluster_cli_ope/commands/service.rb
95
96
  - lib/swarm_cluster_cli_ope/commands/swarm.rb
@@ -99,6 +100,7 @@ files:
99
100
  - lib/swarm_cluster_cli_ope/logger_concern.rb
100
101
  - lib/swarm_cluster_cli_ope/manager.rb
101
102
  - lib/swarm_cluster_cli_ope/models/base.rb
103
+ - lib/swarm_cluster_cli_ope/models/compose_container.rb
102
104
  - lib/swarm_cluster_cli_ope/models/container.rb
103
105
  - lib/swarm_cluster_cli_ope/models/mapped_volume.rb
104
106
  - lib/swarm_cluster_cli_ope/models/service.rb
@@ -108,7 +110,11 @@ files:
108
110
  - lib/swarm_cluster_cli_ope/shell_command_execution.rb
109
111
  - lib/swarm_cluster_cli_ope/shell_command_response.rb
110
112
  - lib/swarm_cluster_cli_ope/sync_configs/base.rb
113
+ - lib/swarm_cluster_cli_ope/sync_configs/base_database.rb
111
114
  - lib/swarm_cluster_cli_ope/sync_configs/copy.rb
115
+ - lib/swarm_cluster_cli_ope/sync_configs/env_configs.rb
116
+ - lib/swarm_cluster_cli_ope/sync_configs/mysql.rb
117
+ - lib/swarm_cluster_cli_ope/sync_configs/post_gres.rb
112
118
  - lib/swarm_cluster_cli_ope/sync_configs/rsync.rb
113
119
  - lib/swarm_cluster_cli_ope/sync_configs/sqlite3.rb
114
120
  - lib/swarm_cluster_cli_ope/version.rb