hybrid_platforms_conductor 32.11.0 → 32.13.1
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/CHANGELOG.md +1109 -0
- data/LICENSE.md +31 -0
- data/README.md +395 -0
- data/bin/setup +1 -1
- data/docs/api.md +349 -0
- data/docs/config_dsl.md +315 -0
- data/docs/executables.md +226 -0
- data/docs/executables/check-node.md +155 -0
- data/docs/executables/deploy.md +198 -0
- data/docs/executables/dump_nodes_json.md +110 -0
- data/docs/executables/free_ips.md +93 -0
- data/docs/executables/free_veids.md +73 -0
- data/docs/executables/get_impacted_nodes.md +94 -0
- data/docs/executables/last_deploys.md +114 -0
- data/docs/executables/nodes_to_deploy.md +139 -0
- data/docs/executables/report.md +159 -0
- data/docs/executables/run.md +126 -0
- data/docs/executables/setup.md +92 -0
- data/docs/executables/ssh_config.md +151 -0
- data/docs/executables/test.md +213 -0
- data/docs/executables/topograph.md +139 -0
- data/docs/gen/mermaid/README.md-0.png +0 -0
- data/docs/gen/mermaid/docs/executables/check-node.md-0.png +0 -0
- data/docs/gen/mermaid/docs/executables/deploy.md-0.png +0 -0
- data/docs/gen/mermaid/docs/executables/free_ips.md-0.png +0 -0
- data/docs/gen/mermaid/docs/executables/free_veids.md-0.png +0 -0
- data/docs/gen/mermaid/docs/executables/get_impacted_nodes.md-0.png +0 -0
- data/docs/gen/mermaid/docs/executables/last_deploys.md-0.png +0 -0
- data/docs/gen/mermaid/docs/executables/nodes_to_deploy.md-0.png +0 -0
- data/docs/gen/mermaid/docs/executables/report.md-0.png +0 -0
- data/docs/gen/mermaid/docs/executables/run.md-0.png +0 -0
- data/docs/gen/mermaid/docs/executables/setup.md-0.png +0 -0
- data/docs/gen/mermaid/docs/executables/ssh_config.md-0.png +0 -0
- data/docs/gen/mermaid/docs/executables/test.md-0.png +0 -0
- data/docs/install.md +161 -0
- data/docs/plugins.md +215 -0
- data/docs/plugins/action/bash.md +37 -0
- data/docs/plugins/action/interactive.md +37 -0
- data/docs/plugins/action/remote_bash.md +67 -0
- data/docs/plugins/action/ruby.md +69 -0
- data/docs/plugins/action/scp.md +61 -0
- data/docs/plugins/cmdb/config.md +46 -0
- data/docs/plugins/cmdb/host_ip.md +33 -0
- data/docs/plugins/cmdb/host_keys.md +33 -0
- data/docs/plugins/cmdb/platform_handlers.md +33 -0
- data/docs/plugins/connector/local.md +28 -0
- data/docs/plugins/connector/ssh.md +95 -0
- data/docs/plugins/platform_handler/yaml_inventory.md +105 -0
- data/docs/plugins/provisioner/docker.md +27 -0
- data/docs/plugins/provisioner/podman.md +27 -0
- data/docs/plugins/provisioner/proxmox.md +115 -0
- data/docs/plugins/report/confluence.md +49 -0
- data/docs/plugins/report/mediawiki.md +28 -0
- data/docs/plugins/report/stdout.md +32 -0
- data/docs/plugins/test/bitbucket_conf.md +97 -0
- data/docs/plugins/test/can_be_checked.md +27 -0
- data/docs/plugins/test/check_deploy_and_idempotence.md +61 -0
- data/docs/plugins/test/check_from_scratch.md +28 -0
- data/docs/plugins/test/connection.md +27 -0
- data/docs/plugins/test/deploy_freshness.md +27 -0
- data/docs/plugins/test/deploy_from_scratch.md +28 -0
- data/docs/plugins/test/deploy_removes_root_access.md +29 -0
- data/docs/plugins/test/divergence.md +41 -0
- data/docs/plugins/test/executables.md +26 -0
- data/docs/plugins/test/file_system.md +49 -0
- data/docs/plugins/test/file_system_hdfs.md +65 -0
- data/docs/plugins/test/hostname.md +27 -0
- data/docs/plugins/test/idempotence.md +56 -0
- data/docs/plugins/test/ip.md +28 -0
- data/docs/plugins/test/jenkins_ci_conf.md +54 -0
- data/docs/plugins/test/jenkins_ci_masters_ok.md +54 -0
- data/docs/plugins/test/linear_strategy.md +26 -0
- data/docs/plugins/test/local_users.md +48 -0
- data/docs/plugins/test/mounts.md +55 -0
- data/docs/plugins/test/orphan_files.md +38 -0
- data/docs/plugins/test/ports.md +50 -0
- data/docs/plugins/test/private_ips.md +27 -0
- data/docs/plugins/test/public_ips.md +27 -0
- data/docs/plugins/test/spectre.md +26 -0
- data/docs/plugins/test/veids.md +27 -0
- data/docs/plugins/test/vulnerabilities.md +65 -0
- data/docs/plugins/test_report/confluence.md +43 -0
- data/docs/plugins/test_report/stdout.md +26 -0
- data/docs/plugins_create.md +135 -0
- data/docs/tutorial.md +61 -0
- data/docs/tutorial/01_installation.md +129 -0
- data/docs/tutorial/02_first_node.md +466 -0
- data/docs/tutorial/03_scale.md +876 -0
- data/docs/tutorial/04_test.md +975 -0
- data/docs/tutorial/05_extend_with_plugins.md +1130 -0
- data/examples/bare/Gemfile +4 -0
- data/examples/bare/hpc_config.rb +2 -0
- data/examples/localhost/Gemfile +4 -0
- data/examples/localhost/hpc_config.rb +2 -0
- data/examples/localhost/inventory.yaml +4 -0
- data/examples/tutorial/01_installation/my-platforms/Gemfile +3 -0
- data/examples/tutorial/01_installation/my-platforms/hpc_config.rb +0 -0
- data/examples/tutorial/02_first_node/my-platforms/Gemfile +3 -0
- data/examples/tutorial/02_first_node/my-platforms/hpc_config.rb +1 -0
- data/examples/tutorial/02_first_node/my-service-conf-repo/inventory.yaml +13 -0
- data/examples/tutorial/02_first_node/my-service-conf-repo/my-service.conf.erb +3 -0
- data/examples/tutorial/02_first_node/my-service-conf-repo/service_my-service.rb +58 -0
- data/examples/tutorial/02_first_node/node/my-service.conf +4 -0
- data/examples/tutorial/03_scale/my-platforms/Gemfile +3 -0
- data/examples/tutorial/03_scale/my-platforms/hpc_config.rb +1 -0
- data/examples/tutorial/03_scale/my-platforms/my_commands.bash +2 -0
- data/examples/tutorial/03_scale/my-service-conf-repo/inventory.yaml +90 -0
- data/examples/tutorial/03_scale/my-service-conf-repo/my-service.conf.erb +3 -0
- data/examples/tutorial/03_scale/my-service-conf-repo/service_my-service.rb +58 -0
- data/examples/tutorial/03_scale/my-service-conf-repo/service_web-hello.rb +43 -0
- data/examples/tutorial/03_scale/node/my-service.conf +4 -0
- data/examples/tutorial/03_scale/web_docker_image/Dockerfile +33 -0
- data/examples/tutorial/03_scale/web_docker_image/hello_world.txt +1 -0
- data/examples/tutorial/03_scale/web_docker_image/hpc_root.key +27 -0
- data/examples/tutorial/03_scale/web_docker_image/hpc_root.key.pub +1 -0
- data/examples/tutorial/03_scale/web_docker_image/main.go +43 -0
- data/examples/tutorial/03_scale/web_docker_image/start.sh +7 -0
- data/examples/tutorial/03_scale/web_docker_image/test.bash +6 -0
- data/examples/tutorial/04_test/my-platforms/Gemfile +3 -0
- data/examples/tutorial/04_test/my-platforms/hpc_config.rb +12 -0
- data/examples/tutorial/04_test/my-platforms/images/debian_10/Dockerfile +13 -0
- data/examples/tutorial/04_test/my-platforms/my_commands.bash +2 -0
- data/examples/tutorial/04_test/my-service-conf-repo/inventory.yaml +100 -0
- data/examples/tutorial/04_test/my-service-conf-repo/my-service.conf.erb +3 -0
- data/examples/tutorial/04_test/my-service-conf-repo/service_my-service.rb +58 -0
- data/examples/tutorial/04_test/my-service-conf-repo/service_web-hello.rb +43 -0
- data/examples/tutorial/04_test/node/my-service.conf +4 -0
- data/examples/tutorial/04_test/web_docker_image/Dockerfile +33 -0
- data/examples/tutorial/04_test/web_docker_image/hello_world.txt +1 -0
- data/examples/tutorial/04_test/web_docker_image/hpc_root.key +27 -0
- data/examples/tutorial/04_test/web_docker_image/hpc_root.key.pub +1 -0
- data/examples/tutorial/04_test/web_docker_image/main.go +43 -0
- data/examples/tutorial/04_test/web_docker_image/start.sh +7 -0
- data/examples/tutorial/04_test/web_docker_image/test.bash +6 -0
- data/examples/tutorial/05_extend_with_plugins/dev-servers-conf-repo/hosts.json +12 -0
- data/examples/tutorial/05_extend_with_plugins/dev-servers-conf-repo/install-gcc.bash +14 -0
- data/examples/tutorial/05_extend_with_plugins/dev-servers-conf-repo/install-python.bash +14 -0
- data/examples/tutorial/05_extend_with_plugins/dev_docker_image/Dockerfile +20 -0
- data/examples/tutorial/05_extend_with_plugins/dev_docker_image/hpc_root.key +27 -0
- data/examples/tutorial/05_extend_with_plugins/dev_docker_image/hpc_root.key.pub +1 -0
- data/examples/tutorial/05_extend_with_plugins/my-platforms/Gemfile +4 -0
- data/examples/tutorial/05_extend_with_plugins/my-platforms/hpc_config.rb +13 -0
- data/examples/tutorial/05_extend_with_plugins/my-platforms/images/debian_10/Dockerfile +13 -0
- data/examples/tutorial/05_extend_with_plugins/my-platforms/my_commands.bash +2 -0
- data/examples/tutorial/05_extend_with_plugins/my-service-conf-repo/inventory.yaml +100 -0
- data/examples/tutorial/05_extend_with_plugins/my-service-conf-repo/my-service.conf.erb +3 -0
- data/examples/tutorial/05_extend_with_plugins/my-service-conf-repo/service_my-service.rb +58 -0
- data/examples/tutorial/05_extend_with_plugins/my-service-conf-repo/service_web-hello.rb +43 -0
- data/examples/tutorial/05_extend_with_plugins/my_hpc_plugins/lib/my_hpc_plugins/hpc_plugins/platform_handler/json_bash.rb +115 -0
- data/examples/tutorial/05_extend_with_plugins/my_hpc_plugins/lib/my_hpc_plugins/hpc_plugins/report/web_report.rb +52 -0
- data/examples/tutorial/05_extend_with_plugins/my_hpc_plugins/lib/my_hpc_plugins/hpc_plugins/test/root_space.rb +44 -0
- data/examples/tutorial/05_extend_with_plugins/my_hpc_plugins/my_hpc_plugins.gemspec +15 -0
- data/examples/tutorial/05_extend_with_plugins/node/my-service.conf +4 -0
- data/examples/tutorial/05_extend_with_plugins/web_docker_image/Dockerfile +33 -0
- data/examples/tutorial/05_extend_with_plugins/web_docker_image/hello_world.txt +1 -0
- data/examples/tutorial/05_extend_with_plugins/web_docker_image/hpc_root.key +27 -0
- data/examples/tutorial/05_extend_with_plugins/web_docker_image/hpc_root.key.pub +1 -0
- data/examples/tutorial/05_extend_with_plugins/web_docker_image/main.go +43 -0
- data/examples/tutorial/05_extend_with_plugins/web_docker_image/start.sh +7 -0
- data/examples/tutorial/05_extend_with_plugins/web_docker_image/test.bash +6 -0
- data/lib/hybrid_platforms_conductor/actions_executor.rb +1 -0
- data/lib/hybrid_platforms_conductor/deployer.rb +3 -2
- data/lib/hybrid_platforms_conductor/hpc_plugins/action/remote_bash.rb +29 -13
- data/lib/hybrid_platforms_conductor/hpc_plugins/action/scp.rb +1 -1
- data/lib/hybrid_platforms_conductor/hpc_plugins/connector/local.rb +98 -0
- data/lib/hybrid_platforms_conductor/hpc_plugins/connector/my_connector.rb.sample +2 -2
- data/lib/hybrid_platforms_conductor/hpc_plugins/connector/ssh.rb +15 -4
- data/lib/hybrid_platforms_conductor/hpc_plugins/platform_handler/platform_handler_plugin.rb.sample +5 -5
- data/lib/hybrid_platforms_conductor/hpc_plugins/platform_handler/yaml_inventory.rb +140 -0
- data/lib/hybrid_platforms_conductor/hpc_plugins/provisioner/proxmox.rb +6 -3
- data/lib/hybrid_platforms_conductor/hpc_plugins/report/templates/confluence_inventory.html.erb +1 -1
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/bitbucket_conf.rb +4 -4
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/deploy_freshness.rb +1 -1
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/deploy_removes_root_access.rb +19 -17
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/divergence.rb +3 -0
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/executables.rb +27 -13
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/hostname.rb +2 -1
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/ip.rb +2 -1
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/local_users.rb +2 -1
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/mounts.rb +4 -3
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/orphan_files.rb +2 -1
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/spectre.rb +1 -1
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/vulnerabilities.rb +8 -7
- data/lib/hybrid_platforms_conductor/hpc_plugins/test_report/confluence.rb +1 -1
- data/lib/hybrid_platforms_conductor/hpc_plugins/test_report/templates/confluence.html.erb +1 -1
- data/lib/hybrid_platforms_conductor/json_dumper.rb +1 -1
- data/lib/hybrid_platforms_conductor/platform_handler.rb +1 -1
- data/lib/hybrid_platforms_conductor/services_handler.rb +18 -16
- data/lib/hybrid_platforms_conductor/tests_runner.rb +0 -1
- data/lib/hybrid_platforms_conductor/topographer.rb +0 -1
- data/lib/hybrid_platforms_conductor/version.rb +1 -1
- data/spec/hybrid_platforms_conductor_test/api/actions_executor/actions/remote_bash_spec.rb +16 -0
- data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/local/connectable_nodes_spec.rb +30 -0
- data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/local/remote_actions_spec.rb +113 -0
- data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/ssh/cli_options_spec.rb +6 -2
- data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/ssh/global_helpers_spec.rb +38 -1
- data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/ssh/remote_actions_spec.rb +37 -4
- data/spec/hybrid_platforms_conductor_test/docs_spec.rb +10 -0
- data/tools/check_md +89 -0
- data/tools/generate_mermaid +75 -0
- metadata +337 -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>👇You are here👇</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>👇You are here👇</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> |
|