swarm_cluster_cli_ope 0.3.1 → 0.5.0.pre.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +46 -2
- data/README.md +27 -4
- data/lib/swarm_cluster_cli_ope/cli.rb +44 -11
- data/lib/swarm_cluster_cli_ope/configuration.rb +12 -2
- data/lib/swarm_cluster_cli_ope/k8s.rb +114 -0
- data/lib/swarm_cluster_cli_ope/k8s_rsync/password +1 -0
- data/lib/swarm_cluster_cli_ope/k8s_rsync/rsyncd.conf +14 -0
- data/lib/swarm_cluster_cli_ope/k8s_rsync/rsyncd.secrets +1 -0
- data/lib/swarm_cluster_cli_ope/shell_command_execution.rb +1 -1
- data/lib/swarm_cluster_cli_ope/sync_configs/base_database.rb +51 -0
- data/lib/swarm_cluster_cli_ope/sync_configs/env_configs.rb +4 -3
- data/lib/swarm_cluster_cli_ope/sync_configs/mysql.rb +9 -43
- data/lib/swarm_cluster_cli_ope/sync_configs/post_gres.rb +159 -0
- data/lib/swarm_cluster_cli_ope/version.rb +1 -1
- metadata +10 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 26f02b47b55fab368037fbf3d391666784ad5db6d4427a3265a1ca09a21b5961
|
4
|
+
data.tar.gz: f496d6f56870aa9e61a40b8ae195b3925c4482b81f60d1023d2db2cafb3bd838
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 00a4f6ff88d19d303c978b34c9cc8483639a3deba3f9fd36767f87486ec314c0b0c29a554ce5cc5f7369b4a0d736ab8b2b72a37698210e78d167bc065f0252b6
|
7
|
+
data.tar.gz: 195f8d4ba4bdbc948f235aa3d0b61bf6e48f9e7f210c37ce72e7eb8fc2d8bd4722a98624626e7b1f7d10ce18ab8b2918253173a15c0ce76d3c3a278c1c5f9eac
|
data/CHANGELOG.md
CHANGED
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
swarm_cluster_cli_ope (0.
|
4
|
+
swarm_cluster_cli_ope (0.5.0.pre.1)
|
5
5
|
activesupport
|
6
6
|
open4
|
7
7
|
thor (~> 1.0)
|
@@ -10,28 +10,72 @@ PATH
|
|
10
10
|
GEM
|
11
11
|
remote: https://rubygems.org/
|
12
12
|
specs:
|
13
|
-
activesupport (6.0.3.
|
13
|
+
activesupport (6.0.3.3)
|
14
14
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
15
15
|
i18n (>= 0.7, < 2)
|
16
16
|
minitest (~> 5.1)
|
17
17
|
tzinfo (~> 1.1)
|
18
18
|
zeitwerk (~> 2.2, >= 2.2.2)
|
19
|
+
addressable (2.7.0)
|
20
|
+
public_suffix (>= 2.0.2, < 5.0)
|
19
21
|
concurrent-ruby (1.1.7)
|
22
|
+
domain_name (0.5.20190701)
|
23
|
+
unf (>= 0.0.5, < 1.0.0)
|
24
|
+
ffi (1.13.1)
|
25
|
+
ffi-compiler (1.0.1)
|
26
|
+
ffi (>= 1.0.0)
|
27
|
+
rake
|
28
|
+
http (4.4.1)
|
29
|
+
addressable (~> 2.3)
|
30
|
+
http-cookie (~> 1.0)
|
31
|
+
http-form_data (~> 2.2)
|
32
|
+
http-parser (~> 1.2.0)
|
33
|
+
http-accept (1.7.0)
|
34
|
+
http-cookie (1.0.3)
|
35
|
+
domain_name (~> 0.5)
|
36
|
+
http-form_data (2.3.0)
|
37
|
+
http-parser (1.2.1)
|
38
|
+
ffi-compiler (>= 1.0, < 2.0)
|
20
39
|
i18n (1.8.5)
|
21
40
|
concurrent-ruby (~> 1.0)
|
41
|
+
jsonpath (1.0.5)
|
42
|
+
multi_json
|
43
|
+
to_regexp (~> 0.2.1)
|
44
|
+
kubeclient (4.9.1)
|
45
|
+
http (>= 3.0, < 5.0)
|
46
|
+
jsonpath (~> 1.0)
|
47
|
+
recursive-open-struct (~> 1.1, >= 1.1.1)
|
48
|
+
rest-client (~> 2.0)
|
49
|
+
mime-types (3.3.1)
|
50
|
+
mime-types-data (~> 3.2015)
|
51
|
+
mime-types-data (3.2020.1104)
|
22
52
|
minitest (5.14.2)
|
53
|
+
multi_json (1.15.0)
|
54
|
+
netrc (0.11.0)
|
23
55
|
open4 (1.3.4)
|
56
|
+
public_suffix (4.0.6)
|
24
57
|
rake (12.3.3)
|
58
|
+
recursive-open-struct (1.1.3)
|
59
|
+
rest-client (2.1.0)
|
60
|
+
http-accept (>= 1.7.0, < 2.0)
|
61
|
+
http-cookie (>= 1.0.2, < 2.0)
|
62
|
+
mime-types (>= 1.16, < 4.0)
|
63
|
+
netrc (~> 0.8)
|
25
64
|
thor (1.0.1)
|
26
65
|
thread_safe (0.3.6)
|
66
|
+
to_regexp (0.2.1)
|
27
67
|
tzinfo (1.2.7)
|
28
68
|
thread_safe (~> 0.1)
|
69
|
+
unf (0.1.4)
|
70
|
+
unf_ext
|
71
|
+
unf_ext (0.0.7.7)
|
29
72
|
zeitwerk (2.4.0)
|
30
73
|
|
31
74
|
PLATFORMS
|
32
75
|
ruby
|
33
76
|
|
34
77
|
DEPENDENCIES
|
78
|
+
kubeclient
|
35
79
|
rake (~> 12.0)
|
36
80
|
swarm_cluster_cli_ope!
|
37
81
|
|
data/README.md
CHANGED
@@ -130,13 +130,36 @@ Possibili CFGS per tipologia:
|
|
130
130
|
- local: -> hash di configurazioni per il DB locale
|
131
131
|
- service: "db" -> nome del servizio nel compose locale, DEFAULT: quello definito sopra
|
132
132
|
- mysql_password_env: "MYSQL_PASSWORD" -> variabile ambiente interna al servizio contenente PASSWORD, DEFAULT: MYSQL_PASSWORD
|
133
|
+
- mysql_password: "root" -> valore in chiaro, in sostituzione della variabile ambiente, DEFAULT: root
|
133
134
|
- mysql_user_env: "MYSQL_USER" -> variabile ambiente interna al servizio contenente USERNAME, DEFAULT: MYSQL_USER
|
135
|
+
- mysql_user: "root" -> valore in chiaro, in sostituzione della variabile ambiente, DEFAULT: root
|
136
|
+
- database_name_env: "MYSQL_DATABASE" -> variabile ambiente interna al servizio contenente NOME DB, DEFAULT: MYSQL_DATABASE
|
137
|
+
- database_name: "nome_db" -> valore in chiaro, in sostituzione della variabile ambiente
|
138
|
+
- remote: -> hash di configurazioni per il DB remoto
|
139
|
+
- service: "db" -> nome del servizio nel compose locale, DEFAULT: quello definito sopra
|
140
|
+
- mysql_password_env: "MYSQL_PASSWORD" -> variabile ambiente interna al servizio contenente PASSWORD, DEFAULT: MYSQL_PASSWORD
|
141
|
+
- mysql_password: "root" -> valore in chiaro, in sostituzione della variabile ambiente, DEFAULT: root
|
142
|
+
- mysql_user_env: "MYSQL_USER" -> variabile ambiente interna al servizio contenente USERNAME, DEFAULT: MYSQL_USER
|
143
|
+
- mysql_user: "root" -> valore in chiaro, in sostituzione della variabile ambiente, DEFAULT: root
|
134
144
|
- database_name_env: "MYSQL_DATABASE" -> variabile ambiente interna al servizio contenente NOME DB, DEFAULT: MYSQL_DATABASE
|
145
|
+
- database_name: "MYSQL_DATABASE" -> valore in chiaro, in sostituzione della variabile ambiente
|
146
|
+
- pg:
|
147
|
+
- local: -> hash di configurazioni per il DB locale
|
148
|
+
- service: "db" -> nome del servizio nel compose locale, DEFAULT: quello definito sopra
|
149
|
+
- pg_password_env: "POSTGRES_USER" -> variabile ambiente interna al servizio contenente PASSWORD, DEFAULT: POSTGRES_PASSWORD
|
150
|
+
- pg_password: "" -> valore in chiaro, in sostituzione della variabile ambiente
|
151
|
+
- pg_user_env: "POSTGRES_USER" -> variabile ambiente interna al servizio contenente USERNAME, DEFAULT: POSTGRES_USER
|
152
|
+
- pg_user: "postgres" -> valore in chiaro, in sostituzione della variabile ambiente, DEFAULT: postgres
|
153
|
+
- database_name_env: "POSTGRES_DB" -> variabile ambiente interna al servizio contenente NOME DB, DEFAULT: POSTGRES_DB
|
154
|
+
- database_name: "nome_db" -> valore in chiaro, in sostituzione della variabile ambiente
|
135
155
|
- remote: -> hash di configurazioni per il DB remoto
|
136
156
|
- service: "db" -> nome del servizio nel compose locale, DEFAULT: quello definito sopra
|
137
|
-
-
|
138
|
-
-
|
139
|
-
-
|
157
|
+
- pg_password_env: "POSTGRES_USER" -> variabile ambiente interna al servizio contenente PASSWORD, DEFAULT: POSTGRES_PASSWORD
|
158
|
+
- pg_password: "" -> valore in chiaro, in sostituzione della variabile ambiente
|
159
|
+
- pg_user_env: "POSTGRES_USER" -> variabile ambiente interna al servizio contenente USERNAME, DEFAULT: POSTGRES_USER
|
160
|
+
- pg_user: "postgres" -> valore in chiaro, in sostituzione della variabile ambiente, DEFAULT: postgres
|
161
|
+
- database_name_env: "POSTGRES_DB" -> variabile ambiente interna al servizio contenente NOME DB, DEFAULT: POSTGRES_DB
|
162
|
+
- database_name: "nome_db" -> valore in chiaro, in sostituzione della variabile ambiente
|
140
163
|
|
141
164
|
#### EXAMPLE:
|
142
165
|
Esempio di sincronizzazione di un file sqlite3 e una cartella
|
@@ -180,7 +203,7 @@ docker stack deploy -c test_folder/test_2/docker_compose.yml test2
|
|
180
203
|
Per simulare una sincronizzazione fra locale e remoto di un mysql, lanciamo lo stesso stack anche come compose, in modo
|
181
204
|
da trovarci sulla stessa macchina con tutte e due le situazioni
|
182
205
|
```shell script
|
183
|
-
docker-compose
|
206
|
+
docker-compose -f test_folder/test_1/docker-compose-local.yml up -d
|
184
207
|
```
|
185
208
|
|
186
209
|
|
@@ -14,6 +14,10 @@ module SwarmClusterCliOpe
|
|
14
14
|
class_option :environment, required: false, type: :string, aliases: [:e],
|
15
15
|
desc: "Esegue tutte le operazioni nell'env scelto, il file di configurazione dovrà avere il nome: #{Configuration.cfgs_project_file_name}.ENV"
|
16
16
|
|
17
|
+
|
18
|
+
desc "k8s SUBCOMMAND ...ARGS", "Gestisce un set di comandi specifici per K8s"
|
19
|
+
subcommand "k8s", K8s
|
20
|
+
|
17
21
|
desc "install", "Creazione della configurazione base della gemma"
|
18
22
|
|
19
23
|
def install
|
@@ -243,6 +247,11 @@ module SwarmClusterCliOpe
|
|
243
247
|
end
|
244
248
|
end
|
245
249
|
|
250
|
+
desc "version", "versione della cli"
|
251
|
+
def version
|
252
|
+
say VERSION
|
253
|
+
end
|
254
|
+
|
246
255
|
desc "stacksync [DIRECTION:pull|push]", "Si occupa di scaricare|caricare,utilizzando le configurazioni presenti, i dati dallo stack remoto"
|
247
256
|
long_desc <<-LONGDESC.gsub("\n", "\x5")
|
248
257
|
le configurazioni sono contenute nell'array: sync_configs.
|
@@ -270,17 +279,40 @@ module SwarmClusterCliOpe
|
|
270
279
|
--remote: -> path al file remoto (contesto del container)
|
271
280
|
|
272
281
|
mysql:
|
273
|
-
--
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
282
|
+
--local: -> hash di configurazioni per il DB locale
|
283
|
+
- service: "db" -> nome del servizio nel compose locale, DEFAULT: quello definito sopra
|
284
|
+
- mysql_password_env: "MYSQL_PASSWORD" -> variabile ambiente interna al servizio contenente PASSWORD, DEFAULT: MYSQL_PASSWORD
|
285
|
+
- mysql_password: "root" -> valore in chiaro, in sostituzione della variabile ambiente, DEFAULT: root
|
286
|
+
- mysql_user_env: "MYSQL_USER" -> variabile ambiente interna al servizio contenente USERNAME, DEFAULT: MYSQL_USER
|
287
|
+
- mysql_user: "root" -> valore in chiaro, in sostituzione della variabile ambiente, DEFAULT: root
|
288
|
+
- database_name_env: "MYSQL_DATABASE" -> variabile ambiente interna al servizio contenente NOME DB, DEFAULT: MYSQL_DATABASE
|
289
|
+
- database_name: "nome_db" -> valore in chiaro, in sostituzione della variabile ambiente
|
290
|
+
--remote: -> hash di configurazioni per il DB remoto
|
291
|
+
- service: "db" -> nome del servizio nel compose locale, DEFAULT: quello definito sopra
|
292
|
+
- mysql_password_env: "MYSQL_PASSWORD" -> variabile ambiente interna al servizio contenente PASSWORD, DEFAULT: MYSQL_PASSWORD
|
293
|
+
- mysql_password: "root" -> valore in chiaro, in sostituzione della variabile ambiente, DEFAULT: root
|
294
|
+
- mysql_user_env: "MYSQL_USER" -> variabile ambiente interna al servizio contenente USERNAME, DEFAULT: MYSQL_USER
|
295
|
+
- mysql_user: "root" -> valore in chiaro, in sostituzione della variabile ambiente, DEFAULT: root
|
296
|
+
- database_name_env: "MYSQL_DATABASE" -> variabile ambiente interna al servizio contenente NOME DB, DEFAULT: MYSQL_DATABASE
|
297
|
+
- database_name: "MYSQL_DATABASE" -> valore in chiaro, in sostituzione della variabile ambiente
|
298
|
+
pg:
|
299
|
+
--local: -> hash di configurazioni per il DB locale
|
300
|
+
- service: "db" -> nome del servizio nel compose locale, DEFAULT: quello definito sopra
|
301
|
+
- pg_password_env: "POSTGRES_USER" -> variabile ambiente interna al servizio contenente PASSWORD, DEFAULT: POSTGRES_PASSWORD
|
302
|
+
- pg_password: "" -> valore in chiaro, in sostituzione della variabile ambiente
|
303
|
+
- pg_user_env: "POSTGRES_USER" -> variabile ambiente interna al servizio contenente USERNAME, DEFAULT: POSTGRES_USER
|
304
|
+
- pg_user: "postgres" -> valore in chiaro, in sostituzione della variabile ambiente, DEFAULT: postgres
|
305
|
+
- database_name_env: "POSTGRES_DB" -> variabile ambiente interna al servizio contenente NOME DB, DEFAULT: POSTGRES_DB
|
306
|
+
- database_name: "nome_db" -> valore in chiaro, in sostituzione della variabile ambiente
|
307
|
+
--remote: -> hash di configurazioni per il DB remoto
|
308
|
+
- service: "db" -> nome del servizio nel compose locale, DEFAULT: quello definito sopra
|
309
|
+
- pg_password_env: "POSTGRES_USER" -> variabile ambiente interna al servizio contenente PASSWORD, DEFAULT: POSTGRES_PASSWORD
|
310
|
+
- pg_password: "" -> valore in chiaro, in sostituzione della variabile ambiente
|
311
|
+
- pg_user_env: "POSTGRES_USER" -> variabile ambiente interna al servizio contenente USERNAME, DEFAULT: POSTGRES_USER
|
312
|
+
- pg_user: "postgres" -> valore in chiaro, in sostituzione della variabile ambiente, DEFAULT: postgres
|
313
|
+
- database_name_env: "POSTGRES_DB" -> variabile ambiente interna al servizio contenente NOME DB, DEFAULT: POSTGRES_DB
|
314
|
+
- database_name: "nome_db" -> valore in chiaro, in sostituzione della variabile ambiente
|
315
|
+
|
284
316
|
|
285
317
|
EXAMPLE:
|
286
318
|
Esempio di sincronizzazione di un file sqlite3 e una cartella
|
@@ -325,6 +357,7 @@ module SwarmClusterCliOpe
|
|
325
357
|
say "----------->>>>>>"
|
326
358
|
say "[ #{sync.class.name} ]"
|
327
359
|
sync.send(direction)
|
360
|
+
say "COMPLETE"
|
328
361
|
say "<<<<<<-----------"
|
329
362
|
end
|
330
363
|
end
|
@@ -140,7 +140,8 @@ module SwarmClusterCliOpe
|
|
140
140
|
if stack_name
|
141
141
|
File.open(File.join(FileUtils.pwd, self.class.cfgs_project_file_name(with_env: @environment)), "wb") do |f|
|
142
142
|
f.write({
|
143
|
-
stack_name: stack_name
|
143
|
+
stack_name: stack_name,
|
144
|
+
version: VERSION
|
144
145
|
}.to_json)
|
145
146
|
end
|
146
147
|
end
|
@@ -169,7 +170,7 @@ module SwarmClusterCliOpe
|
|
169
170
|
# il docker-compose.yml file
|
170
171
|
# @return [String]
|
171
172
|
def local_compose_project_name
|
172
|
-
File.basename(FileUtils.pwd)
|
173
|
+
File.basename(FileUtils.pwd).downcase
|
173
174
|
end
|
174
175
|
|
175
176
|
##
|
@@ -187,6 +188,8 @@ module SwarmClusterCliOpe
|
|
187
188
|
SyncConfigs::Rsync.new(self, c)
|
188
189
|
when 'mysql'
|
189
190
|
SyncConfigs::Mysql.new(self, c)
|
191
|
+
when 'pg'
|
192
|
+
SyncConfigs::PostGres.new(self, c)
|
190
193
|
else
|
191
194
|
logger.error { "CONFIGURAIONE NON PREVISTA: #{c[:how]}" }
|
192
195
|
nil
|
@@ -248,6 +251,13 @@ module SwarmClusterCliOpe
|
|
248
251
|
hash[key] = self.class.read_base.merge(project_cfgs)
|
249
252
|
end
|
250
253
|
|
254
|
+
configuration_version = @_merged_configurations[@environment][:version]
|
255
|
+
if Gem::Version.new(configuration_version) > Gem::Version.new(VERSION)
|
256
|
+
puts "WARNING: Versione del file di configurazione [#{configuration_version}] più aggiornata della gemma [#{VERSION}], eseguire upgrade
|
257
|
+
gem update swarm_cluster_cli_ope"
|
258
|
+
exit
|
259
|
+
end
|
260
|
+
|
251
261
|
@_merged_configurations[@environment]
|
252
262
|
|
253
263
|
end
|
@@ -0,0 +1,114 @@
|
|
1
|
+
require 'kubeclient'
|
2
|
+
module SwarmClusterCliOpe
|
3
|
+
class K8s < Thor
|
4
|
+
include LoggerConcern
|
5
|
+
include ConfigurationConcern
|
6
|
+
include Thor::Actions
|
7
|
+
|
8
|
+
def self.exit_on_failure?
|
9
|
+
true
|
10
|
+
end
|
11
|
+
|
12
|
+
|
13
|
+
desc "rsync <src> <dst>", "esegue un rsync dalla cartella (viene sincronizzato il contenuto)"
|
14
|
+
|
15
|
+
|
16
|
+
def rsync(src, dst)
|
17
|
+
if yes? "Attenzione, i dati locali o remoti verranno sovrascritti/cancellati?[y,yes]"
|
18
|
+
|
19
|
+
reg_exp = /(?<pod_name>.*)\:(?<path>.*)/
|
20
|
+
if File.exist?(src)
|
21
|
+
# il src é la cartella, quindi la destizione è il pod
|
22
|
+
direction = :upload
|
23
|
+
local_path = src
|
24
|
+
podname = dst.match(reg_exp)[:pod_name]
|
25
|
+
podpath = dst.match(reg_exp)[:path]
|
26
|
+
else
|
27
|
+
direction = :download
|
28
|
+
podname = src.match(reg_exp)[:pod_name]
|
29
|
+
podpath = src.match(reg_exp)[:path]
|
30
|
+
local_path = dst
|
31
|
+
end
|
32
|
+
|
33
|
+
puts "#{src} #{direction} #{dst}"
|
34
|
+
|
35
|
+
cfgs.env(options[:environment]) do |cfgs|
|
36
|
+
config = Kubeclient::Config.read(ENV['KUBECONFIG'] || "#{Dir.home}/.kube/config")
|
37
|
+
|
38
|
+
context = config.context # attuale contesto
|
39
|
+
|
40
|
+
puts "Stiamo utilizzando il contesto: #{context.api_endpoint}"
|
41
|
+
|
42
|
+
base_cmd = ["kubectl", "-n #{cfgs.stack_name}"]
|
43
|
+
|
44
|
+
cmd = ShellCommandExecution.new([*base_cmd, "exec #{podname}", "--", 'bash -c "apt update && apt install -yq rsync psmisc"'])
|
45
|
+
if cmd.execute.failed?
|
46
|
+
puts "Problemi nell'installazione di rsync nel pod"
|
47
|
+
else
|
48
|
+
cmd = ShellCommandExecution.new([*base_cmd, "cp", File.expand_path("../k8s_rsync/rsyncd.conf", __FILE__), "#{podname}:/tmp/."])
|
49
|
+
copy_1 = cmd.execute.failed?
|
50
|
+
cmd = ShellCommandExecution.new([*base_cmd, "cp", File.expand_path("../k8s_rsync/rsyncd.secrets", __FILE__), "#{podname}:/tmp/."])
|
51
|
+
copy_2 = cmd.execute.failed?
|
52
|
+
cmd = ShellCommandExecution.new([*base_cmd, "exec #{podname}", "--", 'bash -c "chmod 600 /tmp/rsyncd.secrets && chown root /tmp/*"'])
|
53
|
+
chmod = cmd.execute.failed?
|
54
|
+
if copy_1 or copy_2 or chmod
|
55
|
+
puts "problema nella copia dei file di configurazione nel pod"
|
56
|
+
else
|
57
|
+
|
58
|
+
|
59
|
+
cmd = ShellCommandExecution.new([*base_cmd, "exec -i #{podname}", "--", 'bash -c "rsync --daemon --config=/tmp/rsyncd.conf --verbose --log-file=/tmp/rsync.log"'])
|
60
|
+
if cmd.execute.failed?
|
61
|
+
puts "Rsync non startato"
|
62
|
+
else
|
63
|
+
local_port = rand(30000..40000)
|
64
|
+
|
65
|
+
p = IO.popen([*base_cmd, "port-forward #{podname} #{local_port}:873"].join(" "))
|
66
|
+
pid = p.pid
|
67
|
+
puts "PID in execuzione port forward:#{pid}"
|
68
|
+
|
69
|
+
sleep 1
|
70
|
+
|
71
|
+
# lanciamo il comando quindi per far rsync
|
72
|
+
rsync_command = [
|
73
|
+
"rsync -az --no-o --no-g",
|
74
|
+
"--delete",
|
75
|
+
"--password-file=#{ File.expand_path("../k8s_rsync/password", __FILE__)}"
|
76
|
+
]
|
77
|
+
|
78
|
+
if direction == :upload
|
79
|
+
rsync_command << local_path
|
80
|
+
rsync_command << "rsync://root@0.0.0.0:#{local_port}/archives#{podpath}"
|
81
|
+
else
|
82
|
+
rsync_command << "rsync://root@0.0.0.0:#{local_port}/archives#{podpath}"
|
83
|
+
rsync_command << local_path
|
84
|
+
end
|
85
|
+
|
86
|
+
|
87
|
+
cmd = ShellCommandExecution.new(rsync_command)
|
88
|
+
cmd.execute
|
89
|
+
|
90
|
+
sleep 1
|
91
|
+
Process.kill("INT", pid)
|
92
|
+
|
93
|
+
|
94
|
+
puts "Eseguo pulizia"
|
95
|
+
cmd = ShellCommandExecution.new([*base_cmd, "exec -i #{podname}", "--", 'bash -c "killall rsync"'])
|
96
|
+
cmd.execute
|
97
|
+
cmd = ShellCommandExecution.new([*base_cmd, "exec -i #{podname}", "--", 'bash -c "rm -fr /tmp/rsyncd*"'])
|
98
|
+
cmd.execute
|
99
|
+
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
107
|
+
|
108
|
+
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
|
113
|
+
end
|
114
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
root
|
@@ -0,0 +1 @@
|
|
1
|
+
root:root
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module SwarmClusterCliOpe
|
2
|
+
module SyncConfigs
|
3
|
+
class BaseDatabase < Base
|
4
|
+
|
5
|
+
# @return [SwarmClusterCliOpe::SyncConfigs::EnvConfigs]
|
6
|
+
def remote
|
7
|
+
self.class::EnvConfigs.new(self, @configs.dig(:configs, :remote) || {}, -> { container })
|
8
|
+
end
|
9
|
+
|
10
|
+
# @return [SwarmClusterCliOpe::SyncConfigs::EnvConfigs]
|
11
|
+
def local
|
12
|
+
self.class::EnvConfigs.new(self, @configs.dig(:configs, :local) || {}, -> { local_container })
|
13
|
+
end
|
14
|
+
|
15
|
+
##
|
16
|
+
# Classe interna che rappresenta le configurazioni del DB
|
17
|
+
class EnvConfigs < SwarmClusterCliOpe::SyncConfigs::EnvConfigs
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
##
|
22
|
+
# Funzione che ricapitola le informazioni utilizzate per eseguire l'operazione
|
23
|
+
def resume(direction)
|
24
|
+
puts "RESUME - #{direction}
|
25
|
+
service: #{service}
|
26
|
+
local:
|
27
|
+
service_name: #{local.service_name}
|
28
|
+
database_name: #{local.database_name}
|
29
|
+
username: #{local.username}
|
30
|
+
password: #{local.password}
|
31
|
+
version: #{local.database_version}
|
32
|
+
remote:
|
33
|
+
service_name: #{remote.service_name}
|
34
|
+
database_name: #{remote.database_name}
|
35
|
+
username: #{remote.username}
|
36
|
+
password: #{remote.password}
|
37
|
+
version: #{remote.database_version}"
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def local_container
|
44
|
+
# il nome dello stack del compose usiamo come standard il nome della cartella, come lo fà già composer di default
|
45
|
+
Models::ComposeContainer.find_by_service_name(local.service_name, stack_name: @stack_cfgs.local_compose_project_name)
|
46
|
+
end
|
47
|
+
|
48
|
+
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -35,7 +35,8 @@ module SwarmClusterCliOpe
|
|
35
35
|
# @param [String,Symbol] configuration_name -> nome della configurazione da utilizzare per estrapolare la configurazione
|
36
36
|
# in automatico viene tenuto conto se cercare per la versione
|
37
37
|
# con _env o senza....precedenza SENZA
|
38
|
-
|
38
|
+
# @param [nil,String] default_value se non è estrapolato nessun valore, viene utilizzato il valore di default
|
39
|
+
def self.define_cfgs(name, default_env:, configuration_name:,default_value:nil)
|
39
40
|
configuration_name ||= name
|
40
41
|
|
41
42
|
define_method(name) do
|
@@ -43,10 +44,10 @@ module SwarmClusterCliOpe
|
|
43
44
|
|
44
45
|
#valore restituito direttamente dalla configurazione
|
45
46
|
if @configs.key?(configuration_name)
|
46
|
-
value = @configs["#{configuration_name}".to_sym]
|
47
|
+
value = @configs["#{configuration_name}".to_sym] || default_value
|
47
48
|
else
|
48
49
|
env_var = @configs["#{configuration_name}_env".to_sym] || default_env
|
49
|
-
value = find_env_file_variable(env_var)
|
50
|
+
value = find_env_file_variable(env_var) || default_value
|
50
51
|
end
|
51
52
|
self.instance_variable_set("@#{name}", value)
|
52
53
|
end
|
@@ -1,15 +1,15 @@
|
|
1
1
|
module SwarmClusterCliOpe
|
2
2
|
module SyncConfigs
|
3
|
-
class Mysql <
|
3
|
+
class Mysql < BaseDatabase
|
4
4
|
|
5
5
|
# @return [TrueClass, FalseClass]
|
6
6
|
def pull
|
7
7
|
resume('pull')
|
8
8
|
if yes?("Confermare il comando?[y,yes]")
|
9
9
|
tmp_file = "/tmp/#{Time.now.to_i}.sql.gz"
|
10
|
-
container.exec("bash -c 'mysqldump -u #{remote.
|
10
|
+
container.exec("bash -c 'mysqldump -u #{remote.username} --password=#{remote.password} #{remote.database_name} | gzip -c -f' > #{tmp_file}")
|
11
11
|
local_container.copy_in(tmp_file, tmp_file)
|
12
|
-
local_container.exec("bash -c 'zcat #{tmp_file} | mysql -u #{local.
|
12
|
+
local_container.exec("bash -c 'zcat #{tmp_file} | mysql -u #{local.username} --password=#{local.password} #{local.database_name}'")
|
13
13
|
end
|
14
14
|
true
|
15
15
|
end
|
@@ -19,59 +19,25 @@ module SwarmClusterCliOpe
|
|
19
19
|
resume('PUSH')
|
20
20
|
if yes?("ATTENZIONE !!!!!!PUSH!!!!! - Confermare il comando?[y,yes]")
|
21
21
|
tmp_file = "/tmp/#{Time.now.to_i}.sql.gz"
|
22
|
-
local_container.exec("bash -c 'mysqldump -u #{local.
|
22
|
+
local_container.exec("bash -c 'mysqldump -u #{local.username} --password=#{local.password} #{local.database_name} | gzip -c -f' > #{tmp_file}")
|
23
23
|
container.copy_in(tmp_file, tmp_file)
|
24
|
-
container.exec("bash -c 'zcat #{tmp_file} | mysql -u #{remote.
|
24
|
+
container.exec("bash -c 'zcat #{tmp_file} | mysql -u #{remote.username} --password=#{remote.password} #{remote.database_name}'")
|
25
25
|
end
|
26
26
|
true
|
27
27
|
end
|
28
28
|
|
29
|
-
# @return [SwarmClusterCliOpe::SyncConfigs::Mysql::EnvConfigs]
|
30
|
-
def remote
|
31
|
-
EnvConfigs.new(self, @configs[:configs][:remote] || {}, -> { container })
|
32
|
-
end
|
33
|
-
|
34
|
-
# @return [SwarmClusterCliOpe::SyncConfigs::Mysql::EnvConfigs]
|
35
|
-
def local
|
36
|
-
EnvConfigs.new(self, @configs[:configs][:local] || {}, -> { local_container })
|
37
|
-
end
|
38
|
-
|
39
|
-
|
40
29
|
##
|
41
30
|
# Classe interna che rappresenta le configurazioni del DB
|
42
|
-
class EnvConfigs <
|
31
|
+
class EnvConfigs < BaseDatabase::EnvConfigs
|
43
32
|
|
44
33
|
define_cfgs :database_name, default_env: "MYSQL_DATABASE", configuration_name: :database_name
|
45
|
-
define_cfgs :
|
46
|
-
define_cfgs :
|
34
|
+
define_cfgs :username, default_env: "MYSQL_USER", configuration_name: :mysql_user, default_value: 'root'
|
35
|
+
define_cfgs :password, default_env: "MYSQL_PASSWORD", configuration_name: :mysql_password, default_value: 'root'
|
47
36
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
##
|
52
|
-
# Funzione che ricapitola le informazioni utilizzate per eseguire l'operazione
|
53
|
-
def resume(direction)
|
54
|
-
puts "RESUME - #{direction}
|
55
|
-
service: #{service}
|
56
|
-
local:
|
57
|
-
service_name: #{local.service_name}
|
58
|
-
database_name: #{local.database_name}
|
59
|
-
mysql_user: #{local.mysql_user}
|
60
|
-
mysql_password: #{local.mysql_password}
|
61
|
-
remote:
|
62
|
-
service_name: #{remote.service_name}
|
63
|
-
database_name: #{remote.database_name}
|
64
|
-
mysql_user: #{remote.mysql_user}
|
65
|
-
mysql_password: #{remote.mysql_password}"
|
37
|
+
define_cfgs :database_version, default_env: "MYSQL_MAJOR", configuration_name: :mysql_version
|
66
38
|
|
67
39
|
end
|
68
40
|
|
69
|
-
private
|
70
|
-
|
71
|
-
def local_container
|
72
|
-
# il nome dello stack del compose usiamo come standard il nome della cartella, come lo fà già composer di default
|
73
|
-
Models::ComposeContainer.find_by_service_name(local.service_name, stack_name: @stack_cfgs.local_compose_project_name)
|
74
|
-
end
|
75
41
|
|
76
42
|
end
|
77
43
|
end
|
@@ -0,0 +1,159 @@
|
|
1
|
+
module SwarmClusterCliOpe
|
2
|
+
module SyncConfigs
|
3
|
+
class PostGres < BaseDatabase
|
4
|
+
|
5
|
+
|
6
|
+
def pull
|
7
|
+
resume('pull')
|
8
|
+
|
9
|
+
if yes?("Confermare il comando?[y,yes]")
|
10
|
+
|
11
|
+
tmp_file = "/tmp/#{Time.now.to_i}.sql.gz"
|
12
|
+
dump_cmd(remote, tmp_file)
|
13
|
+
local.container.copy_in(tmp_file, tmp_file)
|
14
|
+
|
15
|
+
# drop old db and recreate
|
16
|
+
if Gem::Version.new(local.database_version) <= Gem::Version.new("12")
|
17
|
+
close_connections_and_drop_cmd(local)
|
18
|
+
else
|
19
|
+
raise "DA ANALIZZARE QUANDO LA 13 disponibile....dropdb ha un force come parametro"
|
20
|
+
end
|
21
|
+
|
22
|
+
create_cmd(local)
|
23
|
+
|
24
|
+
restore_cmd(local, tmp_file)
|
25
|
+
|
26
|
+
end
|
27
|
+
true
|
28
|
+
end
|
29
|
+
|
30
|
+
# @return [TrueClass, FalseClass]
|
31
|
+
def push
|
32
|
+
resume('PUSH')
|
33
|
+
|
34
|
+
if yes?("ATTENZIONE !!!!!!PUSH!!!!! - Confermare il comando?[y,yes]")
|
35
|
+
|
36
|
+
tmp_file = "/tmp/#{Time.now.to_i}.sql.gz"
|
37
|
+
dump_cmd(local, tmp_file)
|
38
|
+
remote.container.copy_in(tmp_file, tmp_file)
|
39
|
+
|
40
|
+
# drop old db and recreate
|
41
|
+
if Gem::Version.new(local.database_version) <= Gem::Version.new("12")
|
42
|
+
close_connections_and_drop_cmd(remote)
|
43
|
+
else
|
44
|
+
raise "DA ANALIZZARE QUANDO LA 13 disponibile....dropdb ha un force come parametro"
|
45
|
+
end
|
46
|
+
create_cmd(remote)
|
47
|
+
|
48
|
+
restore_cmd(remote, tmp_file)
|
49
|
+
|
50
|
+
end
|
51
|
+
true
|
52
|
+
end
|
53
|
+
|
54
|
+
##
|
55
|
+
# Classe interna che rappresenta le configurazioni del DB
|
56
|
+
class EnvConfigs < BaseDatabase::EnvConfigs
|
57
|
+
|
58
|
+
define_cfgs :database_name, default_env: "POSTGRES_DB", configuration_name: :database_name
|
59
|
+
define_cfgs :username, default_env: "POSTGRES_USER", configuration_name: :pg_user, default_value: 'postgres'
|
60
|
+
define_cfgs :password, default_env: "POSTGRES_PASSWORD", configuration_name: :pg_password
|
61
|
+
|
62
|
+
define_cfgs :database_version, default_env: "PG_MAJOR", configuration_name: :pg_version
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
private
|
67
|
+
|
68
|
+
# @param [EnvConfigs] config
|
69
|
+
def create_cmd(config)
|
70
|
+
create_cmd = []
|
71
|
+
create_cmd << "PGPASSWORD=\"#{config.password}\""
|
72
|
+
create_cmd << 'createdb'
|
73
|
+
create_cmd << "--username=#{config.username}"
|
74
|
+
create_cmd << config.database_name
|
75
|
+
|
76
|
+
logger.info { "CREATE COMMAND: #{create_cmd.join(' ')}" }
|
77
|
+
config.container.exec("bash -c '#{create_cmd.join(' ')} || true'")
|
78
|
+
end
|
79
|
+
|
80
|
+
# @param [EnvConfigs] config
|
81
|
+
# def drop_cmd(config)
|
82
|
+
# drop_cmd = []
|
83
|
+
# drop_cmd << "PGPASSWORD=\"#{config.password}\""
|
84
|
+
# drop_cmd << 'dropdb'
|
85
|
+
# drop_cmd << '--if-exists'
|
86
|
+
# drop_cmd << "--username=#{config.username}"
|
87
|
+
# drop_cmd << config.database_name
|
88
|
+
# drop_cmd
|
89
|
+
#
|
90
|
+
# logger.info { "DROP COMMAND: #{drop_cmd.join(' ')}" }
|
91
|
+
# config.container.exec("bash -c '#{drop_cmd.join(' ')}'")
|
92
|
+
# end
|
93
|
+
|
94
|
+
# @param [EnvConfigs] config
|
95
|
+
def restore_cmd(config, tmp_file)
|
96
|
+
restore_cmd = []
|
97
|
+
restore_cmd << "PGPASSWORD=\"#{config.password}\""
|
98
|
+
restore_cmd << 'pg_restore'
|
99
|
+
restore_cmd << '--no-acl'
|
100
|
+
restore_cmd << '--no-owner'
|
101
|
+
restore_cmd << "--username=#{config.username}"
|
102
|
+
restore_cmd << "--dbname=#{config.database_name}"
|
103
|
+
restore_cmd << tmp_file
|
104
|
+
restore_cmd
|
105
|
+
|
106
|
+
logger.info { "RESTORE COMMAND: #{restore_cmd.join(' ')}" }
|
107
|
+
config.container.exec("bash -c '#{restore_cmd.join(' ')}'")
|
108
|
+
end
|
109
|
+
|
110
|
+
# @param [EnvConfigs] config
|
111
|
+
def dump_cmd(config, file)
|
112
|
+
dump_cmd = []
|
113
|
+
dump_cmd << "PGPASSWORD=\"#{config.password}\""
|
114
|
+
dump_cmd << 'pg_dump'
|
115
|
+
dump_cmd << '--no-acl'
|
116
|
+
dump_cmd << '--no-owner'
|
117
|
+
dump_cmd << "--username=#{config.username}"
|
118
|
+
dump_cmd << '--format=custom'
|
119
|
+
dump_cmd << '--compress=9'
|
120
|
+
dump_cmd << config.database_name
|
121
|
+
dump_cmd
|
122
|
+
|
123
|
+
logger.info { "DUMP COMMAND: #{dump_cmd.join(' ')}" }
|
124
|
+
config.container.exec("bash -c '#{dump_cmd.join(' ')}' > #{file}")
|
125
|
+
|
126
|
+
end
|
127
|
+
|
128
|
+
|
129
|
+
# @param [EnvConfigs] config
|
130
|
+
def close_connections_and_drop_cmd(config)
|
131
|
+
cmd = []
|
132
|
+
cmd << "PGPASSWORD=\"#{config.password}\""
|
133
|
+
|
134
|
+
sql = []
|
135
|
+
sql << "SELECT pg_terminate_backend(pg_stat_activity.pid) FROM pg_stat_activity WHERE pg_stat_activity.datname = '\"'\"'#{config.database_name}'\"'\"' AND pid <> pg_backend_pid();;"
|
136
|
+
sql << "DROP DATABASE IF EXISTS #{config.database_name};"
|
137
|
+
|
138
|
+
cmd << "echo \"#{sql.join(" ")}\" "
|
139
|
+
cmd << '|'
|
140
|
+
cmd << 'psql'
|
141
|
+
cmd << "-U #{config.username}"
|
142
|
+
cmd << "postgres"
|
143
|
+
cmd
|
144
|
+
|
145
|
+
logger.info { "CLOSE CONNECTIONS COMMAND: #{cmd.join(' ')}" }
|
146
|
+
config.container.exec("bash -c '#{cmd.join(' ')}'")
|
147
|
+
end
|
148
|
+
|
149
|
+
# quello che fa capistrano quando copia in locale - utenze inventate
|
150
|
+
# gzip -d cortobio_production_new_2020-09-10-171742.sql.gz &&
|
151
|
+
# PGPASSWORD='root' psql -c "SELECT pg_terminate_backend(pg_stat_activity.pid) FROM pg_stat_activity WHERE pg_stat_activity.datname = 'development' AND pid <> pg_backend_pid();;" -U root -h 0.0.0.0 -p 32790 development;
|
152
|
+
# PGPASSWORD='root' dropdb -U root -h 0.0.0.0 -p 32790 development;
|
153
|
+
# PGPASSWORD='root' createdb -U root -h 0.0.0.0 -p 32790 development;
|
154
|
+
# PGPASSWORD='root' psql -U root -h 0.0.0.0 -p 32790 -d development < ./cortobio_production_new_2020-09-10-171742.sql
|
155
|
+
|
156
|
+
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: swarm_cluster_cli_ope
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0.pre.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Marino Bonetti
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-11-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|
@@ -97,6 +97,10 @@ files:
|
|
97
97
|
- lib/swarm_cluster_cli_ope/commands/task.rb
|
98
98
|
- lib/swarm_cluster_cli_ope/configuration.rb
|
99
99
|
- lib/swarm_cluster_cli_ope/configuration_concern.rb
|
100
|
+
- lib/swarm_cluster_cli_ope/k8s.rb
|
101
|
+
- lib/swarm_cluster_cli_ope/k8s_rsync/password
|
102
|
+
- lib/swarm_cluster_cli_ope/k8s_rsync/rsyncd.conf
|
103
|
+
- lib/swarm_cluster_cli_ope/k8s_rsync/rsyncd.secrets
|
100
104
|
- lib/swarm_cluster_cli_ope/logger_concern.rb
|
101
105
|
- lib/swarm_cluster_cli_ope/manager.rb
|
102
106
|
- lib/swarm_cluster_cli_ope/models/base.rb
|
@@ -110,9 +114,11 @@ files:
|
|
110
114
|
- lib/swarm_cluster_cli_ope/shell_command_execution.rb
|
111
115
|
- lib/swarm_cluster_cli_ope/shell_command_response.rb
|
112
116
|
- lib/swarm_cluster_cli_ope/sync_configs/base.rb
|
117
|
+
- lib/swarm_cluster_cli_ope/sync_configs/base_database.rb
|
113
118
|
- lib/swarm_cluster_cli_ope/sync_configs/copy.rb
|
114
119
|
- lib/swarm_cluster_cli_ope/sync_configs/env_configs.rb
|
115
120
|
- lib/swarm_cluster_cli_ope/sync_configs/mysql.rb
|
121
|
+
- lib/swarm_cluster_cli_ope/sync_configs/post_gres.rb
|
116
122
|
- lib/swarm_cluster_cli_ope/sync_configs/rsync.rb
|
117
123
|
- lib/swarm_cluster_cli_ope/sync_configs/sqlite3.rb
|
118
124
|
- lib/swarm_cluster_cli_ope/version.rb
|
@@ -137,9 +143,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
137
143
|
version: 2.3.0
|
138
144
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
139
145
|
requirements:
|
140
|
-
- - "
|
146
|
+
- - ">"
|
141
147
|
- !ruby/object:Gem::Version
|
142
|
-
version:
|
148
|
+
version: 1.3.1
|
143
149
|
requirements: []
|
144
150
|
rubygems_version: 3.0.8
|
145
151
|
signing_key:
|