Start of DB initialisation functions
Not properly working yet
This commit is contained in:
parent
df5e990693
commit
6bd1a86337
@ -22,6 +22,7 @@ package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"flag"
|
||||
"net"
|
||||
"net/http"
|
||||
"time"
|
||||
@ -43,11 +44,29 @@ import (
|
||||
"gitlab.com/blender/flamenco-ng-poc/pkg/api"
|
||||
)
|
||||
|
||||
var cliArgs struct {
|
||||
version bool
|
||||
initDB bool
|
||||
}
|
||||
|
||||
func main() {
|
||||
output := zerolog.ConsoleWriter{Out: colorable.NewColorableStdout(), TimeFormat: time.RFC3339}
|
||||
log.Logger = log.Output(output)
|
||||
log.Info().Str("version", appinfo.ApplicationVersion).Msgf("starting %v", appinfo.ApplicationName)
|
||||
|
||||
parseCliArgs()
|
||||
if cliArgs.version {
|
||||
return
|
||||
}
|
||||
if cliArgs.initDB {
|
||||
log.Info().Msg("creating databases")
|
||||
err := persistence.InitialSetup()
|
||||
if err != nil {
|
||||
log.Fatal().Err(err).Msg("problem performing initial setup")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Open the database.
|
||||
dbCtx, dbCtxCancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer dbCtxCancel()
|
||||
@ -113,3 +132,27 @@ func buildWebService(flamenco api.ServerInterface, persist api_impl.PersistenceS
|
||||
|
||||
return e
|
||||
}
|
||||
|
||||
func parseCliArgs() {
|
||||
var quiet, debug, trace bool
|
||||
|
||||
flag.BoolVar(&cliArgs.version, "version", false, "Shows the application version, then exits.")
|
||||
flag.BoolVar(&cliArgs.initDB, "initdb", false, "Create the database; requires admin access to PostgreSQL.")
|
||||
flag.BoolVar(&quiet, "quiet", false, "Only log warning-level and worse.")
|
||||
flag.BoolVar(&debug, "debug", false, "Enable debug-level logging.")
|
||||
flag.BoolVar(&trace, "trace", false, "Enable trace-level logging.")
|
||||
flag.Parse()
|
||||
|
||||
var logLevel zerolog.Level
|
||||
switch {
|
||||
case trace:
|
||||
logLevel = zerolog.TraceLevel
|
||||
case debug:
|
||||
logLevel = zerolog.DebugLevel
|
||||
case quiet:
|
||||
logLevel = zerolog.WarnLevel
|
||||
default:
|
||||
logLevel = zerolog.InfoLevel
|
||||
}
|
||||
zerolog.SetGlobalLevel(logLevel)
|
||||
}
|
||||
|
1
go.mod
1
go.mod
@ -54,6 +54,7 @@ require (
|
||||
github.com/valyala/fasttemplate v1.2.1 // indirect
|
||||
golang.org/x/mod v0.4.2 // indirect
|
||||
golang.org/x/sys v0.0.0-20211103235746-7861aae1554b // indirect
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect
|
||||
golang.org/x/text v0.3.7 // indirect
|
||||
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba // indirect
|
||||
golang.org/x/tools v0.1.7 // indirect
|
||||
|
2
go.sum
2
go.sum
@ -306,6 +306,8 @@ golang.org/x/sys v0.0.0-20211103235746-7861aae1554b h1:1VkfZQv42XQlA/jchYumAnv1U
|
||||
golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
|
141
internal/manager/persistence/initialisation.go
Normal file
141
internal/manager/persistence/initialisation.go
Normal file
@ -0,0 +1,141 @@
|
||||
package persistence
|
||||
|
||||
/* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* Original Code Copyright (C) 2022 Blender Foundation.
|
||||
*
|
||||
* This file is part of Flamenco.
|
||||
*
|
||||
* Flamenco is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* Flamenco is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* Flamenco. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK ***** */
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"runtime"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
"golang.org/x/term"
|
||||
"gorm.io/driver/postgres"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
var errInputTooLong = errors.New("input is too long")
|
||||
|
||||
const adminDSN = "host=localhost user=postgres password=%s dbname=%s TimeZone=Europe/Amsterdam"
|
||||
|
||||
// InitialSetup uses the `postgres` admin user to set up the database.
|
||||
// TODO: distinguish between production and development setups.
|
||||
func InitialSetup() error {
|
||||
// Get the password of the 'postgres' user.
|
||||
adminPass, err := readPassword()
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to read password: %w", err)
|
||||
}
|
||||
|
||||
// Connect to the 'postgres' database so we can create other databases.
|
||||
db, err := connectDBAsAdmin(adminPass, "postgres")
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to connect to the database: %w", err)
|
||||
}
|
||||
|
||||
// TODO: get username / password / database name from some config file, user input, CLI args, whatevah.
|
||||
// Has to be used by the regular Flamenco Manager runs as well, though.
|
||||
username := "flamenco"
|
||||
userPass := "flamenco"
|
||||
// tx := db.Exec("CREATE USER flamenco PASSWORD ? NOSUPERUSER NOCREATEDB NOCREATEROLE INHERIT LOGIN", userPass)
|
||||
// if tx.Error != nil {
|
||||
// return fmt.Errorf("unable to create database user '%s': %w", username, tx.Error)
|
||||
// }
|
||||
{
|
||||
sqlDB, err := db.DB()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
_, err = sqlDB.Exec("CREATE USER flamenco WITH PASSWORD $1::string NOSUPERUSER NOCREATEDB NOCREATEROLE INHERIT LOGIN", userPass)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// Create the databases.
|
||||
tx := db.Debug().Exec("CREATE DATABASE flamenco OWNER ? ENCODING 'utf8'", username)
|
||||
if tx.Error != nil {
|
||||
return fmt.Errorf("unable to create database 'flamenco': %w", tx.Error)
|
||||
}
|
||||
tx = db.Exec("CREATE DATABASE flamenco-test OWNER ? ENCODING 'utf8'", username)
|
||||
if tx.Error != nil {
|
||||
return fmt.Errorf("unable to create database 'flamenco': %w", tx.Error)
|
||||
}
|
||||
|
||||
// Close the connection so we can reconnect.
|
||||
sqlDB, err := db.DB()
|
||||
if err != nil {
|
||||
fmt.Printf("error closing the database connection, please report this issue: %v", err)
|
||||
} else {
|
||||
sqlDB.Close()
|
||||
}
|
||||
|
||||
// Allow 'flamenco' user to completely nuke and recreate the flamenco-test database, without needing 'CREATEDB' permission.
|
||||
db, err = connectDBAsAdmin(adminPass, "flamenco-test")
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to reconnect to the database: %w", err)
|
||||
}
|
||||
tx = db.Exec("ALTER SCHEMA public OWNER TO ?", username)
|
||||
if tx.Error != nil {
|
||||
fmt.Printf("Unable to allow database user '%s' to reset the test database: %v\n", username, tx.Error)
|
||||
fmt.Println("This is not an issue, unless you want to develop Flamenco yourself.")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func readPassword() (string, error) {
|
||||
if pwFromEnv := os.Getenv("PSQL_ADMIN"); pwFromEnv != "" {
|
||||
log.Info().Msg("getting password from PSQL_ADMIN environment variable")
|
||||
return pwFromEnv, nil
|
||||
}
|
||||
|
||||
fmt.Print("PostgreSQL admin password: ")
|
||||
|
||||
var (
|
||||
line []byte
|
||||
err error
|
||||
)
|
||||
|
||||
if runtime.GOOS == "windows" {
|
||||
// term.ReadPassword() doesn't work reliably on Windows, especially when you
|
||||
// use a MingW terminal (like Git Bash). See
|
||||
// https://github.com/golang/go/issues/11914#issuecomment-613715787 for more
|
||||
// info.
|
||||
//
|
||||
// The downside is that this echoes the password to the terminal.
|
||||
buf := bufio.NewReader(os.Stdin)
|
||||
line, _, err = buf.ReadLine()
|
||||
} else {
|
||||
fd := int(os.Stdin.Fd())
|
||||
line, err = term.ReadPassword(fd)
|
||||
}
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(line), nil
|
||||
}
|
||||
|
||||
func connectDBAsAdmin(password, database string) (*gorm.DB, error) {
|
||||
dsn := fmt.Sprintf(adminDSN, password, database)
|
||||
return gorm.Open(postgres.Open(dsn), &gorm.Config{})
|
||||
}
|
Loading…
Reference in New Issue
Block a user