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 +4 -4
- data/Gemfile.lock +3 -3
- data/README.md +10 -14
- data/lib/swarm_cluster_cli_ope/cli.rb +170 -124
- data/lib/swarm_cluster_cli_ope/configuration.rb +96 -25
- data/lib/swarm_cluster_cli_ope/node.rb +1 -2
- data/lib/swarm_cluster_cli_ope/sync_configs/base.rb +35 -0
- data/lib/swarm_cluster_cli_ope/sync_configs/copy.rb +35 -0
- data/lib/swarm_cluster_cli_ope/sync_configs/rsync.rb +74 -0
- data/lib/swarm_cluster_cli_ope/sync_configs/sqlite3.rb +8 -0
- data/lib/swarm_cluster_cli_ope/version.rb +1 -1
- data/swarm_cluster_cli_ope.gemspec +3 -3
- metadata +11 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 473cc11423d57b9b40b361184587b1acdda0d14751b12266740eb98e1f1c7caa
|
4
|
+
data.tar.gz: 542e14fb88a4d40c34209853678e80fc0d2bddc90745aa9bd6eaee666e7fcf03
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 90fe0e391b0aa2eb12f1564153905db9fd294aa2817094da62dc1a7da7c3c663f7f94f99996d5f3c1e7818f1d8d214d2c1286fdefbe9eedfb932c3abdf224586
|
7
|
+
data.tar.gz: 24e26ab924509fbc0df1d03a67c59ec5d62d544a8cc0709f757012c2dcb6fd8915a049ad82ccec49316f19b4cdb65c1bac9f4c62e3a1c4231f5de7c316bbcbc1
|
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.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.
|
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
|
-
```
|
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/
|
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
|
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
|
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
|
-
|
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
|
62
|
+
option :stack_name, required: false, type: :string
|
57
63
|
|
58
64
|
def services
|
59
|
-
|
60
|
-
|
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
|
74
|
+
option :stack_name, required: false, type: :string
|
66
75
|
|
67
76
|
def mc(service_name)
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
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
|
-
|
93
|
-
|
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
|
-
|
121
|
-
|
122
|
-
#
|
123
|
-
|
124
|
-
|
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
|
-
|
128
|
-
c.add("
|
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
|
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
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
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.
|
162
|
-
|
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
|
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
|
-
|
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
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
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
|
-
|
179
|
-
|
180
|
-
|
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
|
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:
|
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
|
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:
|
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
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
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
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
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
|
-
|
52
|
-
|
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
|
-
|
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
|
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
|
-
|
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
|
-
|
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
|
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
|
-
|
141
|
-
|
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.
|
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
|
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(
|
172
|
-
project_file = File.join(
|
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
|
177
|
-
|
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
|
-
|
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
|
-
|
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
|
@@ -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://
|
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
|
-
|
21
|
-
|
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.
|
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-
|
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://
|
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://
|
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.
|
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
|