Skip to content

Commit

Permalink
terra ansi done, slowly doing python, some problems with superset
Browse files Browse the repository at this point in the history
  • Loading branch information
szachovy committed Oct 10, 2024
1 parent 2c2066f commit 0a92cb8
Show file tree
Hide file tree
Showing 19 changed files with 340 additions and 134 deletions.
2 changes: 2 additions & 0 deletions .flake8
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[flake8]
max-line-length = 120
16 changes: 8 additions & 8 deletions services/mysql-mgmt/docker_compose.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
---
services:
initcontainer:
build: "."
image: "mysql-mgmt"
image: "ghcr.io/szachovy/superset-cluster-mysql-mgmt:latest"
user: "root"
container_name: "mysql-mgmt-initcontainer"
network_mode: "host"
Expand All @@ -12,7 +11,7 @@ services:
- "/bin/bash"
- "-c"
- |
set -euxo pipefail
set -euo pipefail
export MYSQL_SUPERSET_PASSWORD=$(</run/secrets/mysql_superset_password)
if ! mysqlsh \
--login-path="${PRIMARY_MYSQL_NODE}" \
Expand Down Expand Up @@ -98,22 +97,23 @@ services:
- "mysql_superset_password"

maincontainer:
image: "mysql-mgmt"
image: "ghcr.io/szachovy/superset-cluster-mysql-mgmt:latest"
pull_policy: "always"
user: "superset"
entrypoint:
- "/bin/bash"
- "-c"
- |
set -euxo pipefail
set -euo pipefail
sudo keepalived --use-file "/opt/default/keepalived.conf"
sleep ${HEALTHCHECK_START_PERIOD}
mysqlrouter --config "/opt/default/mysql_router/mysqlrouter.conf" &
tail --follow /opt/default/mysql_router/log/mysqlrouter.log
tail --follow --verbose /opt/default/mysql_router/log/*.log
container_name: "mysql-mgmt"
restart: "always"
restart: "on-failure"
network_mode: "host"
healthcheck:
test: ["CMD", "sh", "-c", "[ $(pgrep -c mysqlrouter) -eq 1 ] && [ $(pgrep -c keepalived) -eq 2 ]"]
test: ["CMD", "sh", "-c", "[ $(pgrep --full --count 'mysqlrouter --config /opt/default/mysql_router/mysqlrouter.conf') -eq 1 ] && [ $(pgrep --count keepalived) -eq 2 ]"]
interval: "${HEALTHCHECK_INTERVAL}s"
timeout: "5s"
retries: "${HEALTHCHECK_RETRIES}"
Expand Down
15 changes: 9 additions & 6 deletions services/mysql-mgmt/interfaces.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,16 @@ def network_interfaces(network_interface: str) -> str | StopIteration:
if clib.getifaddrs(ctypes.pointer(network_interfaces)) == 0:
current_interface: network_interface_structure = network_interfaces.contents
while True:
if current_interface.network_interface_name == network_interface.encode() and current_interface.network_interface_data:
if current_interface.network_interface_name == network_interface.encode() \
and current_interface.network_interface_data:
if current_interface.network_interface_address.contents.socket_address_family == 2:
return socket.inet_ntop(socket.AF_INET,
ctypes.cast(ctypes.pointer(current_interface.network_interface_address.contents),
ctypes.POINTER(socket_interface)
).contents.socket_interface_address
)
return socket.inet_ntop(
socket.AF_INET,
ctypes.cast(
ctypes.pointer(current_interface.network_interface_address.contents),
ctypes.POINTER(socket_interface)
).contents.socket_interface_address
)
if not current_interface.next_network_interface:
clib.freeifaddrs(network_interfaces)
raise StopIteration(f'Provided network interface {network_interface} not found.')
Expand Down
16 changes: 11 additions & 5 deletions services/mysql-mgmt/keepalived.conf.tpl
Original file line number Diff line number Diff line change
@@ -1,28 +1,34 @@

global_defs {
vrrp_startup_delay 15
log_file "/opt/default/mysql_router/log/keepalived.log"
enable_traps
}

vrrp_script status {
script "/bin/killall -0 mysqlrouter"
interval 2
interval 1
weight 2
}

vrrp_instance virtual_instance {
state ${STATE}
interface ${VIRTUAL_NETWORK_INTERFACE}
state "${STATE}"
interface "${VIRTUAL_NETWORK_INTERFACE}"
virtual_router_id 51
priority ${PRIORITY}
advert_int 1
nopreempt
garp_master_delay 2
track_script {
status
}
track_interface {
"${VIRTUAL_NETWORK_INTERFACE}"
}
virtual_ipaddress {
${VIRTUAL_IP_ADDRESS}/${VIRTUAL_NETWORK_MASK}
"${VIRTUAL_IP_ADDRESS}/${VIRTUAL_NETWORK_MASK}"
}
virtual_routes {
${VIRTUAL_NETWORK} src ${VIRTUAL_IP_ADDRESS} metric 1 dev ${VIRTUAL_NETWORK_INTERFACE} scope link
"${VIRTUAL_NETWORK}" src "${VIRTUAL_IP_ADDRESS}" metric 1 dev "${VIRTUAL_NETWORK_INTERFACE}" scope link
}
}
2 changes: 2 additions & 0 deletions services/mysql-server/mysql_config.cnf.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,5 @@ ssl-ca = "/etc/mysql/ssl/superset_cluster_ca_certificate.pem"
ssl-cert = "/etc/mysql/ssl/mysql_server_certificate.pem"
ssl-key = "/etc/mysql/ssl/mysql_server_key.pem"
require_secure_transport = "ON"
max_connections = "50"
max_connect_errors = "50"
15 changes: 7 additions & 8 deletions services/mysql-server/seccomp.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
{
"defaultAction": "SCMP_ACT_ALLOW",
"architectures": [
"SCMP_ARCH_X86_64"
"SCMP_ARCH_X86_64"
],
"syscalls": [
{
"names": [
"kill"
],
"action": "SCMP_ACT_ERRNO"
}
]
{
"names": [
"kill"
],
"action": "SCMP_ACT_ERRNO"
}]
}
44 changes: 12 additions & 32 deletions services/mysql-server/store_credentials.exp
Original file line number Diff line number Diff line change
Expand Up @@ -2,41 +2,21 @@

log_user 0

set node1 [lindex $argv 0]
set node2 [lindex $argv 1]
set node3 [lindex $argv 2]
set timeout 10
set mysql_root_password [exec cat "/var/run/mysqld/mysql_root_password"]
set filepath $env(MYSQL_TEST_LOGIN_FILE)

spawn mysql_config_editor set \
--login-path=$node1 \
--host=$node1 \
--user=root \
--skip-warn \
--password

expect "Enter password:"
send "$mysql_root_password\r"

spawn mysql_config_editor set \
--login-path=$node2 \
--host=$node2 \
--user=root \
--skip-warn \
--password

expect "Enter password:"
send "$mysql_root_password\r"

spawn mysql_config_editor set \
--login-path=$node3 \
--host=$node3 \
--user=root \
--skip-warn \
--password

expect "Enter password:"
send "$mysql_root_password\r"
foreach node $argv {
spawn mysql_config_editor set \
--login-path=$node \
--host=$node \
--user=root \
--skip-warn \
--password

expect "Enter password:"
send "$mysql_root_password\r"
}

expect eof

Expand Down
7 changes: 6 additions & 1 deletion services/superset/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ RUN \
superset:superset \
"/var/lib/nginx" \
"/var/log/nginx" \
"/app" \
&& \
apt-get \
clean \
Expand All @@ -58,6 +57,7 @@ ENTRYPOINT [ "/bin/bash", "-c", " \
--recursive \
superset:superset \
/etc/ssl/certs \
/app \
&& \
gosu \
superset \
Expand All @@ -67,5 +67,10 @@ ENTRYPOINT [ "/bin/bash", "-c", " \
gosu \
superset \
/app/entrypoint.sh \
&& \
chown \
--recursive \
root:root \
/app \
" \
]
8 changes: 6 additions & 2 deletions services/superset/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
#!/bin/bash

set -euxo pipefail

if superset test_db \
"mysql+mysqlconnector://superset:$(cat /run/secrets/mysql_superset_password)@${VIRTUAL_IP_ADDRESS}:6446/superset" \
"mysql+mysqlconnector://superset:$(< /run/secrets/mysql_superset_password)@${VIRTUAL_IP_ADDRESS}:6446/superset" \
--connect-args {}; then

superset fab create-admin \
Expand All @@ -21,7 +23,9 @@ if superset test_db \
--app superset.tasks.celery_app:app worker \
--pool prefork \
--concurrency 4 \
-O fair
-O fair &

wait
else
echo "Could not connect to the MySQL database"
exit 1
Expand Down
39 changes: 34 additions & 5 deletions services/superset/set_database_uri.exp
Original file line number Diff line number Diff line change
@@ -1,9 +1,38 @@
#!/usr/bin/expect -f

spawn superset shell
expect ">>>"
send "import mysql_connect; mysql_connect.create_mysql_connection();\n"
expect ">>>"
send "exit()\n"
set timeout 10

if {[catch {spawn superset shell} result]} {
puts "Failed to start the Superset shell: $result"
exit 1
}

expect {
">>>" {
send "import mysql_connect; mysql_connect.create_mysql_connection()\n"
}
timeout {
puts "Timeout while waiting for Superset shell prompt to create MySQL database connection"
exit 1
}
eof {
puts "Superset shell prompt to create MySQL database connection terminated unexpectedly"
exit 1
}
}

expect {
">>>" {
send "exit()\n"
}
timeout {
puts "Timeout while waiting for Superset shell prompt to create MySQL database connection"
exit 1
}
eof {
puts "Superset shell prompt to create MySQL database connection terminated unexpectedly"
exit 1
}
}

expect eof
17 changes: 10 additions & 7 deletions services/superset/superset_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import flask_caching.backends.rediscache
import os


class CeleryConfig(object):
broker_url = "redis://redis:6379/0"
imports = (
Expand All @@ -17,17 +18,19 @@ class CeleryConfig(object):
},
}

with open('/run/secrets/superset_secret_key', 'r') as superset_secret_key:

with open("/run/secrets/superset_secret_key", "r") as superset_secret_key:
SECRET_KEY = superset_secret_key.read().strip()

with open('/run/secrets/mysql_superset_password', 'r') as mysql_superset_password:

with open("/run/secrets/mysql_superset_password", "r") as mysql_superset_password:
SQLALCHEMY_DATABASE_URI = f"mysql+mysqlconnector://superset:{mysql_superset_password.read().strip()}@{os.environ.get('VIRTUAL_IP_ADDRESS')}:6446/superset"

CELERY_CONFIG = CeleryConfig
RESULTS_BACKEND = flask_caching.backends.rediscache.RedisCache(host="redis", port=6379, key_prefix='superset_results')
RESULTS_BACKEND = flask_caching.backends.rediscache.RedisCache(host="redis", port=6379, key_prefix="superset_results")
FILTER_STATE_CACHE_CONFIG = {
'CACHE_TYPE': 'RedisCache',
'CACHE_DEFAULT_TIMEOUT': 86400,
'CACHE_KEY_PREFIX': 'superset_filter_cache',
'CACHE_REDIS_URL': "redis://redis:6379/0"
"CACHE_TYPE": "RedisCache",
"CACHE_DEFAULT_TIMEOUT": 86400,
"CACHE_KEY_PREFIX": "superset_filter_cache",
"CACHE_REDIS_URL": "redis://redis:6379/0"
}
15 changes: 12 additions & 3 deletions src/container.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import abc


class ContainerInstance(abc.ABC):
@abc.abstractmethod
def run(self):
Expand Down Expand Up @@ -80,7 +81,15 @@ def decode_command_output(command: bytes) -> dict | ValueError:

def get_logs(self):
if self.container == 'superset':
return self.client.containers.get(self.client.containers.list(filters={"name": "superset"})[0].name).logs().decode('utf-8')
try:
return self.client.containers.get(self.client.containers.list(filters={"name": "superset"})[0].name).logs().decode('utf-8')
except IndexError:
return 'Container superset has not been spawned by the service.'
if self.container == 'mysql-mgmt':
container_log: str = self.client.containers.get('mysql-mgmt-initcontainer').logs().decode('utf-8') + '\n\n'
if 'mysql-mgmt' in self.client.containers.list(all=True):
container_log += self.client.containers.get(self.container).logs().decode('utf-8')
return container_log
return self.client.containers.get(self.container).logs().decode('utf-8')

def wait_until_healthy(self, cls: typing.Type[ContainerInstance]) -> str:
Expand All @@ -94,7 +103,7 @@ def wait_until_healthy(self, cls: typing.Type[ContainerInstance]) -> str:
if self.client.containers.get(self.container).attrs['State']['Health']['Status'] == 'healthy':
return f'{self.get_logs()}\nContainer {self.container} is healthy'
time.sleep(cls.healthcheck_interval)
return f'{self.get_logs()}\nTimeout while waiting for {self.container} healthcheck'
return f'{self.get_logs()}\nTimeout while waiting for {self.container} healthcheck to be healthy'

def run_mysql_server(self) -> None:
class MySQL_Server(ContainerInstance):
Expand Down Expand Up @@ -298,7 +307,7 @@ def create_mysql_superset_password_secret(self)-> str:
def run(self) -> None:
self.client.services.create(
name="superset",
image="ghcr.io/szachovy/superset-cluster-service:latest",
image="ghcr.io/szachovy/superset-cluster-superset-service:latest",
networks=["superset-network"],
secrets = [
docker.types.SecretReference(secret_id=self.create_superset_secret_key_secret(), secret_name="superset_secret_key"),
Expand Down
5 changes: 4 additions & 1 deletion src/remote.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,10 @@ def __init__(self, node: str) -> None:
except (paramiko.ssh_exception.SSHException, socket.gaierror):
self.ssh_config = paramiko.SSHConfig()
self.ssh_config.parse(open(f'{pathlib.Path.home()}/.ssh/config'))
self.ssh_client.connect(hostname=self.node_hostname(), username='superset', key_filename=self.identity_path())
try:
self.ssh_client.connect(hostname=self.node_hostname(), username='superset', key_filename=self.identity_path())
except KeyError:
logger.error(f'Unable to connect to {self.node} from the localhost')
self.sftp_client = self.ssh_client.open_sftp()

def log_remote_command_execution(func):
Expand Down
Loading

0 comments on commit 0a92cb8

Please sign in to comment.