swarm_cluster_cli_ope 0.1.2 → 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: '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