Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

kickstart with pod examples #1

Merged
merged 24 commits into from
Jan 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
c06ff54
Add @nethserver/ns8-ui-lib dependency
stephdl Jan 5, 2024
c64bd44
Update copyright year and configure module settings
stephdl Jan 5, 2024
d73e1ec
Update translation.json with new fields and labels
stephdl Jan 5, 2024
78d0e7c
Update image labels in build script
stephdl Jan 5, 2024
43b85aa
Update README.md with configuration and debugging instructions
stephdl Jan 5, 2024
869ad9e
Add symlink for traefik module
stephdl Jan 5, 2024
7ecc238
Add script to copy environment variables
stephdl Jan 5, 2024
07e0b09
Add script to configure Traefik virtual host
stephdl Jan 5, 2024
99aad8d
Add systemd service and enable it
stephdl Jan 5, 2024
d3b44c5
Add hostname validation in configure-module script
stephdl Jan 5, 2024
7c793fe
Add configure_environment_vars script
stephdl Jan 5, 2024
a688c93
Remove configure-module script
stephdl Jan 5, 2024
dd55c1e
Add script to configure Traefik module
stephdl Jan 5, 2024
e962794
Add error handling and redirect output to journal
stephdl Jan 5, 2024
69c5777
Update configure-module input schema
stephdl Jan 5, 2024
3643033
Refactor configuration reading and add environment variable support
stephdl Jan 5, 2024
44a8a0a
Update get-configuration output schema
stephdl Jan 5, 2024
fa6e4f3
Add state-include.conf for Restic backup
stephdl Jan 5, 2024
8bc399a
Add kickstart-app.service systemd unit file
stephdl Jan 5, 2024
c9fcd24
Update kickstart.service to use Podman and fix copyright year
stephdl Jan 5, 2024
06f5f18
Add systemd service file for mariadb-app
stephdl Jan 5, 2024
2f84a60
Add restart script for kickstart service
stephdl Jan 5, 2024
442d10c
Update traefik configuration and remove systemd script
stephdl Jan 5, 2024
b0bf775
Update translation.json
stephdl Jan 5, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 80 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,25 +41,42 @@ Output example:

## Configure

Let's assume that the kickstart instance is named `kickstart1`.
Let's assume that the mattermost instance is named `kickstart1`.

Launch `configure-module`, by setting the following parameters:
- `<MODULE_PARAM1_NAME>`: <MODULE_PARAM1_DESCRIPTION>
- `<MODULE_PARAM2_NAME>`: <MODULE_PARAM2_DESCRIPTION>
- ...
- `host`: a fully qualified domain name for the application
- `http2https`: enable or disable HTTP to HTTPS redirection (true/false)
- `lets_encrypt`: enable or disable Let's Encrypt certificate (true/false)


Example:

api-cli run module/kickstart1/configure-module --data '{}'
```
api-cli run configure-module --agent module/kickstart1 --data - <<EOF
{
"host": "kickstart.domain.com",
"http2https": true,
"lets_encrypt": false
}
EOF
```

The above command will:
- start and configure the kickstart instance
- (describe configuration process)
- ...
- configure a virtual host for trafik to access the instance

## Get the configuration
You can retrieve the configuration with

Send a test HTTP request to the kickstart backend service:
```
api-cli run get-configuration --agent module/kickstart1
```

## Uninstall

curl http://127.0.0.1/kickstart/
To uninstall the instance:

remove-module --no-preserve kickstart1

## Smarthost setting discovery

Expand All @@ -80,12 +97,60 @@ See also the `systemd/user/kickstart.service` file.
This setting discovery is just an example to understand how the module is
expected to work: it can be rewritten or discarded completely.

## Uninstall

To uninstall the instance:

remove-module --no-preserve kickstart1

## Debug

some CLI are needed to debug

- The module runs under an agent that initiate a lot of environment variables (in /home/kickstart1/.config/state), it could be nice to verify them
on the root terminal

`runagent -m kickstart1 env`

- you can become runagent for testing scripts and initiate all environment variables

`runagent -m kickstart1`

the path become :
```
echo $PATH
/home/kickstart1/.config/bin:/usr/local/agent/pyenv/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/usr/
```

- if you want to debug a container or see environment inside
`runagent -m kickstart1`
```
podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d292c6ff28e9 localhost/podman-pause:4.6.1-1702418000 9 minutes ago Up 9 minutes 127.0.0.1:20015->80/tcp 80b8de25945f-infra
d8df02bf6f4a docker.io/library/mariadb:10.11.5 --character-set-s... 9 minutes ago Up 9 minutes 127.0.0.1:20015->80/tcp mariadb-app
9e58e5bd676f docker.io/library/nginx:stable-alpine3.17 nginx -g daemon o... 9 minutes ago Up 9 minutes 127.0.0.1:20015->80/tcp kickstart-app
```

you can see what environment variable is inside the container
```
podman exec kickstart-app env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
TERM=xterm
PKG_RELEASE=1
MARIADB_DB_HOST=127.0.0.1
MARIADB_DB_NAME=kickstart
MARIADB_IMAGE=docker.io/mariadb:10.11.5
MARIADB_DB_TYPE=mysql
container=podman
NGINX_VERSION=1.24.0
NJS_VERSION=0.7.12
MARIADB_DB_USER=kickstart
MARIADB_DB_PASSWORD=kickstart
MARIADB_DB_PORT=3306
HOME=/root
```

you can run a shell inside the container

```
podman exec -ti kickstart-app sh
/ #
```
## Testing

Test the module using the `test-module.sh` script:
Expand Down
8 changes: 7 additions & 1 deletion build-images.sh
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,17 @@ buildah run \
buildah add "${container}" imageroot /imageroot
buildah add "${container}" ui/dist /ui
# Setup the entrypoint, ask to reserve one TCP port with the label and set a rootless container
# Select you image(s) with the label org.nethserver.images
# ghcr.io/xxxxx is the GitHub container registry or your own registry or docker.io for Docker Hub
# The image tag is set to latest by default, but can be overridden with the IMAGETAG environment variable
# --label="org.nethserver.images=docker.io/mariadb:10.11.5 docker.io/roundcube/roundcubemail:1.6.4-apache"
# rootfull=0 === rootless container
# tcp-ports-demand=1 number of tcp Port to reserve , 1 is the minimum, can be udp or tcp
buildah config --entrypoint=/ \
--label="org.nethserver.authorizations=traefik@node:routeadm" \
--label="org.nethserver.tcp-ports-demand=1" \
--label="org.nethserver.rootfull=0" \
--label="org.nethserver.images=docker.io/jmalloc/echo-server:latest" \
--label="org.nethserver.images=docker.io/mariadb:10.11.5 docker.io/nginx:stable-alpine3.17" \
"${container}"
# Commit the image
buildah commit "${container}" "${repobase}/${reponame}"
Expand Down
1 change: 1 addition & 0 deletions imageroot/actions/clone-module/50traefik
29 changes: 29 additions & 0 deletions imageroot/actions/configure-module/01Hostname_validation
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#!/usr/bin/env python3

#
# Copyright (C) 2023 Nethesis S.r.l.
# SPDX-License-Identifier: GPL-3.0-or-later
#

import os
import sys
import json
import agent
import urllib.request
import urllib.error
import ssl

agent.set_weight(os.path.basename(__file__), 0) # Validation step, no task progress at all

# retrieve json data
data = json.load(sys.stdin)

# Setup default values
host = data.get("host")
# do not test if it is the same host
oldHost = os.environ.get('TRAEFIK_HOST','')

if host != oldHost and agent.http_route_in_use(domain=host):
agent.set_status('validation-failed')
json.dump([{'field':'host','parameter':'host','value':host,'error':'domain_already_used_in_traefik'}],fp=sys.stdout)
sys.exit(2)
33 changes: 33 additions & 0 deletions imageroot/actions/configure-module/10configure_environment_vars
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#!/usr/bin/env python3

#
# Copyright (C) 2022 Nethesis S.r.l.
# SPDX-License-Identifier: GPL-3.0-or-later
#

import json
import sys
import agent

# Try to parse the stdin as JSON.
# If parsing fails, output everything to stderr
data = json.load(sys.stdin)

#This is specific to you module, so you need to change it accordingly.
# we read a json stdin {"vars1":true, "var2":"foo", "vars3": 3} and we writ it to .config/state/environment
# Upper case to set environment variable and minor case to read from stdin

# this values must exists in the json stdin
# agent.set_env("MAIL_SERVER", data["mail_server"])
# agent.set_env("LDAP_DOMAIN", data["ldap_domain"])

# you can add default values for the following variables
# agent.set_env("MAIL_DOMAIN",data.get("mail_domain",""))
# agent.set_env("WOWORKERSCOUNT",data.get("workers_count",3))
# agent.set_env("AUXILIARYACCOUNT",data.get("auxiliary_account",True))
# agent.set_env("ACTIVESYNC",data.get("activesync",False))


# Make sure everything is saved inside the environment file
# just before starting systemd unit
#agent.dump_env()
34 changes: 0 additions & 34 deletions imageroot/actions/configure-module/20configure

This file was deleted.

51 changes: 51 additions & 0 deletions imageroot/actions/configure-module/20configure_traefik
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#!/usr/bin/env python3

#
# Copyright (C) 2022 Nethesis S.r.l.
# SPDX-License-Identifier: GPL-3.0-or-later
#

import json
import sys
import agent
import agent.tasks
import os

# Try to parse the stdin as JSON.
# If parsing fails, output everything to stderr
data = json.load(sys.stdin)

# Setup default values
host = data.get("host")
h2hs = data.get("http2https", True)
le = data.get("lets_encrypt", False)

# Talk with agent using file descriptor.
# Setup configuration from user input.
agent.set_env("TRAEFIK_HOST", host)
agent.set_env("TRAEFIK_HTTP2HTTPS", h2hs)
agent.set_env("TRAEFIK_LETS_ENCRYPT", le)

# Make sure everything is saved inside the environment file
# just before starting systemd unit
agent.dump_env()

# Find default traefik instance for current node
default_traefik_id = agent.resolve_agent_id('traefik@node')
if default_traefik_id is None:
sys.exit(2)

response = agent.tasks.run(
agent_id=agent.resolve_agent_id('traefik@node'),
action='set-route',
data={
'instance': os.environ['MODULE_ID'],
'url': 'http://127.0.0.1:' + os.environ["TCP_PORT"],
'host': host,
'http2https': h2hs,
'lets_encrypt': le
},
)

# Check if traefik configuration has been successfull
agent.assert_exp(response['exit_code'] == 0)
4 changes: 4 additions & 0 deletions imageroot/actions/configure-module/80start_services
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
# Copyright (C) 2023 Nethesis S.r.l.
# SPDX-License-Identifier: GPL-3.0-or-later
#
set -e

# Redirect any output to the journal (stderr)
exec 1>&2

# If the control reaches this step, the service can be enabled and started

Expand Down
36 changes: 32 additions & 4 deletions imageroot/actions/configure-module/validate-input.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,36 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "configure-module input",
"$id": "http://schema.nethserver.org/kickstart/configure-module-input.json",
"title": "Configure kickstart",
"$id": "http://nethserver.org/json-schema/task/input/kickstart/configure-module",
"description": "Configure kickstart",
"examples": [],
"type": "object"
"examples": [
{
"host": "kickstart.domain.org",
"http2https": true,
"lets_encrypt": true
}
],
"type": "object",
"required": [
"host",
"http2https",
"lets_encrypt"
],
"properties": {
"host": {
"type": "string",
"description": "Host name for the application, like 'kickstart.domain.org'",
"format": "idn-hostname"
},
"lets_encrypt": {
"type": "boolean",
"title": "Let's Encrypt certificate",
"description": "Request a valid Let's Encrypt certificate."
},
"http2https": {
"type": "boolean",
"title": "HTTP to HTTPS redirection",
"description": "Redirect all the HTTP requests to HTTPS"
}
}
}
16 changes: 14 additions & 2 deletions imageroot/actions/get-configuration/20read
Original file line number Diff line number Diff line change
@@ -1,14 +1,26 @@
#!/usr/bin/env python3

#
# Copyright (C) 2023 Nethesis S.r.l.
# Copyright (C) 2022 Nethesis S.r.l.
# SPDX-License-Identifier: GPL-3.0-or-later
#

import json
#
# Read configuration
#

import os
import sys
import json
import agent

# Prepare return variable
config = {}

# Read current configuration from the environment file
config["host"] = os.getenv("TRAEFIK_HOST","")
config["http2https"] = os.getenv("TRAEFIK_HTTP2HTTPS") == "True"
config["lets_encrypt"] = os.getenv("TRAEFIK_LETS_ENCRYPT") == "True"

# Dump the configuration to stdout
json.dump(config, fp=sys.stdout)
Loading
Loading