From 108b42eb98470897bd1bae4bb0430fd15f683e47 Mon Sep 17 00:00:00 2001 From: Adam JOLY Date: Tue, 7 Jan 2025 16:01:49 +0100 Subject: [PATCH] =?UTF-8?q?=E3=80=8C=F0=9F=8F=97=EF=B8=8F=E3=80=8D=20wip(M?= =?UTF-8?q?ariadb-entry):=20entrypoint=20starting=20to=20work?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Makefile | 8 +- cmd/mariadb-entry/mariadb-entry.go | 14 --- cmd/mariadb/entrypoint/entrypoint.go | 117 +++++++++++++++++++++++++ cmd/mariadb/entrypoint/setupEnv.go | 5 ++ cmd/mariadb/healthcheck/healthcheck.go | 36 ++++++++ configs/mariadb/docker.cnf | 8 ++ docker-compose.yml | 14 ++- docker/mariadb/Dockerfile | 33 ++++--- go.mod | 5 ++ go.sum | 4 + internal/env/env_util.go | 34 +++++++ internal/log/log.go | 20 +++++ 12 files changed, 266 insertions(+), 32 deletions(-) delete mode 100644 cmd/mariadb-entry/mariadb-entry.go create mode 100644 cmd/mariadb/entrypoint/entrypoint.go create mode 100644 cmd/mariadb/entrypoint/setupEnv.go create mode 100644 cmd/mariadb/healthcheck/healthcheck.go create mode 100644 configs/mariadb/docker.cnf create mode 100644 go.sum create mode 100644 internal/env/env_util.go create mode 100644 internal/log/log.go diff --git a/Makefile b/Makefile index 376ac1b..b078281 100644 --- a/Makefile +++ b/Makefile @@ -8,11 +8,13 @@ DOCKERFILE_DB := $(DOCKER_FOLDER)/$(DB_SERVER_NAME)/Dockerfile DOCKERFILE_WEVSRV := $(DOCKER_FOLDER)/$(WEB_SERVER_NAME)/Dockerfile DOCKERFILE_CMS := $(DOCKER_FOLDER)/$(CMS_NAME)/Dockerfile -mariadb-build: +db-build: docker build -f $(DOCKERFILE_DB) -t $(DB_SERVER_NAME) . -nginx-build: +websrv-build: docker build -f $(DOCKERFILE_WEVSRV) -t $(WEB_SERVER_NAME) . -wp-build: +cms-build: docker build -f $(DOCKERFILE_CMS) -t $(CMS_NAME) . + +.PHONY: cms-build db-build websrv-build diff --git a/cmd/mariadb-entry/mariadb-entry.go b/cmd/mariadb-entry/mariadb-entry.go deleted file mode 100644 index 0019acb..0000000 --- a/cmd/mariadb-entry/mariadb-entry.go +++ /dev/null @@ -1,14 +0,0 @@ -package main - -import ( - "fmt" - "os" -) - -func main() { - args := os.Args - - for _, v := range args { - fmt.Println(v) - } -} diff --git a/cmd/mariadb/entrypoint/entrypoint.go b/cmd/mariadb/entrypoint/entrypoint.go new file mode 100644 index 0000000..e89fb1a --- /dev/null +++ b/cmd/mariadb/entrypoint/entrypoint.go @@ -0,0 +1,117 @@ +package main + +import ( + "errors" + "fmt" + "log" + "os" + "os/exec" + "time" + + "git.keyzox.me/42_adjoly/inception/internal/env" + "git.keyzox.me/42_adjoly/inception/internal/log" +) + +func createDBDir(dataDir string) { + if dataDir == "/var/lib/mysql" { + return + } + err := os.Mkdir(dataDir, 750) + if err != nil { + log.Fatal(err) + } + err = os.Mkdir(dataDir+"/.already", 750) + if err != nil { + log.Fatal(err) + } +} + +func checkOlderDB(dataDir string) bool { + if _, err := os.Stat(dataDir+"/.already"); errors.Is(err, os.ErrNotExist) { + return false + } + return true +} + +func waitForMariaDB() { + for i := 0; i < 30; i++ { + cmd := exec.Command("mysql", "-uroot", "-e", "SELECT 1") + if err := cmd.Run(); err == nil { + return + } + fmt.Println("MariaDB init process in progress...") + time.Sleep(1 * time.Second) + } + fmt.Println("MariaDB init process failed.") + os.Exit(1) +} + +func configureMariaDB(rootPassword, user, password, database string) { + cmd := exec.Command("mysql", "-uroot", "-e", fmt.Sprintf(` + ALTER USER 'root'@'localhost' IDENTIFIED BY '%s'; + CREATE DATABASE IF NOT EXISTS %s; + CREATE USER IF NOT EXISTS '%s'@'%%' IDENTIFIED BY '%s'; + GRANT ALL PRIVILEGES ON %s.* TO '%s'@'%%'; + FLUSH PRIVILEGES; + `, rootPassword, database, user, password, database, user)) + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + if err := cmd.Run(); err != nil { + fmt.Printf("Error configuring MariaDB: %v\n", err) + os.Exit(1) + } +} + +func main() { + args := os.Args + + + if args[1] == "mariadbd" || args[1] == "mysqld" { + _log.Log("note", "Entrypoint script for MariaDB Server started") + + rootPass := env.FileEnv("MYSQL_ROOT_PASSWORD", "default") + pass := env.FileEnv("MYSQL_PASSWORD", "default") + user := env.FileEnv("MYSQL_USER", "mariadb") + dbName := env.EnvCheck("MYSQL_DATABASE", "default") + dataDir := env.EnvCheck("DATADIR", "/var/lib/mysql") + + oldDB := checkOlderDB(dataDir) + if oldDB == false { + createDBDir(dataDir) + // Init DB + cmd := exec.Command("mariadb-install-db", "--user=mysql", "--ldata="+dataDir) + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + createDBDir(dataDir) + if err := cmd.Run(); err != nil { + _log.Log("error", "Error initializing MariaDB") + } + + // Starting temp mariadb server for config + cmd = exec.Command("mariadbd-safe", "--skip-networking") + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + if err := cmd.Start(); err != nil { + fmt.Printf("Error starting MariaDB: %v\n", err) + os.Exit(1) + } + // Wait for mariadb to start + waitForMariaDB() + + configureMariaDB(rootPass, user, pass, dbName) + + if err := cmd.Process.Kill(); err != nil { + fmt.Printf("Error stopping MariaDB: %v\n", err) + } + } + } + + cmd := exec.Command(args[1], args[2:]...) + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + cmd.Stdin = os.Stdin + if err := cmd.Run(); err != nil { + fmt.Printf("Error running MariaDB: %v\n", err) + os.Exit(1) + } +} diff --git a/cmd/mariadb/entrypoint/setupEnv.go b/cmd/mariadb/entrypoint/setupEnv.go new file mode 100644 index 0000000..5e8510a --- /dev/null +++ b/cmd/mariadb/entrypoint/setupEnv.go @@ -0,0 +1,5 @@ +package main + +import ( + +) diff --git a/cmd/mariadb/healthcheck/healthcheck.go b/cmd/mariadb/healthcheck/healthcheck.go new file mode 100644 index 0000000..a000cb6 --- /dev/null +++ b/cmd/mariadb/healthcheck/healthcheck.go @@ -0,0 +1,36 @@ +package main + +import ( + "database/sql" + "fmt" + + "git.keyzox.me/42_adjoly/inception/internal/env" + "git.keyzox.me/42_adjoly/inception/internal/log" +) + +func checkHealth(host, user, pass, port, dbName string) bool { + dsn := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s", user, pass, host, port, dbName) + + db, err := sql.Open("mysql", dsn) + if err != nil { + _log.Log("error", "Failed to open database connection") + } + defer db.Close() + if err := db.Ping(); err != nil { + _log.Log("error", "Health check failed") + } + return true +} + +func main() { + pass := env.FileEnv("MYSQL_PASSWORD", "default") + user := env.FileEnv("MYSQL_USER", "mariadb") + dbName := env.EnvCheck("MYSQL_DATABASE", "default") + dbHost := "localhost" + + res := checkHealth(dbHost, user, pass, "3306", dbName) + if res == true{ + _log.Log("note", "Mariadb is healthy") + } + _log.Log("error", "Health check failed") +} diff --git a/configs/mariadb/docker.cnf b/configs/mariadb/docker.cnf new file mode 100644 index 0000000..aea3fc6 --- /dev/null +++ b/configs/mariadb/docker.cnf @@ -0,0 +1,8 @@ +[mariadb] +host-cache-size=0 +skip-name-resolve + +expire_logs_days=10 + +!includedir /etc/mysql/mariadb.conf.d +!includedir /etc/mysql/conf.d diff --git a/docker-compose.yml b/docker-compose.yml index f11a271..c5087fe 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,4 +1,3 @@ -version: "3" name: inception volumes: @@ -12,6 +11,9 @@ networks: services: nginx: container_name: inception-nginx + build: + context: . + dockerfile: docker/nginx/Dockerfile networks: - inception environment: @@ -27,6 +29,9 @@ services: wordpress-php: container_name: inception-workp-php + build: + context: . + dockerfile: docker/wordpress/dockerfile networks: - inception environment: @@ -39,9 +44,16 @@ services: db: container_name: inception-db + build: + context: . + dockerfile: docker/mariadb/Dockerfile networks: - inception environment: + - MYSQL_ROOT_PASSWORD="alpine" + - MYSQL_PASSWORD="alpine" + - MYSQL_USER="kanel" + - MYSQL_DATABASE="knl" - TZ=Europe/Paris volumes: - wp-db:/var/lib/mysql diff --git a/docker/mariadb/Dockerfile b/docker/mariadb/Dockerfile index 3e2e413..c4e055e 100644 --- a/docker/mariadb/Dockerfile +++ b/docker/mariadb/Dockerfile @@ -4,34 +4,39 @@ LABEL version="0.1" LABEL maintainer="KeyZox" RUN addgroup mysql \ - && adduser -S -G mysql mysql -h /var/lib/mysql \ - && echo 'permit nopass root as mysql' >> /etc/doas.conf + && adduser -S -G mysql mysql -h /var/lib/mysql RUN mkdir /build COPY go.mod /build/go.mod COPY cmd /build/cmd +COPY internal /build/internal -RUN apk add --no-cache go \ +RUN apk add --no-cache go mariadb tzdata \ && cd /build \ - && go build git.keyzox.me/42_adjoly/inception/cmd/mariadb-entry \ - && cp /build/mariadb-entry /mariadb-entry \ + && go build git.keyzox.me/42_adjoly/inception/cmd/mariadb/entrypoint \ + && go build git.keyzox.me/42_adjoly/inception/cmd/mariadb/healthcheck \ + && cp /build/entrypoint /docker-entrypoint \ + && cp /build/healthcheck /docker-healthcheck \ + && chmod +x /docker-healthcheck \ + && chmod +x /docker-entrypoint \ && apk del go \ - && rm -Rf /build + && mkdir -p /etc/mysql/conf.d /etc/mysql/mariadb.conf.d/ /run/mariadb /run/mysqld \ + && chmod ugo+rwx,o+t /run/mariadb \ + && chown -R mysql:mysql /var/lib/mysql /run/mariadb /run/mysqld \ + && rm -Rf /build \ + && rm -rf /var/cache/apk/* ENV LANG=C.UTF-8 -#COPY --chmod=0644 docker.cnf /etc/my.cnf.d/ - -RUN apk add --no-cache mariadb tzdata doas +COPY --chmod=0644 configs/mariadb/docker.cnf /etc/my.cnf.d/ VOLUME /var/lib/mysql -#COPY --chmod=0741 healthcheck.sh /healthcheck.sh - -#ENTRYPOINT [ "/mariadb-entry" ] +ENTRYPOINT [ "/docker-entrypoint" ] WORKDIR /var/lib/mysql -USER mysql +#USER mysql EXPOSE 3306 -CMD [ "mariadbd" ] +CMD [ "mariadbd", "--user=mysql" ] +HEALTHCHECK --interval=30s --timeout=10s --retries=3 CMD /docker-healthcheck diff --git a/go.mod b/go.mod index 1bcfc46..9edfe73 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,8 @@ module git.keyzox.me/42_adjoly/inception go 1.23.4 + +require ( + filippo.io/edwards25519 v1.1.0 // indirect + github.com/go-sql-driver/mysql v1.8.1 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..19dbcec --- /dev/null +++ b/go.sum @@ -0,0 +1,4 @@ +filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= +filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= +github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y= +github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= diff --git a/internal/env/env_util.go b/internal/env/env_util.go new file mode 100644 index 0000000..7a5aea9 --- /dev/null +++ b/internal/env/env_util.go @@ -0,0 +1,34 @@ +package env + +import ( + "os" + + "git.keyzox.me/42_adjoly/inception/internal/log" +) + +func FileEnv(Value string, Default string) string { + val, is := os.LookupEnv(Value) + + if is { + return val + } else { + val, is := os.LookupEnv(Value + "_FILE") + if is { + content, err := os.ReadFile(val) + if err != nil { + _log.Log("error", "Error reading file") + } + return string(content) + } + } + return Default +} + +func EnvCheck(Value, Default string) string { + val, is := os.LookupEnv(Value) + + if is { + return val + } + return Default +} diff --git a/internal/log/log.go b/internal/log/log.go new file mode 100644 index 0000000..9963da0 --- /dev/null +++ b/internal/log/log.go @@ -0,0 +1,20 @@ +package _log + +import ( + "fmt" + "os" + "time" +) + +func Log(Type string, Log string) { + t := time.Now() + t.Format(time.RFC3339) + if Type == "note" { + fmt.Printf("%s-[%s] [Entrypoint]: %s\n", t, Type, Log) + } else if Type == "warn" { + fmt.Fprintf(os.Stderr ,"%s-[%s] [Entrypoint]: %s\n", t, Type, Log) + } else if Type == "error" { + fmt.Fprintf(os.Stderr ,"%s-[%s] [Entrypoint]: %s\n", t, Type, Log) + os.Exit(1) + } +}