swarm_cluster_cli_ope 0.1.6 → 0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4d080e1fbcc49d24e180f7cae13bf99415e85b7ae7a443c175a8251486fd75f5
4
- data.tar.gz: 6b4b0b8ffaf462a4f7ae9e7601276b40cf722860ecd3bfb1270a5734bbb6211d
3
+ metadata.gz: 473cc11423d57b9b40b361184587b1acdda0d14751b12266740eb98e1f1c7caa
4
+ data.tar.gz: 542e14fb88a4d40c34209853678e80fc0d2bddc90745aa9bd6eaee666e7fcf03
5
5
  SHA512:
6
- metadata.gz: fce5856e48f7d73ff31aac4c26fb2d7c0c235f0c36ab8a6fda65e79b7696f48f35faff221d5e97de4bfd8183d704c76ce11b3534b311fcf6697580c88cfeba0d
7
- data.tar.gz: 90c49135edaabb0d3e4f9abcb63880df81279159198429e803abcb96ac606a8ba908d4392375c52cda82ada9bcf95805d920b3e8a3d066525923daed3885c702
6
+ metadata.gz: 90fe0e391b0aa2eb12f1564153905db9fd294aa2817094da62dc1a7da7c3c663f7f94f99996d5f3c1e7818f1d8d214d2c1286fdefbe9eedfb932c3abdf224586
7
+ data.tar.gz: 24e26ab924509fbc0df1d03a67c59ec5d62d544a8cc0709f757012c2dcb6fd8915a049ad82ccec49316f19b4cdb65c1bac9f4c62e3a1c4231f5de7c316bbcbc1
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- swarm_cluster_cli_ope (0.1.6)
4
+ swarm_cluster_cli_ope (0.2)
5
5
  activesupport
6
6
  open4
7
7
  thor (~> 1.0)
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/docker_compose.yml test1
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 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).
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
- puts JSON.pretty_generate(cfgs.class.merged_configurations)
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, default: cfgs.stack_name
62
+ option :stack_name, required: false, type: :string
58
63
 
59
64
  def services
60
- Models::Service.all(stack_name: options[:stack_name]).each do |s|
61
- puts s.name
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, default: cfgs.stack_name
74
+ option :stack_name, required: false, type: :string
67
75
 
68
76
  def mc(service_name)
69
-
70
- # Disabilito output della libreria
71
- MakeMakefile::Logging.instance_variable_set(:@logfile, File::NULL)
72
- unless find_executable 'mc'
73
- puts "Non hai installato MC"
74
- exit 0
75
- end
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
- puts "Creazione container #{shell_operation.string_command}"
94
- id_container = shell_operation.execute.raw_result[:stdout]
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
- if id_container
122
- # cancello container
123
- # docker stop #{id_container}
124
- puts "Spengo container di appoggio"
125
- puts "docker stop #{id_container}"
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
- stop_ssh_container = cmd.command do |c|
129
- c.add("stop #{id_container}")
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, default: cfgs.stack_name
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
- #identifico quale dei due è il servizio e quale la path
148
- if src.match(/^(.*)\:/)
149
- container = Models::Container.find_by_service_name(Regexp.last_match[1], stack_name: options[:stack_name])
150
- ris = container.copy_out(src.match(/\:(.*)$/)[1], dest)
151
- else
152
- container = Models::Container.find_by_service_name(dest.match(/^(.*)\:/)[1], stack_name: options[:stack_name])
153
- ris = container.copy_in(src, dest.match(/\:(.*)$/)[1])
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.stack_name = stack_name
163
- cfgs.save_project_cfgs
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, default: cfgs.stack_name
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
- container = Models::Container.find_by_service_name(service_name, stack_name: options[:stack_name])
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
- cmd = container.docker_command
174
- cmd.base_suffix_command = ''
175
- shell_operation = cmd.command do |c|
176
- c.add("exec -it #{container.id} #{options[:shell]}")
177
- end
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
- say "Stai entrando della shell in #{options[:shell]} del container #{options[:stack_name]}->#{container.name}[#{container.id}]"
180
- system(shell_operation.string_command)
181
- say "Shell chiusa"
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, default: cfgs.stack_name
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, default: cfgs.stack_name
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
- private
211
-
212
- def rsync_binded(direction: :down, options: {})
213
-
214
- # trovo il container del servizio
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
- # trovo la cartella bindata e la relativa cartella sul nodo
224
- volume = container.mapped_volumes.find { |v| v.destination == options[:binded_container_folders] and v.is_binded? }
225
- if volume.nil?
226
- say "Non ho trovato il volume bindato con questa destinazione all'interno del container #{options[:binded_container_folders]}"
227
- exit 0
228
- end
229
-
230
- #costruisco il comando rsync fra cartella del nodo e cartella sul pc
231
- cmd = ["rsync", "-zr", "--delete"]
232
- if direction == :down
233
- cmd << "#{volume.ssh_connection_path}/."
234
- # creo la cartella in locale se non esiste
235
- FileUtils.mkdir_p(options[:local_folder])
236
- cmd << options[:local_folder]
237
- end
238
- if direction == :up
239
- cmd << "#{options[:local_folder]}/."
240
- cmd << volume.ssh_connection_path
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
- return @_nodes if @_nodes
52
- @_nodes = self.class.merged_configurations[:connections_maps].collect { |m, c| Node.new(name: m.to_s, connection_uri: c) }
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
- @_nodes = objs
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 = self.class.merged_configurations[:stack_name] if self.class.merged_configurations.key?(: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
- self.class.merged_configurations[:log_level].to_s || "0"
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
- self.class.merged_configurations.key?(:dev_mode)
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 @stack_name
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
- def self.cfgs_project_file_name
145
- '.swarm_cluster_project'
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.class.merged_configurations.to_json)
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 self.merged_configurations
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(folder, cfgs_project_file_name))
176
- project_file = File.join(folder, cfgs_project_file_name)
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 folder == '/'
181
- folder = File.expand_path("..", folder)
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
- @_merged_configurations = read_base.merge(project_cfgs)
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
@@ -0,0 +1,8 @@
1
+ module SwarmClusterCliOpe
2
+ module SyncConfigs
3
+ class Sqlite3 < Copy
4
+
5
+
6
+ end
7
+ end
8
+ end
@@ -1,3 +1,3 @@
1
1
  module SwarmClusterCliOpe
2
- VERSION = "0.1.6"
2
+ VERSION = "0.2"
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.1.6
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-05-12 00:00:00.000000000 Z
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.6
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