swarm_cluster_cli_ope 0.1.2 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '09565df25f695d7e64c5034d7daaa833ba640c61b2b326ad046601355f13f705'
4
- data.tar.gz: c997f3969018ae3335e86987595b7c5e1bba6792477c6c343f27e291a1430f47
3
+ metadata.gz: 473cc11423d57b9b40b361184587b1acdda0d14751b12266740eb98e1f1c7caa
4
+ data.tar.gz: 542e14fb88a4d40c34209853678e80fc0d2bddc90745aa9bd6eaee666e7fcf03
5
5
  SHA512:
6
- metadata.gz: b1f2e55552084f16fd1b0f2bc9955113771212b52d5f9d508aac86a578e0bf1d95f2a513fa9b171e31cb7016d9899002331957d38fdc1e71afa0c1a677f95b59
7
- data.tar.gz: a0daa2f6d6b4187d038eea485d65c88d5aa670760f99935d8115e4c8cccf6196f991b7e8f71a17881a44117f40a7d60cdde94a7d91707dc7eb154fb9ad70d4c1
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.2)
4
+ swarm_cluster_cli_ope (0.2)
5
5
  activesupport
6
6
  open4
7
7
  thor (~> 1.0)
@@ -10,12 +10,12 @@ PATH
10
10
  GEM
11
11
  remote: https://rubygems.org/
12
12
  specs:
13
- activesupport (6.0.2.2)
13
+ activesupport (6.0.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
- zeitwerk (~> 2.2)
18
+ zeitwerk (~> 2.2, >= 2.2.2)
19
19
  concurrent-ruby (1.1.6)
20
20
  i18n (1.8.2)
21
21
  concurrent-ruby (~> 1.0)
data/README.md CHANGED
@@ -22,7 +22,7 @@ Or install it yourself as:
22
22
 
23
23
  Una volta installato lanciare il comando
24
24
 
25
- ```swarm_cluster_cli_ope install``` che si occuperà di configurare le varie impostazioni dell'ambiente
25
+ ```swarm_cli_ope install``` che si occuperà di configurare le varie impostazioni dell'ambiente
26
26
 
27
27
  FILE di configurazione base:
28
28
  ```json
@@ -36,9 +36,12 @@ 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
- quali stack_name
44
+ quali stack_name (.swarm_cluster_project)
42
45
  ```shell script
43
46
  swarm_cli_ope configure_project STACK_NAME
44
47
  ```
@@ -82,10 +85,6 @@ swarm_cli_ope services --stack-name=NOME_STACK
82
85
  ```shell script
83
86
  swarm_cli_ope cp --stack-name=NOME_STACK PATH_FILE_LOCALE NOME_SERVIZIO:DESTINAZIONE_NEL_CONTAINER
84
87
  ```
85
- ES:
86
- ```shell script
87
- swarm_cli_ope cp --stack-name=webapps-examinerapp-staging ./test_folder/test_1/cartella_bindata/test jeapp:/tmp/.
88
- ```
89
88
 
90
89
  ### Rsync da/a container a/da locale
91
90
 
@@ -96,23 +95,20 @@ Utilizzare `rsync_binded_from` per scaricare e `rsync_binded_to` per caricare
96
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
97
96
  ```
98
97
 
99
- ES:
100
- ```shell script
101
- swarm_cli_ope rsync_binded_from --stack-name=web-site-ranchilbosco-production --service_name wordpress --binded-container-folders /var/www/html/wp-content/uploads --destination ./uploads
102
- ```
103
-
104
-
105
98
  ## Development
106
99
 
107
100
  nel file di configurazione creato nella home aggiungere la chiave "dev_mode":1 per collegarsi localmente
108
101
 
109
102
  ### Abbiamo due tasks swarm di simulazione
110
103
  ```shell script
111
- 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
112
106
  docker stack deploy -c test_folder/test_2/docker_compose.yml test2
113
107
  ```
114
108
 
115
- 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).
116
112
 
117
113
 
118
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
@@ -19,6 +22,7 @@ module SwarmClusterCliOpe
19
22
  say "Configurazione già presente"
20
23
  else
21
24
  #se non presente allora chiediamo le varie configurazioni
25
+ say "Ricordarsi di poter raggiungere i server che verranno inseriti"
22
26
  lista = []
23
27
  loop do
24
28
  connection_name = ask("Aggiungi un server alla lista dei server Manager(inserire uri: ssh://server | unix:///socket/path:")
@@ -26,7 +30,7 @@ module SwarmClusterCliOpe
26
30
  node = Node.new(name: result.Name, connection_uri: connection_name)
27
31
  say "Aggiungo #{node.name} che si connette con DOCKER_HOST=#{node.connection_uri}"
28
32
  lista << node
29
- break if no? "Vuoi inserire al server?[n,no]"
33
+ break if no? "Vuoi inserire altri server?[n,no]"
30
34
  end
31
35
  #scriviamo le varie configurazioni
32
36
  cfg = cfgs
@@ -36,10 +40,12 @@ module SwarmClusterCliOpe
36
40
 
37
41
  end
38
42
 
39
- desc "config", "Visualizza le configurazioni mergiate (HOME + Project)"
43
+ desc "config", "Visualizza le configurazioni mergiate (HOME + Project configuration[#{Configuration.cfgs_project_file_name}])"
40
44
 
41
45
  def config
42
- puts JSON.pretty_generate(cfgs.class.merged_configurations)
46
+ cfgs.env(options[:environment]) do
47
+ puts JSON.pretty_generate(cfgs.merged_configurations)
48
+ end
43
49
  end
44
50
 
45
51
 
@@ -53,88 +59,93 @@ module SwarmClusterCliOpe
53
59
  end
54
60
 
55
61
  desc "services", "lista dei servizi per uno stack"
56
- option :stack_name, required: false, type: :string, default: cfgs.stack_name
62
+ option :stack_name, required: false, type: :string
57
63
 
58
64
  def services
59
- Models::Service.all(stack_name: options[:stack_name]).each do |s|
60
- 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
61
70
  end
62
71
  end
63
72
 
64
73
  desc "mc SERVICE_NAME", "Apre MC tra la cartella attuale e il container (potrebbe dar luogo a degli errori, ma funziona)"
65
- option :stack_name, required: false, type: :string, default: cfgs.stack_name
74
+ option :stack_name, required: false, type: :string
66
75
 
67
76
  def mc(service_name)
68
-
69
- # Disabilito output della libreria
70
- MakeMakefile::Logging.instance_variable_set(:@logfile, File::NULL)
71
- unless find_executable 'mc'
72
- puts "Non hai installato MC"
73
- exit 0
74
- end
75
-
76
- begin
77
- container = Models::Container.find_by_service_name(service_name, stack_name: options[:stack_name])
78
-
79
- server = container.node.hostname
80
-
81
- # Creo container ssh
82
- # DOCKER_HOST=ssh://swarm_node_1 docker run --rm -d -p 12222:22 \
83
- # --volumes-from sistemi-test_swarm_cluster_cli_wordpress.1.zbbz1xxh4vzzccndvs973jnuc \
84
- # sickp/alpine-sshd:7.5
85
- #
86
- cmd = container.docker_command
87
- cmd.base_suffix_command = ''
88
- shell_operation = cmd.command do |c|
89
- 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
90
84
  end
91
85
 
92
- puts "Creazione container #{shell_operation.string_command}"
93
- id_container = shell_operation.execute.raw_result[:stdout]
94
- puts "Container generato con id:#{id_container}"
95
-
96
- # eseguo tunnel verso nodo e container ssh
97
- socket_ssh_path = "/tmp/socket_ssh_#{id_container}"
98
- # ssh -f -N -T -M -S <path-to-socket> -L 13333:0.0.0.0:42222 <server>
99
- cmd_tunnel = ["ssh", "-f -N -T -M", "-S #{socket_ssh_path}", "-L 13333:0.0.0.0:42222", server].join(" ")
100
- puts "Apro tunnel"
101
- puts cmd_tunnel
102
- system(cmd_tunnel)
103
-
104
- # apro MC
105
- # mc . sftp://root:root@0.0.0.0:13333
106
- mc_cmd = "mc . sftp://root:root@0.0.0.0:13333"
107
- puts "Apro MC"
108
- puts mc_cmd
109
- system(mc_cmd)
110
- ensure
111
- if socket_ssh_path
112
- # chiudo tunnel
113
- # ssh -S <path-to-socket> -O exit <server>
114
- close_tunnel_cmd = "ssh -S #{socket_ssh_path} -O exit #{server}"
115
- puts "Chiudo tunnel"
116
- # say close_tunnel_cmd
117
- ShellCommandExecution.new(close_tunnel_cmd).execute
118
- end
86
+ begin
87
+ container = Models::Container.find_by_service_name(service_name, stack_name: stack_name)
119
88
 
120
- if id_container
121
- # cancello container
122
- # docker stop #{id_container}
123
- puts "Spengo container di appoggio"
124
- 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
+ #
125
96
  cmd = container.docker_command
126
97
  cmd.base_suffix_command = ''
127
- stop_ssh_container = cmd.command do |c|
128
- 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
129
128
  end
130
- stop_ssh_container.execute
131
- end
132
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
133
144
  end
134
145
  end
135
146
 
136
147
  desc "cp SRC DEST", "Copia la sorgente in destinazione"
137
- option :stack_name, required: false, type: :string, default: cfgs.stack_name
148
+ option :stack_name, required: false, type: :string
138
149
  long_desc <<-LONGDESC
139
150
  SRC e DEST possono essere un servizio, solo uno di essi può essere un servizio (TODO)
140
151
  Per identificare che sia un servizio controllo se nella stringa è presete il :
@@ -143,49 +154,76 @@ module SwarmClusterCliOpe
143
154
  LONGDESC
144
155
 
145
156
  def cp(src, dest)
146
- #identifico quale dei due è il servizio e quale la path
147
- if src.match(/^(.*)\:/)
148
- container = Models::Container.find_by_service_name(Regexp.last_match[1], stack_name: options[:stack_name])
149
- ris = container.copy_out(src.match(/\:(.*)$/)[1], dest)
150
- else
151
- container = Models::Container.find_by_service_name(dest.match(/^(.*)\:/)[1], stack_name: options[:stack_name])
152
- 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
+
153
186
  end
154
- puts "COMPLETATO" if ris
155
187
  end
156
188
 
157
189
 
158
190
  desc "configure_project STACK_NAME", "Genera il file di configurazione del progetto contenente il nome dello stack"
159
191
 
160
192
  def configure_project(stack_name)
161
- cfgs.stack_name = stack_name
162
- cfgs.save_project_cfgs
193
+ cfgs.env(options[:environment]) do |c|
194
+ c.stack_name = stack_name
195
+ c.save_project_cfgs
196
+ end
163
197
  end
164
198
 
199
+
165
200
  desc "service_shell SERVICE_NAME", "apre una shell [default bash] dentro al container"
166
- option :stack_name, required: false, type: :string, default: cfgs.stack_name
201
+ option :stack_name, required: false, type: :string
167
202
  option :shell, required: false, type: :string, default: 'bash'
168
203
 
169
204
  def service_shell(service_name)
170
- 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)
171
208
 
172
- cmd = container.docker_command
173
- cmd.base_suffix_command = ''
174
- shell_operation = cmd.command do |c|
175
- c.add("exec -it #{container.id} #{options[:shell]}")
176
- 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
177
214
 
178
- say "Stai entrando della shell in #{options[:shell]} del container #{options[:stack_name]}->#{container.name}[#{container.id}]"
179
- system(shell_operation.string_command)
180
- 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
181
219
  end
182
220
 
183
221
 
184
222
  desc "rsync_binded_from", "esegue un rsync dalla cartella bindata (viene sincronizzato il contenuto)"
185
- option :stack_name, required: false, type: :string, default: cfgs.stack_name
223
+ option :stack_name, required: false, type: :string
186
224
  option :service_name, required: true, type: :string
187
225
  option :binded_container_folders, required: true, type: :string, desc: "path della cartella bindata all'interno del container da sincronizzare"
188
- option :local_folder, required: false, type: :string, desc: "path della cartella dove sincronizzare il comando"
226
+ option :local_folder, required: true, type: :string, desc: "path della cartella dove sincronizzare il comando"
189
227
 
190
228
  def rsync_binded_from
191
229
  if yes? "Attenzione, i dati locali verranno sovrascritti/cancellati?[y,yes]"
@@ -194,10 +232,10 @@ module SwarmClusterCliOpe
194
232
  end
195
233
 
196
234
  desc "rsync_binded_to", "esegue un rsync verso la cartella bindata"
197
- option :stack_name, required: false, type: :string, default: cfgs.stack_name
235
+ option :stack_name, required: false, type: :string
198
236
  option :service_name, required: true, type: :string
199
237
  option :binded_container_folders, required: true, type: :string, desc: "path della cartella bindata all'interno del container da sincronizzare"
200
- option :local_folder, required: false, type: :string, desc: "path della cartella dove sincronizzare il comando"
238
+ option :local_folder, required: true, type: :string, desc: "path della cartella dove sincronizzare il comando"
201
239
 
202
240
  def rsync_binded_to
203
241
  if yes? "ATTENZIONE, i dati remoti verranno sovrascritti/cancellati da quelli locali?[y,yes]"
@@ -205,46 +243,54 @@ module SwarmClusterCliOpe
205
243
  end
206
244
  end
207
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
208
263
 
209
- private
210
-
211
- def rsync_binded(direction: :down, options: {})
212
-
213
- # trovo il container del servizio
214
- container = Models::Container.find_by_service_name(options[:service_name], stack_name: options[:stack_name])
215
-
216
- if container.nil?
217
- say "Container non trovato con #{options[:stack_name]}@##{options[:service_name]}"
218
- 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
219
269
  end
270
+ end
220
271
 
272
+ private
221
273
 
222
- # trovo la cartella bindata e la relativa cartella sul nodo
223
- volume = container.mapped_volumes.find { |v| v.destination == options[:binded_container_folders] and v.is_binded? }
224
- if volume.nil?
225
- say "Non ho trovato il volume bindato con questa destinazione all'interno del container #{options[:binded_container_folders]}"
226
- exit 0
227
- end
228
-
229
- #costruisco il comando rsync fra cartella del nodo e cartella sul pc
230
- cmd = ["rsync", "-zr", "--delete"]
231
- if direction == :down
232
- cmd << "#{volume.ssh_connection_path}/."
233
- # creo la cartella in locale se non esiste
234
- FileUtils.mkdir_p(options[:local_folder])
235
- cmd << options[:local_folder]
236
- end
237
- if direction == :up
238
- cmd << "#{options[:local_folder]}/."
239
- cmd << volume.ssh_connection_path
240
- 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
241
292
 
242
- cmd = ShellCommandExecution.new(cmd)
243
293
 
244
- say "Comando da eseguire:"
245
- say " #{cmd.string_command}"
246
- if yes?("Confermare il comando?[y,yes]")
247
- cmd.execute
248
294
  end
249
295
  end
250
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,35 @@ 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"
104
+ rescue SwarmClusterCliOpe::Configuration::NoBaseConfigurations
105
+ # quando andiamo in errore durante l'installazione per avere le informazioni per il logger.
106
+ # Usiamo lo standard
107
+ "0"
77
108
  end
78
109
 
79
110
  ##
@@ -81,7 +112,7 @@ module SwarmClusterCliOpe
81
112
  # @return [TrueClass, FalseClass]
82
113
  def development_mode?
83
114
  return false unless self.class.exist_base?
84
- self.class.merged_configurations.key?(:dev_mode)
115
+ merged_configurations.key?(:dev_mode)
85
116
  end
86
117
 
87
118
  ##
@@ -106,8 +137,8 @@ module SwarmClusterCliOpe
106
137
  ##
107
138
  # Si occupa del salvataggio delle configurazioni di progetto, se abbiamo lo stack_name
108
139
  def save_project_cfgs
109
- if @stack_name
110
- 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|
111
142
  f.write({
112
143
  stack_name: stack_name
113
144
  }.to_json)
@@ -132,13 +163,31 @@ module SwarmClusterCliOpe
132
163
  nodes.find { |c| c.id == node_id }
133
164
  end
134
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
+
135
183
  private
136
184
 
137
185
  ##
138
186
  # nome del file in cui salvare le configurazioni di progetto
139
187
  # @return [String]
140
- def self.cfgs_project_file_name
141
- '.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}" : ""}"
142
191
  end
143
192
 
144
193
  ##
@@ -146,7 +195,7 @@ module SwarmClusterCliOpe
146
195
  # quindi ogni ora si autoripulisce e con un md5 delle configurazioni di base
147
196
  # @return [String]
148
197
  def swarm_manager_cache_path
149
- md5 = Digest::MD5.hexdigest(self.class.merged_configurations.to_json)
198
+ md5 = Digest::MD5.hexdigest(self.merged_configurations.to_json)
150
199
  file_name = Time.now.strftime(".swarm_cluster_cli_manager_cache-%Y%m%d%H-#{md5}")
151
200
  File.join("/tmp", file_name)
152
201
  end
@@ -160,29 +209,51 @@ module SwarmClusterCliOpe
160
209
  JSON.parse(File.read(self.base_cfg_path)).deep_symbolize_keys
161
210
  end
162
211
 
212
+ public
213
+
163
214
  ## Cerca le configurazioni di progetto e le mergia se sono presenti
164
215
  # @return [Hash]
165
- def self.merged_configurations
166
- 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)
167
244
  project_file = nil
168
- folder = FileUtils.pwd
169
245
  loop do
170
246
 
171
- if File.exist?(File.join(folder, cfgs_project_file_name))
172
- 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)
173
249
  end
174
250
 
175
251
  break unless project_file.nil?
176
- break if folder == '/'
177
- folder = File.expand_path("..", folder)
178
- end
179
-
180
- project_cfgs = {}
181
- unless project_file.nil?
182
- project_cfgs = JSON.parse(File.read(project_file)).deep_symbolize_keys
252
+ break if start_folder == '/'
253
+ start_folder = File.expand_path("..", start_folder)
183
254
  end
184
255
 
185
- @_merged_configurations = read_base.merge(project_cfgs)
256
+ project_file
186
257
  end
187
258
 
188
259
  end
@@ -50,8 +50,7 @@ module SwarmClusterCliOpe
50
50
  # @return [OpenStruct]
51
51
  def info
52
52
  # path al file di cache
53
- # TODO sarebbe da aggiornare ogni tanto, metti che uno non spegne mai il pc
54
- path = "/tmp/.swarm_cluster_cli_info_cache_#{name}"
53
+ path = Time.now.strftime("/tmp/.swarm_cluster_cli_info_cache_#{name}-%Y%m%d%H")
55
54
  if File.exist?(path)
56
55
  i = JSON.parse(File.read(path), object_class: OpenStruct)
57
56
  else
@@ -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.2"
2
+ VERSION = "0.2"
3
3
  end
@@ -10,15 +10,15 @@ Gem::Specification.new do |spec|
10
10
  spec.description = "Gestione di varie operazioni come sincronia con le cartelle bindate dei container (rsync) up o
11
11
  down e possibilità di scaricare/caricare i file direttamente all'interno del cluster, in
12
12
  modo facilitato"
13
- spec.homepage = "https://gitlab.archimedianet.it/sistemi/swarm_cluster_cli_ope"
13
+ spec.homepage = "https://github.com/ArchimediaZerogroup/swarm_cluster_cli_ope"
14
14
  spec.license = "MIT"
15
15
  spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
16
16
 
17
17
  spec.metadata["allowed_push_host"] = 'https://rubygems.org/'
18
18
 
19
19
  spec.metadata["homepage_uri"] = spec.homepage
20
- # spec.metadata["source_code_uri"] = "TODO: Put your gem's public repo URL here."
21
- # spec.metadata["changelog_uri"] = "TODO: Put your gem's CHANGELOG.md URL here."
20
+ spec.metadata["source_code_uri"] = "https://github.com/ArchimediaZerogroup/swarm_cluster_cli_ope"
21
+ spec.metadata["changelog_uri"] = "https://github.com/ArchimediaZerogroup/swarm_cluster_cli_ope/blob/master/CHANGELOG.md"
22
22
 
23
23
  # Specify which files should be added to the gem when it is released.
24
24
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
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.2
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-05 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,15 +107,21 @@ 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
113
- homepage: https://gitlab.archimedianet.it/sistemi/swarm_cluster_cli_ope
117
+ homepage: https://github.com/ArchimediaZerogroup/swarm_cluster_cli_ope
114
118
  licenses:
115
119
  - MIT
116
120
  metadata:
117
121
  allowed_push_host: https://rubygems.org/
118
- homepage_uri: https://gitlab.archimedianet.it/sistemi/swarm_cluster_cli_ope
122
+ homepage_uri: https://github.com/ArchimediaZerogroup/swarm_cluster_cli_ope
123
+ source_code_uri: https://github.com/ArchimediaZerogroup/swarm_cluster_cli_ope
124
+ changelog_uri: https://github.com/ArchimediaZerogroup/swarm_cluster_cli_ope/blob/master/CHANGELOG.md
119
125
  post_install_message:
120
126
  rdoc_options: []
121
127
  require_paths:
@@ -131,7 +137,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
131
137
  - !ruby/object:Gem::Version
132
138
  version: '0'
133
139
  requirements: []
134
- rubygems_version: 3.0.6
140
+ rubygems_version: 3.0.8
135
141
  signing_key:
136
142
  specification_version: 4
137
143
  summary: WIP Gemma per la gestione del cluster swarm