hybrid_platforms_conductor 32.12.0 → 32.13.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (134) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1103 -0
  3. data/LICENSE.md +31 -0
  4. data/README.md +395 -0
  5. data/bin/setup +1 -1
  6. data/docs/api.md +349 -0
  7. data/docs/config_dsl.md +315 -0
  8. data/docs/executables.md +226 -0
  9. data/docs/executables/check-node.md +155 -0
  10. data/docs/executables/deploy.md +198 -0
  11. data/docs/executables/dump_nodes_json.md +110 -0
  12. data/docs/executables/free_ips.md +93 -0
  13. data/docs/executables/free_veids.md +73 -0
  14. data/docs/executables/get_impacted_nodes.md +94 -0
  15. data/docs/executables/last_deploys.md +114 -0
  16. data/docs/executables/nodes_to_deploy.md +139 -0
  17. data/docs/executables/report.md +159 -0
  18. data/docs/executables/run.md +126 -0
  19. data/docs/executables/setup.md +92 -0
  20. data/docs/executables/ssh_config.md +151 -0
  21. data/docs/executables/test.md +213 -0
  22. data/docs/executables/topograph.md +139 -0
  23. data/docs/gen/mermaid/README.md-0.png +0 -0
  24. data/docs/gen/mermaid/docs/executables/check-node.md-0.png +0 -0
  25. data/docs/gen/mermaid/docs/executables/deploy.md-0.png +0 -0
  26. data/docs/gen/mermaid/docs/executables/free_ips.md-0.png +0 -0
  27. data/docs/gen/mermaid/docs/executables/free_veids.md-0.png +0 -0
  28. data/docs/gen/mermaid/docs/executables/get_impacted_nodes.md-0.png +0 -0
  29. data/docs/gen/mermaid/docs/executables/last_deploys.md-0.png +0 -0
  30. data/docs/gen/mermaid/docs/executables/nodes_to_deploy.md-0.png +0 -0
  31. data/docs/gen/mermaid/docs/executables/report.md-0.png +0 -0
  32. data/docs/gen/mermaid/docs/executables/run.md-0.png +0 -0
  33. data/docs/gen/mermaid/docs/executables/setup.md-0.png +0 -0
  34. data/docs/gen/mermaid/docs/executables/ssh_config.md-0.png +0 -0
  35. data/docs/gen/mermaid/docs/executables/test.md-0.png +0 -0
  36. data/docs/install.md +161 -0
  37. data/docs/plugins.md +215 -0
  38. data/docs/plugins/action/bash.md +37 -0
  39. data/docs/plugins/action/interactive.md +37 -0
  40. data/docs/plugins/action/remote_bash.md +67 -0
  41. data/docs/plugins/action/ruby.md +69 -0
  42. data/docs/plugins/action/scp.md +61 -0
  43. data/docs/plugins/cmdb/config.md +46 -0
  44. data/docs/plugins/cmdb/host_ip.md +33 -0
  45. data/docs/plugins/cmdb/host_keys.md +33 -0
  46. data/docs/plugins/cmdb/platform_handlers.md +33 -0
  47. data/docs/plugins/connector/local.md +28 -0
  48. data/docs/plugins/connector/ssh.md +95 -0
  49. data/docs/plugins/platform_handler/yaml_inventory.md +105 -0
  50. data/docs/plugins/provisioner/docker.md +27 -0
  51. data/docs/plugins/provisioner/podman.md +27 -0
  52. data/docs/plugins/provisioner/proxmox.md +115 -0
  53. data/docs/plugins/report/confluence.md +49 -0
  54. data/docs/plugins/report/mediawiki.md +28 -0
  55. data/docs/plugins/report/stdout.md +32 -0
  56. data/docs/plugins/test/bitbucket_conf.md +97 -0
  57. data/docs/plugins/test/can_be_checked.md +27 -0
  58. data/docs/plugins/test/check_deploy_and_idempotence.md +61 -0
  59. data/docs/plugins/test/check_from_scratch.md +28 -0
  60. data/docs/plugins/test/connection.md +27 -0
  61. data/docs/plugins/test/deploy_freshness.md +27 -0
  62. data/docs/plugins/test/deploy_from_scratch.md +28 -0
  63. data/docs/plugins/test/deploy_removes_root_access.md +29 -0
  64. data/docs/plugins/test/divergence.md +41 -0
  65. data/docs/plugins/test/executables.md +26 -0
  66. data/docs/plugins/test/file_system.md +49 -0
  67. data/docs/plugins/test/file_system_hdfs.md +65 -0
  68. data/docs/plugins/test/hostname.md +27 -0
  69. data/docs/plugins/test/idempotence.md +56 -0
  70. data/docs/plugins/test/ip.md +28 -0
  71. data/docs/plugins/test/jenkins_ci_conf.md +54 -0
  72. data/docs/plugins/test/jenkins_ci_masters_ok.md +54 -0
  73. data/docs/plugins/test/linear_strategy.md +26 -0
  74. data/docs/plugins/test/local_users.md +48 -0
  75. data/docs/plugins/test/mounts.md +55 -0
  76. data/docs/plugins/test/orphan_files.md +38 -0
  77. data/docs/plugins/test/ports.md +50 -0
  78. data/docs/plugins/test/private_ips.md +27 -0
  79. data/docs/plugins/test/public_ips.md +27 -0
  80. data/docs/plugins/test/spectre.md +26 -0
  81. data/docs/plugins/test/veids.md +27 -0
  82. data/docs/plugins/test/vulnerabilities.md +65 -0
  83. data/docs/plugins/test_report/confluence.md +43 -0
  84. data/docs/plugins/test_report/stdout.md +26 -0
  85. data/docs/plugins_create.md +135 -0
  86. data/docs/tutorial.md +57 -0
  87. data/docs/tutorial/01_installation.md +129 -0
  88. data/docs/tutorial/02_first_node.md +466 -0
  89. data/docs/tutorial/03_scale.md +876 -0
  90. data/docs/tutorial/04_test.md +965 -0
  91. data/docs/tutorial/05_extend_with_plugins.md +1132 -0
  92. data/examples/bare/Gemfile +4 -0
  93. data/examples/bare/hpc_config.rb +2 -0
  94. data/examples/localhost/Gemfile +4 -0
  95. data/examples/localhost/hpc_config.rb +2 -0
  96. data/examples/localhost/inventory.yaml +4 -0
  97. data/lib/hybrid_platforms_conductor/actions_executor.rb +1 -0
  98. data/lib/hybrid_platforms_conductor/deployer.rb +3 -2
  99. data/lib/hybrid_platforms_conductor/hpc_plugins/action/remote_bash.rb +29 -13
  100. data/lib/hybrid_platforms_conductor/hpc_plugins/action/scp.rb +1 -1
  101. data/lib/hybrid_platforms_conductor/hpc_plugins/connector/local.rb +98 -0
  102. data/lib/hybrid_platforms_conductor/hpc_plugins/connector/my_connector.rb.sample +2 -2
  103. data/lib/hybrid_platforms_conductor/hpc_plugins/connector/ssh.rb +7 -3
  104. data/lib/hybrid_platforms_conductor/hpc_plugins/platform_handler/platform_handler_plugin.rb.sample +5 -5
  105. data/lib/hybrid_platforms_conductor/hpc_plugins/platform_handler/yaml_inventory.rb +140 -0
  106. data/lib/hybrid_platforms_conductor/hpc_plugins/provisioner/proxmox.rb +5 -2
  107. data/lib/hybrid_platforms_conductor/hpc_plugins/test/bitbucket_conf.rb +4 -4
  108. data/lib/hybrid_platforms_conductor/hpc_plugins/test/deploy_freshness.rb +1 -1
  109. data/lib/hybrid_platforms_conductor/hpc_plugins/test/deploy_removes_root_access.rb +19 -17
  110. data/lib/hybrid_platforms_conductor/hpc_plugins/test/divergence.rb +3 -0
  111. data/lib/hybrid_platforms_conductor/hpc_plugins/test/hostname.rb +2 -1
  112. data/lib/hybrid_platforms_conductor/hpc_plugins/test/ip.rb +2 -1
  113. data/lib/hybrid_platforms_conductor/hpc_plugins/test/local_users.rb +2 -1
  114. data/lib/hybrid_platforms_conductor/hpc_plugins/test/mounts.rb +4 -3
  115. data/lib/hybrid_platforms_conductor/hpc_plugins/test/orphan_files.rb +2 -1
  116. data/lib/hybrid_platforms_conductor/hpc_plugins/test/spectre.rb +1 -1
  117. data/lib/hybrid_platforms_conductor/hpc_plugins/test/vulnerabilities.rb +8 -7
  118. data/lib/hybrid_platforms_conductor/hpc_plugins/test_report/confluence.rb +1 -1
  119. data/lib/hybrid_platforms_conductor/json_dumper.rb +1 -1
  120. data/lib/hybrid_platforms_conductor/platform_handler.rb +1 -1
  121. data/lib/hybrid_platforms_conductor/services_handler.rb +18 -16
  122. data/lib/hybrid_platforms_conductor/tests_runner.rb +0 -1
  123. data/lib/hybrid_platforms_conductor/topographer.rb +0 -1
  124. data/lib/hybrid_platforms_conductor/version.rb +1 -1
  125. data/spec/hybrid_platforms_conductor_test/api/actions_executor/actions/remote_bash_spec.rb +16 -0
  126. data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/local/connectable_nodes_spec.rb +30 -0
  127. data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/local/remote_actions_spec.rb +113 -0
  128. data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/ssh/cli_options_spec.rb +6 -2
  129. data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/ssh/global_helpers_spec.rb +38 -1
  130. data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/ssh/remote_actions_spec.rb +8 -8
  131. data/spec/hybrid_platforms_conductor_test/docs_spec.rb +10 -0
  132. data/tools/check_md +89 -0
  133. data/tools/generate_mermaid +75 -0
  134. metadata +207 -12
@@ -0,0 +1,876 @@
1
+
2
+ ---
3
+ **<p style="text-align: center;">Tutorial navigation</p>**
4
+
5
+ | <sub>[Introduction](/docs/tutorial.md)</sub> | <sub>[1. Installation and first-time setup](/docs/tutorial/01_installation.md)</sub> | <sub>[2. Deploy and check a first node](/docs/tutorial/02_first_node.md)</sub> | <nobr><sub><sub>&#128071;You are here&#128071;</sub></sub></nobr><br><sub>[3. Scale your processes](/docs/tutorial/03_scale.md)</sub> | <sub>[4. Testing your processes and platforms](/docs/tutorial/04_test.md)</sub> | <sub>[5. Extend Hybrid Platforms Conductor with your own requirements](/docs/tutorial/05_extend_with_plugins.md)</sub> |
6
+ | ---------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------- |
7
+ | <sub><sub>**[Use-case](/docs/tutorial.md#use-case)**</sub></sub> | <sub><sub>**[Dependencies installation](/docs/tutorial/01_installation.md#hpc-dependencies)**</sub></sub> | <sub><sub>**[Add your first node and its platform repository](/docs/tutorial/02_first_node.md#add-first-node)**</sub></sub> | <sub><sub>**[Provision our web services platform](/docs/tutorial/03_scale.md#provision)**</sub></sub> | <sub><sub>**[Hello test framework](/docs/tutorial/04_test.md#framework)**</sub></sub> | <sub><sub>**[Create your plugins' repository](/docs/tutorial/05_extend_with_plugins.md#plugins-repo)**</sub></sub> |
8
+ | <sub><sub>**[Prerequisites](/docs/tutorial.md#prerequisites)**</sub></sub> | <sub><sub>**[Our platforms' main repository](/docs/tutorial/01_installation.md#main-repo)**</sub></sub> | <sub><sub>**[Check and deploy services on this node](/docs/tutorial/02_first_node.md#check-deploy)**</sub></sub> | <sub><sub>**[Run commands on our new web services](/docs/tutorial/03_scale.md#run)**</sub></sub> | <sub><sub>**[Testing your nodes](/docs/tutorial/04_test.md#nodes-tests)**</sub></sub> | <sub><sub>**[Your own platform handler](/docs/tutorial/05_extend_with_plugins.md#platform-handler)**</sub></sub> |
9
+ | <sub><sub>**[Tutorial setup](/docs/tutorial.md#tutorial-setup)**</sub></sub> | | <sub><sub>**[Updating the configuration](/docs/tutorial/02_first_node.md#update)**</sub></sub> | <sub><sub>**[Check and deploy our web services on several nodes at once](/docs/tutorial/03_scale.md#check-deploy)**</sub></sub> | <sub><sub>**[Testing your platforms' configuration](/docs/tutorial/04_test.md#platforms-tests)**</sub></sub> | <sub><sub>**[Write your own tests](/docs/tutorial/05_extend_with_plugins.md#test)**</sub></sub> |
10
+ | | | | | <sub><sub>**[Other kinds of tests](/docs/tutorial/04_test.md#other-tests)**</sub></sub> | <sub><sub>**[Enough of stdout, we want to report to other tools](/docs/tutorial/05_extend_with_plugins.md#report)**</sub></sub> |
11
+ | | | | | | <sub><sub>**[What next?](/docs/tutorial/05_extend_with_plugins.md#what-next)**</sub></sub> |
12
+
13
+ # 3. Scale your processes
14
+
15
+ In this section we will cover how Hybrid Platforms Conductor scales naturally your DevOps processes.
16
+
17
+ We'll take a real world example: Web services running on hosts accessible through SSH.
18
+ We'll use Docker to have those hosts running, so that even if you don't own an infrastructure you can see go on with this tutorial.
19
+
20
+ Then we'll see how Hybrid Platforms Conductor helps in checking, deploying, running all those services on those nodes in a very simple way.
21
+
22
+ <a name="provision"></a>
23
+ ## Provision our web services platform
24
+
25
+ The goal here is top have a full platform provisioned by Docker of web services.
26
+ Then we'll play with it.
27
+
28
+ First we'll create a Docker image with the following features:
29
+ * A web server (written in Go and running on port 80) that outputs a simple Hello world, whose message is taken from the file `/root/hello_world.txt`.
30
+ * An OpenSSH server that allows SSH connections to the `root` account, authenticated with a RSA key.
31
+
32
+ We'll do this by creating all files needed, the Dockerfile, and building the image:
33
+ ```bash
34
+ mkdir -p ~/hpc_tutorial/web_docker_image
35
+
36
+ # The Go web server code
37
+ cat <<EOF >~/hpc_tutorial/web_docker_image/main.go
38
+ package main
39
+
40
+ import (
41
+ "fmt"
42
+ "io/ioutil"
43
+ "log"
44
+ "net/http"
45
+ "os"
46
+ )
47
+
48
+ const homepageEndPoint = "/"
49
+
50
+ // StartWebServer the webserver
51
+ func StartWebServer() {
52
+ http.HandleFunc(homepageEndPoint, handleHomepage)
53
+ port := os.Getenv("PORT")
54
+ if len(port) == 0 {
55
+ panic("Environment variable PORT is not set")
56
+ }
57
+
58
+ log.Printf("Starting web server to listen on endpoints [%s] and port %s",
59
+ homepageEndPoint, port)
60
+ if err := http.ListenAndServe(":"+port, nil); err != nil {
61
+ panic(err)
62
+ }
63
+ }
64
+
65
+ func handleHomepage(w http.ResponseWriter, r *http.Request) {
66
+ urlPath := r.URL.Path
67
+ log.Printf("Web request received on url path %s", urlPath)
68
+ content, content_err := ioutil.ReadFile("/root/hello_world.txt")
69
+ if content_err != nil {
70
+ fmt.Printf("Failed to read message to display, err: %s", content_err)
71
+ }
72
+ _, write_err := w.Write(content)
73
+ if write_err != nil {
74
+ fmt.Printf("Failed to write response, err: %s", write_err)
75
+ }
76
+ }
77
+
78
+ func main() {
79
+ StartWebServer()
80
+ }
81
+ EOF
82
+
83
+ # The hello_world message file
84
+ cat <<EOF >~/hpc_tutorial/web_docker_image/hello_world.txt
85
+ Hello World!
86
+ EOF
87
+
88
+ # Generate root admin RSA keys
89
+ yes y | ssh-keygen -t rsa -b 2048 -C "admin@example.com" -f ~/hpc_tutorial/web_docker_image/hpc_root.key -N ""
90
+
91
+ # The Docker start script
92
+ cat <<EOF >~/hpc_tutorial/web_docker_image/start.sh
93
+ #!/bin/bash
94
+
95
+ # Start sshd as a daemon
96
+ /usr/sbin/sshd
97
+
98
+ # Start web server
99
+ sh -c /codebase/bin/server
100
+ EOF
101
+
102
+ # The Dockerfile
103
+ cat <<EOF >~/hpc_tutorial/web_docker_image/Dockerfile
104
+ # syntax=docker/dockerfile:1
105
+ # Pull the image containing Go
106
+ FROM golang:1.16.3-buster
107
+
108
+ # Install the web server
109
+ # Create the message file to be displayed by the web server
110
+ COPY hello_world.txt /root/hello_world.txt
111
+ # Copy the code
112
+ COPY main.go /codebase/src/main.go
113
+ # Build the binary
114
+ RUN cd /codebase && go build -v -o /codebase/bin/server ./src/main.go
115
+ # Set the env which will be available at runtime
116
+ ENV PORT=80
117
+ EXPOSE 80
118
+
119
+ # Install sshd
120
+ RUN apt-get update && apt-get install -y openssh-server
121
+ RUN mkdir /var/run/sshd
122
+ # Activate root login
123
+ RUN sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config
124
+ # Speed-up considerably ssh performance and avoid huge lags and timeouts without DNS
125
+ RUN sed -i 's/#UseDNS yes/UseDNS no/' /etc/ssh/sshd_config
126
+ EXPOSE 22
127
+
128
+ # Upload our root key for key authentication of root
129
+ COPY hpc_root.key.pub /root/.ssh/authorized_keys
130
+ RUN chmod 700 /root/.ssh
131
+ RUN chmod 400 /root/.ssh/authorized_keys
132
+
133
+ # Startup script
134
+ COPY start.sh /start.sh
135
+ RUN chmod +x /start.sh
136
+ CMD ["/start.sh"]
137
+ EOF
138
+
139
+ # Build the Docker image named hpc_tutorial_web
140
+ DOCKER_BUILDKIT=1 docker build -t hpc_tutorial_web ~/hpc_tutorial/web_docker_image
141
+ # =>
142
+ # [+] Building 27.7s (20/20) FINISHED
143
+ # => [internal] load build definition from Dockerfile 0.0s
144
+ # => => transferring dockerfile: 32B 0.0s
145
+ # => [internal] load .dockerignore 0.0s
146
+ # => => transferring context: 2B 0.0s
147
+ # => resolve image config for docker.io/docker/dockerfile:1 0.6s
148
+ # => CACHED docker-image://docker.io/docker/dockerfile:1@sha256:e2a8561e419ab1ba6b2fe6cbdf49fd92b95912df1cf7d313c3e2230a333fdbcc 0.0s
149
+ # => [internal] load metadata for docker.io/library/golang:1.16.3-buster 0.6s
150
+ # => [ 1/13] FROM docker.io/library/golang:1.16.3-buster@sha256:9d64369fd3c633df71d7465d67d43f63bb31192193e671742fa1c26ebc3a6210 0.0s
151
+ # => [internal] load build context 0.0s
152
+ # => => transferring context: 1.19kB 0.0s
153
+ # => CACHED [ 2/13] COPY hello_world.txt /root/hello_world.txt 0.0s
154
+ # => [ 3/13] COPY main.go /codebase/src/main.go 0.1s
155
+ # => [ 4/13] RUN cd /codebase && go build -v -o /codebase/bin/server ./src/main.go 1.8s
156
+ # => [ 5/13] RUN apt-get update && apt-get install -y openssh-server 18.3s
157
+ # => [ 6/13] RUN mkdir /var/run/sshd 0.6s
158
+ # => [ 7/13] RUN sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config 0.7s
159
+ # => [ 8/13] RUN sed -i 's/#UseDNS yes/UseDNS no/' /etc/ssh/sshd_config 0.6s
160
+ # => [ 9/13] COPY hpc_root.key.pub /root/.ssh/authorized_keys 0.1s
161
+ # => [10/13] RUN chmod 700 /root/.ssh 0.6s
162
+ # => [11/13] RUN chmod 400 /root/.ssh/authorized_keys 0.6s
163
+ # => [12/13] COPY start.sh /start.sh 0.1s
164
+ # => [13/13] RUN chmod +x /start.sh 0.7s
165
+ # => exporting to image 1.7s
166
+ # => => exporting layers 1.6s
167
+ # => => writing image sha256:38183990af6d364d19e9ba7b45aec02a103c82cf6aaf26a0dfbbdb803e067c3c 0.0s
168
+ # => => naming to docker.io/library/hpc_tutorial_web 0.0s
169
+ ```
170
+
171
+ So now it's time to create the Docker containers hosting our web services!
172
+
173
+ We'll create 10 of them, named `webN`, and associate the hostnames `webN.hpc_tutorial.org` to them.
174
+ ```bash
175
+ # Provision 10 containers
176
+ for ((i=1;i<=10;i++));
177
+ do
178
+ docker run --hostname "web$i.hpc_tutorial.org" --name "web$i" -P -d hpc_tutorial_web
179
+ done
180
+ ```
181
+
182
+ Then to be closer to a real-world situation, we will use hostnames and IPs to access our web services.
183
+ To do that, we will generate the hostnames/ip mapping in the /etc/hosts file of our containers.
184
+ ```bash
185
+ for ((i=1;i<=10;i++));
186
+ do
187
+ echo "$(docker container inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' web$i) web$i.hpc_tutorial.org" >>/etc/hosts
188
+ done
189
+ ```
190
+
191
+ We can check that our web services are running correctly by using a simple test script:
192
+ ```bash
193
+ cat <<EOF >~/hpc_tutorial/web_docker_image/test.bash
194
+ #!/bin/bash
195
+
196
+ for ((i=1;i<=10;i++));
197
+ do
198
+ echo "Container web\$i: \$(curl http://web\$i.hpc_tutorial.org 2>/dev/null)"
199
+ done
200
+ EOF
201
+ chmod a+x ~/hpc_tutorial/web_docker_image/test.bash
202
+
203
+ ~/hpc_tutorial/web_docker_image/test.bash
204
+ # =>
205
+ # Container web1: Hello World!
206
+ # Container web2: Hello World!
207
+ # Container web3: Hello World!
208
+ # Container web4: Hello World!
209
+ # Container web5: Hello World!
210
+ # Container web6: Hello World!
211
+ # Container web7: Hello World!
212
+ # Container web8: Hello World!
213
+ # Container web9: Hello World!
214
+ # Container web10: Hello World!
215
+ ```
216
+
217
+ Please note that if we exit your Docker tutorial container and restart it, you will need to restart your web containers and regenerate their hostname/ip in `/etc/hosts`.
218
+ This will be done this way (to be done each time you will restart your tutorial or web containers):
219
+ ```bash
220
+ for ((i=1;i<=10;i++));
221
+ do
222
+ docker container start web$i
223
+ echo "$(docker container inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' web$i) web$i.hpc_tutorial.org" >>/etc/hosts
224
+ done
225
+ ```
226
+
227
+ Now we are in front of a real-world situation: 10 web services running behind hostnames. Let's see how to handle them with Hybrid Platforms Conductor.
228
+
229
+ <a name="run"></a>
230
+ ## Run commands on our new web services
231
+
232
+ In order for Hybrid Platforms Conductor's processes to handle those new web services, we start by adding those new nodes to our inventory, and register the `web-hello` service to them:
233
+ ```bash
234
+ for ((i=1;i<=10;i++));
235
+ do
236
+ cat <<EOF >>~/hpc_tutorial/my-service-conf-repo/inventory.yaml
237
+ web$i:
238
+ metadata:
239
+ description: Web service nbr $i
240
+ hostname: web$i.hpc_tutorial.org
241
+ # The list of service names this node should have
242
+ services:
243
+ - web-hello
244
+ EOF
245
+ done
246
+ ```
247
+
248
+ Now they should appear in our inventory with [`report`](/docs/executables/run.md):
249
+ ```bash
250
+ ./bin/report
251
+ # =>
252
+ # +-------+----------------------+------------------------+-------------+-----------+----+-----------------------+------------+
253
+ # | Node | Platform | Host name | IP | Physical? | OS | Description | Services |
254
+ # +-------+----------------------+------------------------+-------------+-----------+----+-----------------------+------------+
255
+ # | local | my-service-conf-repo | | | No | | The local environment | my-service |
256
+ # | web1 | my-service-conf-repo | web1.hpc_tutorial.org | 172.17.0.4 | No | | Web service nbr 1 | web-hello |
257
+ # | web10 | my-service-conf-repo | web10.hpc_tutorial.org | 172.17.0.13 | No | | Web service nbr 10 | web-hello |
258
+ # | web2 | my-service-conf-repo | web2.hpc_tutorial.org | 172.17.0.5 | No | | Web service nbr 2 | web-hello |
259
+ # | web3 | my-service-conf-repo | web3.hpc_tutorial.org | 172.17.0.6 | No | | Web service nbr 3 | web-hello |
260
+ # | web4 | my-service-conf-repo | web4.hpc_tutorial.org | 172.17.0.7 | No | | Web service nbr 4 | web-hello |
261
+ # | web5 | my-service-conf-repo | web5.hpc_tutorial.org | 172.17.0.8 | No | | Web service nbr 5 | web-hello |
262
+ # | web6 | my-service-conf-repo | web6.hpc_tutorial.org | 172.17.0.9 | No | | Web service nbr 6 | web-hello |
263
+ # | web7 | my-service-conf-repo | web7.hpc_tutorial.org | 172.17.0.10 | No | | Web service nbr 7 | web-hello |
264
+ # | web8 | my-service-conf-repo | web8.hpc_tutorial.org | 172.17.0.11 | No | | Web service nbr 8 | web-hello |
265
+ # | web9 | my-service-conf-repo | web9.hpc_tutorial.org | 172.17.0.12 | No | | Web service nbr 9 | web-hello |
266
+ # +-------+----------------------+------------------------+-------------+-----------+----+-----------------------+------------+
267
+ ```
268
+ You can already see that the IP address has already been discovered and added to the nodes' metadata.
269
+ This is done thanks to the [`host_ip` CMDB plugin](/docs/plugins/cmdb/host_ip.md).
270
+
271
+ As our web services require the `root` RSA key to connect to them, let's add it to our ssh agent (you'll have to redo this each time you exit and restart the `hpc_tutorial` container):
272
+ ```bash
273
+ eval "$(ssh-agent -s)"
274
+ ssh-add ~/hpc_tutorial/web_docker_image/hpc_root.key
275
+ # => Identity added: /root/hpc_tutorial/web_docker_image/hpc_root.key (admin@example.com)
276
+ ```
277
+
278
+ Now that our nodes are accessible we can perform some commands on them.
279
+ The [`run` executable](/docs/executables/run.md) has an extensive CLI to perform many operations on nodes, handling parallel executions, timeouts...
280
+ Here we'll see some of those operations that can save hours of manual operations when a large number of nodes is involved.
281
+
282
+ Run simple commands on all nodes at once, and display them in the output:
283
+ ```bash
284
+ # Execute 1 command on all nodes, using the root user for nodes needing SSH access
285
+ ./bin/run --ssh_user root --all --command "echo Hostname here is \$(hostname)"
286
+ # =>
287
+ # Hostname here is e8dddeb2ba25
288
+ # Hostname here is web1.hpc_tutorial.org
289
+ # Hostname here is web10.hpc_tutorial.org
290
+ # Hostname here is web2.hpc_tutorial.org
291
+ # Hostname here is web3.hpc_tutorial.org
292
+ # Hostname here is web4.hpc_tutorial.org
293
+ # Hostname here is web5.hpc_tutorial.org
294
+ # Hostname here is web6.hpc_tutorial.org
295
+ # Hostname here is web7.hpc_tutorial.org
296
+ # Hostname here is web8.hpc_tutorial.org
297
+ # Hostname here is web9.hpc_tutorial.org
298
+ ```
299
+
300
+ Here a lot has already happened!
301
+ We see that the command has been executed on all nodes: the local node (`e8dddeb2ba25` in this output) and the other web* nodes.
302
+ However, the local node has no SSH access: it uses the [`local` connector plugin](/docs/plugins/connector/local.md), whereas all other nodes use an SSH access with their IP and SSH user root, thanks to the [`ssh` connector plugin](/docs/plugins/connector/ssh.md).
303
+ Connector plugins know which nodes they are able to connect to thanks each node's metadata (in our case `local_node` and `host_ip` metadata were used).
304
+ Thanks to this plugins-oriented architecture, Hybrid Platforms Conductor is able to run the same command on all those nodes in the same interface.
305
+
306
+ What if our commands are long and verbose, and we want to execute them in parallel?
307
+ Use the `--parallel` switch, and commands will be run in parallel, dumping the output in files inside the `./run_logs` directory:
308
+ ```bash
309
+ ./bin/run --ssh_user root --all --command "echo Hostname here is \$(hostname)" --parallel
310
+ # =>
311
+ # Executing actions [100%] - | C| - [ Queue: 0 - Processing: 0 - Done: 11 - Total: 11 ]
312
+
313
+ ls -la run_logs
314
+ # total 52
315
+ # drwxr-xr-x 2 root root 4096 Apr 28 14:44 .
316
+ # drwxr-xr-x 6 root root 4096 Apr 28 13:10 ..
317
+ # -rw-r--r-- 1 root root 30 Apr 28 14:51 local.stdout
318
+ # -rw-r--r-- 1 root root 39 Apr 28 14:51 web1.stdout
319
+ # -rw-r--r-- 1 root root 40 Apr 28 14:51 web10.stdout
320
+ # -rw-r--r-- 1 root root 39 Apr 28 14:51 web2.stdout
321
+ # -rw-r--r-- 1 root root 39 Apr 28 14:51 web3.stdout
322
+ # -rw-r--r-- 1 root root 39 Apr 28 14:51 web4.stdout
323
+ # -rw-r--r-- 1 root root 39 Apr 28 14:51 web5.stdout
324
+ # -rw-r--r-- 1 root root 39 Apr 28 14:51 web6.stdout
325
+ # -rw-r--r-- 1 root root 39 Apr 28 14:51 web7.stdout
326
+ # -rw-r--r-- 1 root root 39 Apr 28 14:51 web8.stdout
327
+ # -rw-r--r-- 1 root root 39 Apr 28 14:51 web9.stdout
328
+
329
+ cat run_logs/web4.stdout
330
+ # => Hostname here is web4.hpc_tutorial.org
331
+ ```
332
+
333
+ The [`ssh` connector plugin](/docs/plugins/connector/ssh.md) allows us to not use the `--ssh_user` parameter if we set the `hpc_ssh_user` environment variable.
334
+ Let's do it to avoid having to repeat our SSH user on any command line needing it:
335
+ ```bash
336
+ export hpc_ssh_user=root
337
+ ```
338
+
339
+ What if we want to run commands on a subset of nodes?
340
+ You can select nodes based on their name, regular expressions, nodes lists they belong to, services they contain...
341
+ Check the [`run`](/docs/executables/run.md) documentation on `./bin/run --help` for more details.
342
+
343
+ Here are some examples:
344
+ ```bash
345
+ # Run only on 1 node
346
+ ./bin/run --command "echo Hostname here is \$(hostname)" --node web4
347
+ # =>
348
+ # Hostname here is web4.hpc_tutorial.org
349
+
350
+ # Run on several nodes
351
+ ./bin/run --command "echo Hostname here is \$(hostname)" --node web4 --node web8
352
+ # =>
353
+ # Hostname here is web4.hpc_tutorial.org
354
+ # Hostname here is web8.hpc_tutorial.org
355
+
356
+ # Run on nodes selected with regular expressions
357
+ ./bin/run --command "echo Hostname here is \$(hostname)" --node /web\[135\].*/
358
+ # =>
359
+ # Hostname here is web1.hpc_tutorial.org
360
+ # Hostname here is web10.hpc_tutorial.org
361
+ # Hostname here is web3.hpc_tutorial.org
362
+ # Hostname here is web5.hpc_tutorial.org
363
+
364
+ # Run on nodes selected by their service
365
+ ./bin/run --command "echo Hostname here is \$(hostname)" --node-service my-service
366
+ # =>
367
+ # Hostname here is e8dddeb2ba25
368
+ ```
369
+
370
+ What if we have several commands to execute?
371
+ ```bash
372
+ # Several commands specifid in command line arguments
373
+ ./bin/run --node /web\[135\].*/ --command "echo Hostname here is" --command hostname
374
+ # =>
375
+ # Hostname here is
376
+ # web1.hpc_tutorial.org
377
+ # Hostname here is
378
+ # web10.hpc_tutorial.org
379
+ # Hostname here is
380
+ # web3.hpc_tutorial.org
381
+ # Hostname here is
382
+ # web5.hpc_tutorial.org
383
+
384
+ # Run commands from a file
385
+ cat <<EOF >my_commands.bash
386
+ echo Hostname here is
387
+ hostname
388
+ EOF
389
+ ./bin/run --node /web\[135\].*/ --commands-file my_commands.bash
390
+ # =>
391
+ # Hostname here is
392
+ # web1.hpc_tutorial.org
393
+ # Hostname here is
394
+ # web10.hpc_tutorial.org
395
+ # Hostname here is
396
+ # web3.hpc_tutorial.org
397
+ # Hostname here is
398
+ # web5.hpc_tutorial.org
399
+ ```
400
+
401
+ So now you already have powerful tools to operate a large number of nodes and platforms, and automate such operations.
402
+
403
+ Let's apply this to manually change the configuration of our first 5 web servers, and return `Hello Mars!` instead of `Hello World!`.
404
+ ```bash
405
+ ./bin/run --node /web\[1-5\]\$/ --command 'echo Hello Mars! >/root/hello_world.txt'
406
+ ```
407
+
408
+ And check that the web servers have indeed changed their response, using our test script:
409
+ ```bash
410
+ ~/hpc_tutorial/web_docker_image/test.bash
411
+ # =>
412
+ # Container web1: Hello Mars!
413
+ # Container web2: Hello Mars!
414
+ # Container web3: Hello Mars!
415
+ # Container web4: Hello Mars!
416
+ # Container web5: Hello Mars!
417
+ # Container web6: Hello World!
418
+ # Container web7: Hello World!
419
+ # Container web8: Hello World!
420
+ # Container web9: Hello World!
421
+ # Container web10: Hello World!
422
+ ```
423
+
424
+ Now let's use more DevOps processes than manual changes.
425
+
426
+ <a name="check-deploy"></a>
427
+ ## Check and deploy our web services on several nodes at once
428
+
429
+ Now that we have plenty of web services, let's add a way to configure the services there.
430
+ We'll add a new service file in our configuration that can change the hello world message, and include the hostname and IP address of the host.
431
+
432
+ We add configuration methods that check and deploy the `web-hello` service (we follow the same logic as for our `my-service` service - using the `check` and `deploy` methods):
433
+ ```bash
434
+ cat <<EOF >~/hpc_tutorial/my-service-conf-repo/service_web-hello.rb
435
+ # Get actions to check the node's service against the wanted content
436
+ #
437
+ # Parameters::
438
+ # * *node* (String): Node on which we check the service
439
+ # Result::
440
+ # * Array< Hash<Symbol,Object> >: The list of actions
441
+ def check(node)
442
+ # We first dump the wanted content in a temporary file and then we diff it.
443
+ # We will access the node's planet, hostname and IP from its metadata using the NodesHandler API, through the @nodes_handler object
444
+ [
445
+ {
446
+ remote_bash: <<~EOS
447
+ echo 'Hello #{@nodes_handler.get_planet_of(node) || 'World'} from #{@nodes_handler.get_hostname_of(node)} (#{@nodes_handler.get_host_ip_of(node)})' >/tmp/hello_world.txt.wanted
448
+ echo Diffs on hello_world.txt:
449
+ if test -f /root/hello_world.txt; then
450
+ diff /root/hello_world.txt /tmp/hello_world.txt.wanted || true
451
+ else
452
+ echo "Create hello_world.txt from scratch"
453
+ cat /tmp/hello_world.txt.wanted
454
+ fi
455
+ EOS
456
+ }
457
+ ]
458
+ end
459
+
460
+ # Get actions to deploy the node's service against the wanted content
461
+ #
462
+ # Parameters::
463
+ # * *node* (String): Node on which we deploy the service
464
+ # Result::
465
+ # * Array< Hash<Symbol,Object> >: The list of actions
466
+ def deploy(node)
467
+ # We first check, as this will display diffs and prepare the file to be copied.
468
+ # And then we really deploy the file on our node.
469
+ check(node) + [
470
+ {
471
+ remote_bash: <<~EOS
472
+ mkdir -p ~/hpc_tutorial/node
473
+ cp /tmp/hello_world.txt.wanted /root/hello_world.txt
474
+ EOS
475
+ }
476
+ ]
477
+ end
478
+ EOF
479
+ ```
480
+
481
+ We can check that our service is correctly defined by issuing a simple [`check-node`](/docs/executables/check-node.md) on one of the web nodes:
482
+ ```bash
483
+ ./bin/check-node --node web1
484
+ # =>
485
+ # ===== Packaging deployment ==== Begin...
486
+ # ===== Packaging deployment ==== ...End
487
+ #
488
+ # ===== Checking on 1 nodes ==== Begin...
489
+ # ===== [ web1 / web-hello ] - HPC Service Check ===== Begin
490
+ # ===== [ web1 / web-hello ] - HPC Service Check ===== Begin
491
+ # Diffs on hello_world.txt:
492
+ # 1c1
493
+ # < Hello Mars!
494
+ # ---
495
+ # > Hello World from web1.hpc_tutorial.org (172.17.0.4)
496
+ # ===== [ web1 / web-hello ] - HPC Service Check ===== End
497
+ # ===== [ web1 / web-hello ] - HPC Service Check ===== End
498
+ # Executing actions [100%] - | C| - [ Queue: 0 - Processing: 0 - Done: 1 - Total: 1 ]
499
+ # ===== Checking on 1 nodes ==== ...End
500
+ ```
501
+
502
+ If we want to check several nodes at once, we can use [`deploy`](/docs/executables/deploy.md) with the `--why-run` flag, and any nodes selector that we've seen in the previous tutorial section can also be used here.
503
+
504
+ Example, we want to check the nodes `web4`, `web5` and `web6`:
505
+ ```bash
506
+ ./bin/deploy --why-run --node /web[4-6]/
507
+ # =>
508
+ # ===== Packaging deployment ==== Begin...
509
+ # ===== Packaging deployment ==== ...End
510
+ #
511
+ # ===== Checking on 3 nodes ==== Begin...
512
+ # ===== [ web4 / web-hello ] - HPC Service Check ===== Begin
513
+ # ===== [ web4 / web-hello ] - HPC Service Check ===== Begin
514
+ # Diffs on hello_world.txt:
515
+ # 1c1
516
+ # < Hello Mars!
517
+ # ---
518
+ # > Hello World from web4.hpc_tutorial.org (172.17.0.7)
519
+ # ===== [ web4 / web-hello ] - HPC Service Check ===== End
520
+ # ===== [ web4 / web-hello ] - HPC Service Check ===== End
521
+ # ===== [ web5 / web-hello ] - HPC Service Check ===== Begin
522
+ # ===== [ web5 / web-hello ] - HPC Service Check ===== Begin
523
+ # Diffs on hello_world.txt:
524
+ # 1c1
525
+ # < Hello Mars!
526
+ # ---
527
+ # > Hello World from web5.hpc_tutorial.org (172.17.0.8)
528
+ # ===== [ web5 / web-hello ] - HPC Service Check ===== End
529
+ # ===== [ web5 / web-hello ] - HPC Service Check ===== End
530
+ # ===== [ web6 / web-hello ] - HPC Service Check ===== Begin
531
+ # ===== [ web6 / web-hello ] - HPC Service Check ===== Begin
532
+ # Diffs on hello_world.txt:
533
+ # 1c1
534
+ # < Hello World!
535
+ # ---
536
+ # > Hello World from web6.hpc_tutorial.org (172.17.0.9)
537
+ # ===== [ web6 / web-hello ] - HPC Service Check ===== End
538
+ # ===== [ web6 / web-hello ] - HPC Service Check ===== End
539
+ # Executing actions [100%] - | C| - [ Queue: 0 - Processing: 0 - Done: 3 - Total: 3 ]
540
+ # ===== Checking on 3 nodes ==== ...End
541
+ ```
542
+ We see clearly the differences that would be applied in case we deploy for real.
543
+
544
+ If you want to execute those in parallel and see outputs in `./run_logs/*.stdout` files, you can use the `--parallel` flag here too!
545
+ ```bash
546
+ ./bin/deploy --why-run --node /web[4-6]/ --parallel
547
+ # =>
548
+ # ===== Packaging deployment ==== Begin...
549
+ # ===== Packaging deployment ==== ...End
550
+ #
551
+ # ===== Checking on 3 nodes ==== Begin...
552
+ # Executing actions [100%] - | C| - [ Queue: 0 - Processing: 0 - Done: 3 - Total: 3 ]
553
+ # Executing actions [100%] - | C| - [ Queue: 0 - Processing: 0 - Done: 3 - Total: 3 ]
554
+ # ===== Checking on 3 nodes ==== ...End
555
+
556
+ cat run_logs/web4.stdout
557
+ # =>
558
+ # ===== [ web4 / web-hello ] - HPC Service Check ===== Begin
559
+ # ===== [ web4 / web-hello ] - HPC Service Check ===== Begin
560
+ # Diffs on hello_world.txt:
561
+ # 1c1
562
+ # < Hello Mars!
563
+ # ---
564
+ # > Hello World from web4.hpc_tutorial.org (172.17.0.7)
565
+ # ===== [ web4 / web-hello ] - HPC Service Check ===== End
566
+ # ===== [ web4 / web-hello ] - HPC Service Check ===== End
567
+ ```
568
+
569
+ So now that we have great ways to check which nodes have diverged, let's deploy a bunch of them and see the result live.
570
+ We'll deploy web2 to web8.
571
+ ```bash
572
+ ./bin/deploy --node /web[2-8]/ --parallel
573
+ ```
574
+
575
+ And then we check the result live:
576
+ ```bash
577
+ ~/hpc_tutorial/web_docker_image/test.bash
578
+ # =>
579
+ # Container web1: Hello Mars!
580
+ # Container web2: Hello World from web2.hpc_tutorial.org (172.17.0.5)
581
+ # Container web3: Hello World from web3.hpc_tutorial.org (172.17.0.6)
582
+ # Container web4: Hello World from web4.hpc_tutorial.org (172.17.0.7)
583
+ # Container web5: Hello World from web5.hpc_tutorial.org (172.17.0.8)
584
+ # Container web6: Hello World from web6.hpc_tutorial.org (172.17.0.9)
585
+ # Container web7: Hello World from web7.hpc_tutorial.org (172.17.0.10)
586
+ # Container web8: Hello World from web8.hpc_tutorial.org (172.17.0.11)
587
+ # Container web9: Hello World!
588
+ # Container web10: Hello World!
589
+ ```
590
+ We see that only web services from 2 to 8 have been deployed.
591
+
592
+ By the way, remember the [`last_deploys` executable](/docs/executables/last_deploys.md)?
593
+ Time to check the new deployment there too.
594
+
595
+ ```bash
596
+ ./bin/last_deploys
597
+ # =>
598
+ # [...]
599
+ # +-------+---------------------+-------+------------+-------------------------------------------------------------------------------------------------------------------------------------+
600
+ # | Node | Date | Admin | Services | Error |
601
+ # +-------+---------------------+-------+------------+-------------------------------------------------------------------------------------------------------------------------------------+
602
+ # | web1 | | | | Error: failed_command |
603
+ # | | | | | /bin/bash: line 1: cd: /var/log/deployments: No such file or directory |
604
+ # | | | | | Command '/tmp/hpc_ssh/platforms_ssh_5120020210428-1741-15weu1h/ssh hpc.web1 /bin/bash <<'EOF'' returned error code 1 (expected 0). |
605
+ # | web10 | | | | Error: failed_command |
606
+ # | | | | | /bin/bash: line 1: cd: /var/log/deployments: No such file or directory |
607
+ # | | | | | Command '/tmp/hpc_ssh/platforms_ssh_5120020210428-1741-15weu1h/ssh hpc.web10 /bin/bash <<'EOF'' returned error code 1 (expected 0). |
608
+ # | web9 | | | | Error: failed_command |
609
+ # | | | | | /bin/bash: line 1: cd: /var/log/deployments: No such file or directory |
610
+ # | | | | | Command '/tmp/hpc_ssh/platforms_ssh_5120020210428-1741-15weu1h/ssh hpc.web9 /bin/bash <<'EOF'' returned error code 1 (expected 0). |
611
+ # | local | 2021-04-27 17:09:44 | root | my-service | |
612
+ # | web2 | 2021-04-28 16:58:06 | root | web-hello | |
613
+ # | web3 | 2021-04-28 16:58:06 | root | web-hello | |
614
+ # | web4 | 2021-04-28 16:58:06 | root | web-hello | |
615
+ # | web5 | 2021-04-28 16:58:06 | root | web-hello | |
616
+ # | web6 | 2021-04-28 16:58:06 | root | web-hello | |
617
+ # | web7 | 2021-04-28 16:58:06 | root | web-hello | |
618
+ # | web8 | 2021-04-28 16:58:06 | root | web-hello | |
619
+ # +-------+---------------------+-------+------------+-------------------------------------------------------------------------------------------------------------------------------------+
620
+ ```
621
+ Some nodes haven't been deployed yet, so they return errors when trying to read deployment logs.
622
+ However we can clearly see on the other nodes that deployment was done a few seconds ago.
623
+
624
+ ### Check and deploy all our nodes with various services at once
625
+
626
+ Now it's time to get even further: we also want to make some web services nodes implement our very first service `my-service` (remember the service configuring the file `~/hpc_tutorial/node/my-service.conf`).
627
+
628
+ This operation will only require to alter our inventory: we add the services we want on the nodes we want, with the metadata we want.
629
+ No need to change any configuration code.
630
+
631
+ Let's say we want the `my-service` service to be implemented in web services from web1 to web5, and that we want to assign different planets in those web services as well.
632
+ We will change our inventory file that will look like that in the end (see the various services and metadata changed):
633
+ ```bash
634
+ cat <<EOF >~/hpc_tutorial/my-service-conf-repo/inventory.yaml
635
+ ---
636
+ local:
637
+ metadata:
638
+ description: The local environment
639
+ local_node: true
640
+ service_port: 1107
641
+ service_timeout: 60
642
+ services:
643
+ - my-service
644
+ web1:
645
+ metadata:
646
+ description: Web service nbr 1
647
+ hostname: web1.hpc_tutorial.org
648
+ planet: Mercury
649
+ service_port: 1201
650
+ service_timeout: 60
651
+ services:
652
+ - web-hello
653
+ - my-service
654
+ web2:
655
+ metadata:
656
+ description: Web service nbr 2
657
+ hostname: web2.hpc_tutorial.org
658
+ planet: Venus
659
+ service_port: 1202
660
+ service_timeout: 60
661
+ services:
662
+ - web-hello
663
+ - my-service
664
+ web3:
665
+ metadata:
666
+ description: Web service nbr 3
667
+ hostname: web3.hpc_tutorial.org
668
+ planet: Earth
669
+ service_port: 1203
670
+ service_timeout: 60
671
+ services:
672
+ - web-hello
673
+ - my-service
674
+ web4:
675
+ metadata:
676
+ description: Web service nbr 4
677
+ hostname: web4.hpc_tutorial.org
678
+ planet: Mars
679
+ service_port: 1204
680
+ service_timeout: 60
681
+ services:
682
+ - web-hello
683
+ - my-service
684
+ web5:
685
+ metadata:
686
+ description: Web service nbr 5
687
+ hostname: web5.hpc_tutorial.org
688
+ planet: Jupiter
689
+ service_port: 1205
690
+ service_timeout: 60
691
+ services:
692
+ - web-hello
693
+ - my-service
694
+ web6:
695
+ metadata:
696
+ description: Web service nbr 6
697
+ hostname: web6.hpc_tutorial.org
698
+ services:
699
+ - web-hello
700
+ web7:
701
+ metadata:
702
+ description: Web service nbr 7
703
+ hostname: web7.hpc_tutorial.org
704
+ services:
705
+ - web-hello
706
+ web8:
707
+ metadata:
708
+ description: Web service nbr 8
709
+ hostname: web8.hpc_tutorial.org
710
+ services:
711
+ - web-hello
712
+ web9:
713
+ metadata:
714
+ description: Web service nbr 9
715
+ hostname: web9.hpc_tutorial.org
716
+ services:
717
+ - web-hello
718
+ web10:
719
+ metadata:
720
+ description: Web service nbr 10
721
+ hostname: web10.hpc_tutorial.org
722
+ # The list of service names this node should have
723
+ services:
724
+ - web-hello
725
+ EOF
726
+ ```
727
+
728
+ We can check that services are assigned correctly using [`report`](/docs/executables/report.md):
729
+ ```bash
730
+ ./bin/report
731
+ # =>
732
+ # +-------+----------------------+------------------------+-------------+-----------+----+-----------------------+-----------------------+
733
+ # | Node | Platform | Host name | IP | Physical? | OS | Description | Services |
734
+ # +-------+----------------------+------------------------+-------------+-----------+----+-----------------------+-----------------------+
735
+ # | local | my-service-conf-repo | | | No | | The local environment | my-service |
736
+ # | web1 | my-service-conf-repo | web1.hpc_tutorial.org | 172.17.0.4 | No | | Web service nbr 1 | my-service, web-hello |
737
+ # | web10 | my-service-conf-repo | web10.hpc_tutorial.org | 172.17.0.13 | No | | Web service nbr 10 | web-hello |
738
+ # | web2 | my-service-conf-repo | web2.hpc_tutorial.org | 172.17.0.5 | No | | Web service nbr 2 | my-service, web-hello |
739
+ # | web3 | my-service-conf-repo | web3.hpc_tutorial.org | 172.17.0.6 | No | | Web service nbr 3 | my-service, web-hello |
740
+ # | web4 | my-service-conf-repo | web4.hpc_tutorial.org | 172.17.0.7 | No | | Web service nbr 4 | my-service, web-hello |
741
+ # | web5 | my-service-conf-repo | web5.hpc_tutorial.org | 172.17.0.8 | No | | Web service nbr 5 | my-service, web-hello |
742
+ # | web6 | my-service-conf-repo | web6.hpc_tutorial.org | 172.17.0.9 | No | | Web service nbr 6 | web-hello |
743
+ # | web7 | my-service-conf-repo | web7.hpc_tutorial.org | 172.17.0.10 | No | | Web service nbr 7 | web-hello |
744
+ # | web8 | my-service-conf-repo | web8.hpc_tutorial.org | 172.17.0.11 | No | | Web service nbr 8 | web-hello |
745
+ # | web9 | my-service-conf-repo | web9.hpc_tutorial.org | 172.17.0.12 | No | | Web service nbr 9 | web-hello |
746
+ # +-------+----------------------+------------------------+-------------+-----------+----+-----------------------+-----------------------+
747
+ ```
748
+ Some nodes are having several services.
749
+
750
+ Without changing anything else, we can check all those services on all nodes with 1 command line:
751
+ ```bash
752
+ ./bin/deploy --why-run --all --parallel
753
+ # =>
754
+ # ===== Packaging deployment ==== Begin...
755
+ # ===== Packaging deployment ==== ...End
756
+ #
757
+ # ===== Checking on 11 nodes ==== Begin...
758
+ # Executing actions [100%] - | C| - [ Queue: 0 - Processing: 0 - Done: 11 - Total: 11 ]
759
+ # Executing actions [100%] - | C| - [ Queue: 0 - Processing: 0 - Done: 11 - Total: 11 ]
760
+ # ===== Checking on 11 nodes ==== ...End
761
+ #
762
+
763
+ # Check the diffs and files creations from run_logs
764
+ ls run_logs/* | xargs grep -e Create -e '>'
765
+ # =>
766
+ # run_logs/web1.stdout:> Hello Mercury from web1.hpc_tutorial.org (172.17.0.4)
767
+ # run_logs/web1.stdout:Create file from scratch
768
+ # run_logs/web10.stdout:> Hello World from web10.hpc_tutorial.org (172.17.0.13)
769
+ # run_logs/web2.stdout:> Hello Venus from web2.hpc_tutorial.org (172.17.0.5)
770
+ # run_logs/web2.stdout:Create file from scratch
771
+ # run_logs/web3.stdout:> Hello Earth from web3.hpc_tutorial.org (172.17.0.6)
772
+ # run_logs/web3.stdout:Create file from scratch
773
+ # run_logs/web4.stdout:> Hello Mars from web4.hpc_tutorial.org (172.17.0.7)
774
+ # run_logs/web4.stdout:Create file from scratch
775
+ # run_logs/web5.stdout:> Hello Jupiter from web5.hpc_tutorial.org (172.17.0.8)
776
+ # run_logs/web5.stdout:Create file from scratch
777
+ # run_logs/web9.stdout:> Hello World from web9.hpc_tutorial.org (172.17.0.12)
778
+ ```
779
+ We see that `my-service` file will be created from scratch on `web1-5`, and the Hello World message of `web-hello` service will be corrected on `web1-5`, `web9` and `web10`.
780
+
781
+ This is typically the kind of situation that can occur often when the nodes are being maintained manually, or have suffered from local and temporary modifications by operators to cope with urgencies.
782
+
783
+ Now that we are happy with the review of those changes, we can align all our services on all our nodes:
784
+ ```bash
785
+ ./bin/deploy --all --parallel
786
+ # =>
787
+ # ===== Packaging deployment ==== Begin...
788
+ # ===== Packaging deployment ==== ...End
789
+ #
790
+ # ===== Deploying on 11 nodes ==== Begin...
791
+ # Executing actions [100%] - | C| - [ Queue: 0 - Processing: 0 - Done: 11 - Total: 11 ]
792
+ # Executing actions [100%] - | C| - [ Queue: 0 - Processing: 0 - Done: 11 - Total: 11 ]
793
+ # ===== Saving deployment logs for 11 nodes ==== Begin...
794
+ # Executing actions [100%] - | C| - [ Queue: 0 - Processing: 0 - Done: 11 - Total: 11 ]
795
+ # ===== Saving deployment logs for 11 nodes ==== ...End
796
+ #
797
+ # ===== Deploying on 11 nodes ==== ...End
798
+ ```
799
+
800
+ And we can perform all the checks to make sure the deployment went smoothly:
801
+ ```bash
802
+ ./bin/last_deploys
803
+ # =>
804
+ # +-------+---------------------+-------+-----------------------+-------+
805
+ # | Node | Date | Admin | Services | Error |
806
+ # +-------+---------------------+-------+-----------------------+-------+
807
+ # | local | 2021-04-28 17:34:17 | root | my-service | |
808
+ # | web1 | 2021-04-28 17:34:17 | root | web-hello, my-service | |
809
+ # | web10 | 2021-04-28 17:34:17 | root | web-hello | |
810
+ # | web2 | 2021-04-28 17:34:17 | root | web-hello, my-service | |
811
+ # | web3 | 2021-04-28 17:34:17 | root | web-hello, my-service | |
812
+ # | web4 | 2021-04-28 17:34:17 | root | web-hello, my-service | |
813
+ # | web5 | 2021-04-28 17:34:17 | root | web-hello, my-service | |
814
+ # | web6 | 2021-04-28 17:34:17 | root | web-hello | |
815
+ # | web7 | 2021-04-28 17:34:17 | root | web-hello | |
816
+ # | web8 | 2021-04-28 17:34:17 | root | web-hello | |
817
+ # | web9 | 2021-04-28 17:34:17 | root | web-hello | |
818
+ # +-------+---------------------+-------+-----------------------+-------+
819
+
820
+ # Check the configuration of web-hello services
821
+ ~/hpc_tutorial/web_docker_image/test.bash
822
+ # =>
823
+ # Container web1: Hello Mercury from web1.hpc_tutorial.org (172.17.0.4)
824
+ # Container web2: Hello Venus from web2.hpc_tutorial.org (172.17.0.5)
825
+ # Container web3: Hello Earth from web3.hpc_tutorial.org (172.17.0.6)
826
+ # Container web4: Hello Mars from web4.hpc_tutorial.org (172.17.0.7)
827
+ # Container web5: Hello Jupiter from web5.hpc_tutorial.org (172.17.0.8)
828
+ # Container web6: Hello World from web6.hpc_tutorial.org (172.17.0.9)
829
+ # Container web7: Hello World from web7.hpc_tutorial.org (172.17.0.10)
830
+ # Container web8: Hello World from web8.hpc_tutorial.org (172.17.0.11)
831
+ # Container web9: Hello World from web9.hpc_tutorial.org (172.17.0.12)
832
+ # Container web10: Hello World from web10.hpc_tutorial.org (172.17.0.13)
833
+
834
+ # Check which node has the my-service file configured
835
+ ./bin/run --all --command "echo \$(hostname) - \$(ls /root/hpc_tutorial/node/my-service.conf 2>/dev/null)"
836
+ # e8dddeb2ba25 - /root/hpc_tutorial/node/my-service.conf
837
+ # web1.hpc_tutorial.org - /root/hpc_tutorial/node/my-service.conf
838
+ # web10.hpc_tutorial.org -
839
+ # web2.hpc_tutorial.org - /root/hpc_tutorial/node/my-service.conf
840
+ # web3.hpc_tutorial.org - /root/hpc_tutorial/node/my-service.conf
841
+ # web4.hpc_tutorial.org - /root/hpc_tutorial/node/my-service.conf
842
+ # web5.hpc_tutorial.org - /root/hpc_tutorial/node/my-service.conf
843
+ # web6.hpc_tutorial.org -
844
+ # web7.hpc_tutorial.org -
845
+ # web8.hpc_tutorial.org -
846
+ # web9.hpc_tutorial.org -
847
+
848
+ # Check that there is nothing else to be changed on all our nodes
849
+ ./bin/deploy --why-run --all --parallel
850
+ ls run_logs/* | xargs grep -e Create -e '>'
851
+ # =>
852
+ ```
853
+
854
+ **Woot!**
855
+ You managed to:
856
+ * configure **different services on several nodes using different technologies** (local connection, using SSH, on Docker),
857
+ * **running commands, checking and deploying configuration on those nodes using the same simple 1-liners interface**, despite those nodes running on different technologies,
858
+ * **change the distribution and configuration** of your services and nodes only by editing your inventory and metadata,
859
+ * **track and check easily** all your deployments.
860
+
861
+ This already gives you powerful tools to **manage heterogeneous platforms and environments at scale** and empower the agility of your DevOps processes.
862
+
863
+ Next steps are about testing your processes and configurations so that you have very simple ways to monitor when they break, and integrate those tests in CI/CD-like workflows.
864
+
865
+ **[Next >> Test your processes and platforms](/docs/tutorial/04_test.md)**
866
+
867
+ ---
868
+ **<p style="text-align: center;">Tutorial navigation</p>**
869
+
870
+ | <sub>[Introduction](/docs/tutorial.md)</sub> | <sub>[1. Installation and first-time setup](/docs/tutorial/01_installation.md)</sub> | <sub>[2. Deploy and check a first node](/docs/tutorial/02_first_node.md)</sub> | <nobr><sub><sub>&#128071;You are here&#128071;</sub></sub></nobr><br><sub>[3. Scale your processes](/docs/tutorial/03_scale.md)</sub> | <sub>[4. Testing your processes and platforms](/docs/tutorial/04_test.md)</sub> | <sub>[5. Extend Hybrid Platforms Conductor with your own requirements](/docs/tutorial/05_extend_with_plugins.md)</sub> |
871
+ | ---------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------- |
872
+ | <sub><sub>**[Use-case](/docs/tutorial.md#use-case)**</sub></sub> | <sub><sub>**[Dependencies installation](/docs/tutorial/01_installation.md#hpc-dependencies)**</sub></sub> | <sub><sub>**[Add your first node and its platform repository](/docs/tutorial/02_first_node.md#add-first-node)**</sub></sub> | <sub><sub>**[Provision our web services platform](/docs/tutorial/03_scale.md#provision)**</sub></sub> | <sub><sub>**[Hello test framework](/docs/tutorial/04_test.md#framework)**</sub></sub> | <sub><sub>**[Create your plugins' repository](/docs/tutorial/05_extend_with_plugins.md#plugins-repo)**</sub></sub> |
873
+ | <sub><sub>**[Prerequisites](/docs/tutorial.md#prerequisites)**</sub></sub> | <sub><sub>**[Our platforms' main repository](/docs/tutorial/01_installation.md#main-repo)**</sub></sub> | <sub><sub>**[Check and deploy services on this node](/docs/tutorial/02_first_node.md#check-deploy)**</sub></sub> | <sub><sub>**[Run commands on our new web services](/docs/tutorial/03_scale.md#run)**</sub></sub> | <sub><sub>**[Testing your nodes](/docs/tutorial/04_test.md#nodes-tests)**</sub></sub> | <sub><sub>**[Your own platform handler](/docs/tutorial/05_extend_with_plugins.md#platform-handler)**</sub></sub> |
874
+ | <sub><sub>**[Tutorial setup](/docs/tutorial.md#tutorial-setup)**</sub></sub> | | <sub><sub>**[Updating the configuration](/docs/tutorial/02_first_node.md#update)**</sub></sub> | <sub><sub>**[Check and deploy our web services on several nodes at once](/docs/tutorial/03_scale.md#check-deploy)**</sub></sub> | <sub><sub>**[Testing your platforms' configuration](/docs/tutorial/04_test.md#platforms-tests)**</sub></sub> | <sub><sub>**[Write your own tests](/docs/tutorial/05_extend_with_plugins.md#test)**</sub></sub> |
875
+ | | | | | <sub><sub>**[Other kinds of tests](/docs/tutorial/04_test.md#other-tests)**</sub></sub> | <sub><sub>**[Enough of stdout, we want to report to other tools](/docs/tutorial/05_extend_with_plugins.md#report)**</sub></sub> |
876
+ | | | | | | <sub><sub>**[What next?](/docs/tutorial/05_extend_with_plugins.md#what-next)**</sub></sub> |