entrypoint/: auto-import SQL schema

This commit is contained in:
Alexander A. Klimov 2020-07-03 13:54:42 +02:00
parent 537d520f91
commit d73b44d879
3 changed files with 163 additions and 1 deletions

View File

@ -15,6 +15,7 @@ RUN ["locale-gen", "-j", "4"]
RUN ["bash", "-exo", "pipefail", "-c", "export DEBIAN_FRONTEND=noninteractive; apt-get update; apt-get install --no-install-{recommends,suggests} -y apache2 libapache2-mod-php7.3 php-{imagick,redis} php7.3-{bcmath,bz2,common,curl,dba,enchant,gd,gmp,imap,interbase,intl,json,ldap,mbstring,mysql,odbc,opcache,pgsql,pspell,readline,recode,snmp,soap,sqlite3,sybase,tidy,xml,xmlrpc,xsl,zip}; apt-get clean; rm -vrf /var/lib/apt/lists/*"]
COPY --from=entrypoint /entrypoint/entrypoint /entrypoint
COPY entrypoint/db-init /entrypoint-db-init
RUN ["a2enmod", "rewrite"]
RUN ["ln", "-vsf", "/dev/stdout", "/var/log/apache2/access.log"]

View File

@ -0,0 +1,82 @@
<?php
namespace Icinga\Module\Dockerentrypoint\Clicommands;
use Icinga\Application\Config;
use Icinga\Application\Icinga;
use Icinga\Cli\Command;
use Icinga\Data\ResourceFactory;
use Icinga\Module\Setup\Utils\DbTool;
use Icinga\Util\Json;
class DbCommand extends Command
{
public function backendsAction()
{
$resources = [];
$config = Config::app();
if ($config->get('global', 'config_backend') === 'db') {
$configResource = $config->get('global', 'config_resource');
if ($configResource !== null) {
$resources[$configResource] = null;
}
}
foreach (['authentication', 'groups'] as $file) {
foreach (Config::app($file) as $backend) {
if ($backend->backend === 'db') {
$resource = $backend->resource;
if ($resource !== null) {
$resources[$resource] = null;
}
}
}
}
ksort($resources);
echo Json::encode(array_keys($resources));
}
public function initializedAction()
{
echo (int) (array_search('icingaweb_group', $this->getDb()->listTables(), true) !== false);
}
public function initAction()
{
$db = $this->getDb();
$db->import(
Config::module('setup')
->get('schema', 'path', Icinga::app()->getBaseDir('etc/schema')) . "/{$db->dbType}.schema.sql"
);
}
/**
* @return DbTool
*/
protected function getDb()
{
$config = ResourceFactory::getResourceConfig($this->params->getRequired('resource'))->toArray();
$type = isset($config['db']) ? $config['db'] : 'mysql';
if (! isset($config['port'])) {
switch ($type) {
case 'mysql':
$config['port'] = 3306;
break;
case 'pgsql':
$config['port'] = 5432;
}
}
$db = new DbTool($config);
$db->connectToDb();
$db->dbType = $type;
return $db;
}
}

View File

@ -2,6 +2,8 @@ package main
import (
"bufio"
"bytes"
"encoding/json"
"fmt"
"github.com/go-ini/ini"
"io/ioutil"
@ -15,6 +17,7 @@ import (
)
const confDir = "/data/etc/icingaweb2"
const modsDir = "/usr/share/icingaweb2/modules"
const dirMode = 0750
var enModsDir = path.Join(confDir, "enabledModules")
@ -126,12 +129,16 @@ func entrypoint() error {
for mod := range enabledModules {
logf("trace1", "Enabling module %#v", mod)
errSl := os.Symlink(path.Join("/usr/share/icingaweb2/modules", mod), path.Join(enModsDir, mod))
errSl := os.Symlink(path.Join(modsDir, mod), path.Join(enModsDir, mod))
if errSl != nil {
return errSl
}
}
}
if errID := initDb(); errID != nil {
return errID
}
}
path := os.Args[1]
@ -150,6 +157,78 @@ func entrypoint() error {
return syscall.Exec(path, os.Args[1:], os.Environ())
}
func initDb() error {
logf("info", "Checking database resources used as backends")
{
enMod := path.Join(enModsDir, "dockerentrypoint")
if errSl := os.Symlink("/entrypoint-db-init", enMod); errSl != nil {
return errSl
}
defer os.Remove(enMod)
}
{
enMod := path.Join(enModsDir, "setup")
errSl := os.Symlink(path.Join(modsDir, "setup"), enMod)
if errSl != nil {
if le, ok := errSl.(*os.LinkError); !ok || !os.IsNotExist(le.Err) {
return errSl
}
}
if errSl == nil {
defer os.Remove(enMod)
}
}
var resources []string
if errIJ := icingacliJson(&resources, "dockerentrypoint", "db", "backends"); errIJ != nil {
return errIJ
}
for _, resource := range resources {
logf("debug", "Checking database resource %#v", resource)
var initialized uint8
errIJ := icingacliJson(&initialized, "dockerentrypoint", "db", "initialized", "--resource="+resource)
if errIJ != nil {
return errIJ
}
if initialized == 0 {
logf("debug", "Importing schema into database resource %#v", resource)
cmd := exec.Command("icingacli", "dockerentrypoint", "db", "init", "--resource="+resource)
cmd.Stdout = os.Stderr
cmd.Stderr = os.Stderr
if errRn := cmd.Run(); errRn != nil {
return errRn
}
}
}
return nil
}
func icingacliJson(v interface{}, arg ...string) error {
cmd := exec.Command("icingacli", arg...)
var out bytes.Buffer
cmd.Stdout = &out
cmd.Stderr = os.Stderr
if errRn := cmd.Run(); errRn != nil {
return errRn
}
return json.Unmarshal(out.Bytes(), v)
}
var out = bufio.NewWriter(os.Stderr)
func logf(severity, format string, a ...interface{}) {