Rework templating for bootstrap
This commit is contained in:
parent
08d1840a63
commit
47aeb05c82
4 changed files with 108 additions and 43 deletions
|
|
@ -1,7 +1,6 @@
|
||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"io/fs"
|
"io/fs"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
@ -10,10 +9,7 @@ import (
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/config"
|
"github.com/FAU-CDI/wisski-distillery/internal/config"
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/core"
|
"github.com/FAU-CDI/wisski-distillery/internal/core"
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/fsx"
|
"github.com/FAU-CDI/wisski-distillery/pkg/fsx"
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/hostname"
|
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/logging"
|
"github.com/FAU-CDI/wisski-distillery/pkg/logging"
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/password"
|
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/unpack"
|
|
||||||
"github.com/tkw1536/goprogram/exit"
|
"github.com/tkw1536/goprogram/exit"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -95,12 +91,16 @@ func (bs bootstrap) Run(context wisski_distillery.Context) error {
|
||||||
// TODO: Should we read an existing configuration file?
|
// TODO: Should we read an existing configuration file?
|
||||||
wdcliPath := filepath.Join(root, core.Executable)
|
wdcliPath := filepath.Join(root, core.Executable)
|
||||||
envPath := filepath.Join(root, core.ConfigFile)
|
envPath := filepath.Join(root, core.ConfigFile)
|
||||||
domain := bs.Hostname
|
|
||||||
if domain == "" {
|
// setup a new template for the configuration file!
|
||||||
domain = hostname.FQDN()
|
var tpl config.Template
|
||||||
|
tpl.DeployRoot = bs.Directory
|
||||||
|
tpl.DefaultDomain = bs.Hostname
|
||||||
|
|
||||||
|
// and use thge defaults
|
||||||
|
if err := tpl.SetDefaults(); err != nil {
|
||||||
|
return errBootstrapWriteConfig.WithMessageF(err)
|
||||||
}
|
}
|
||||||
overridesPath := filepath.Join(root, core.OverridesJSON)
|
|
||||||
authorizedKeysFile := filepath.Join(root, core.AuthorizedKeys)
|
|
||||||
|
|
||||||
{
|
{
|
||||||
logging.LogMessage(context.IOStream, "Copying over wdcli executable")
|
logging.LogMessage(context.IOStream, "Copying over wdcli executable")
|
||||||
|
|
@ -119,53 +119,31 @@ func (bs bootstrap) Run(context wisski_distillery.Context) error {
|
||||||
{
|
{
|
||||||
if !fsx.IsFile(envPath) {
|
if !fsx.IsFile(envPath) {
|
||||||
if err := logging.LogOperation(func() error {
|
if err := logging.LogOperation(func() error {
|
||||||
password, err := password.Password(128)
|
|
||||||
if err != nil {
|
|
||||||
return errBootstrapWriteConfig.WithMessageF(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
env, err := os.Create(envPath)
|
env, err := os.Create(envPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errBootstrapWriteConfig.WithMessageF(err)
|
return err
|
||||||
}
|
}
|
||||||
if err := unpack.WriteTemplate(
|
defer env.Close()
|
||||||
env,
|
|
||||||
map[string]string{
|
|
||||||
"DEPLOY_ROOT": root,
|
|
||||||
"DEFAULT_DOMAIN": domain,
|
|
||||||
"SELF_OVERRIDES_FILE": overridesPath,
|
|
||||||
"AUTHORIZED_KEYS_FILE": authorizedKeysFile,
|
|
||||||
|
|
||||||
"GRAPHDB_ADMIN_USER": "admin",
|
return tpl.MarshalTo(env)
|
||||||
"GRAPHDB_ADMIN_PASSWORD": password[:64],
|
|
||||||
|
|
||||||
"MYSQL_ADMIN_USER": "admin",
|
|
||||||
"MYSQL_ADMIN_PASSWORD": password[64:],
|
|
||||||
},
|
|
||||||
bytes.NewReader(core.ConfigFileTemplate),
|
|
||||||
); err != nil {
|
|
||||||
return errBootstrapWriteConfig.WithMessageF(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}, context.IOStream, "Installing configuration file"); err != nil {
|
}, context.IOStream, "Installing configuration file"); err != nil {
|
||||||
return err
|
return errBootstrapWriteConfig.WithMessageF(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := logging.LogOperation(func() error {
|
if err := logging.LogOperation(func() error {
|
||||||
|
|
||||||
context.Println(overridesPath)
|
context.Println(tpl.SelfOverridesFile)
|
||||||
if err := os.WriteFile(
|
if err := os.WriteFile(
|
||||||
overridesPath,
|
tpl.SelfOverridesFile,
|
||||||
core.DefaultOverridesJSON,
|
core.DefaultOverridesJSON,
|
||||||
fs.ModePerm,
|
fs.ModePerm,
|
||||||
); err != nil {
|
); err != nil {
|
||||||
return errBootstrapCreateFile.WithMessageF(err)
|
return errBootstrapCreateFile.WithMessageF(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
context.Println(authorizedKeysFile)
|
context.Println(tpl.AuthorizedKeys)
|
||||||
if err := os.WriteFile(
|
if err := os.WriteFile(
|
||||||
authorizedKeysFile,
|
tpl.AuthorizedKeys,
|
||||||
core.DefaultAuthorizedKeys,
|
core.DefaultAuthorizedKeys,
|
||||||
fs.ModePerm,
|
fs.ModePerm,
|
||||||
); err != nil {
|
); err != nil {
|
||||||
|
|
|
||||||
91
internal/config/template.go
Normal file
91
internal/config/template.go
Normal file
|
|
@ -0,0 +1,91 @@
|
||||||
|
package config
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"io"
|
||||||
|
"path/filepath"
|
||||||
|
"reflect"
|
||||||
|
|
||||||
|
"github.com/FAU-CDI/wisski-distillery/internal/core"
|
||||||
|
"github.com/FAU-CDI/wisski-distillery/pkg/hostname"
|
||||||
|
"github.com/FAU-CDI/wisski-distillery/pkg/password"
|
||||||
|
"github.com/FAU-CDI/wisski-distillery/pkg/unpack"
|
||||||
|
|
||||||
|
_ "embed"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Template is a template for the cofiguration file
|
||||||
|
type Template struct {
|
||||||
|
DeployRoot string `env:"DEPLOY_ROOT"`
|
||||||
|
DefaultDomain string `env:"DEFAULT_DOMAIN"`
|
||||||
|
SelfOverridesFile string `env:"SELF_OVERRIDES_FILE"`
|
||||||
|
AuthorizedKeys string `env:"AUTHORIZED_KEYS_FILE"`
|
||||||
|
TriplestoreAdminUser string `env:"GRAPHDB_ADMIN_USER"`
|
||||||
|
TriplestoreAdminPassword string `env:"GRAPHDB_ADMIN_PASSWORD"`
|
||||||
|
MysqlAdminUsername string `env:"MYSQL_ADMIN_USER"`
|
||||||
|
MysqlAdminPassword string `env:"MYSQL_ADMIN_PASSWORD"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetDefaults sets defaults on the template
|
||||||
|
func (tpl *Template) SetDefaults() (err error) {
|
||||||
|
if tpl.DeployRoot == "" {
|
||||||
|
tpl.DeployRoot = core.BaseDirectoryDefault
|
||||||
|
}
|
||||||
|
|
||||||
|
if tpl.DefaultDomain == "" {
|
||||||
|
tpl.DefaultDomain = hostname.FQDN()
|
||||||
|
}
|
||||||
|
|
||||||
|
if tpl.SelfOverridesFile == "" {
|
||||||
|
tpl.SelfOverridesFile = filepath.Join(tpl.DeployRoot, core.OverridesJSON)
|
||||||
|
}
|
||||||
|
|
||||||
|
if tpl.AuthorizedKeys == "" {
|
||||||
|
tpl.AuthorizedKeys = filepath.Join(tpl.DeployRoot, core.AuthorizedKeys)
|
||||||
|
}
|
||||||
|
|
||||||
|
if tpl.TriplestoreAdminUser == "" {
|
||||||
|
tpl.TriplestoreAdminUser = "admin"
|
||||||
|
}
|
||||||
|
|
||||||
|
if tpl.TriplestoreAdminPassword == "" {
|
||||||
|
tpl.TriplestoreAdminPassword, err = password.Password(64)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if tpl.MysqlAdminUsername == "" {
|
||||||
|
tpl.MysqlAdminUsername = "admin"
|
||||||
|
}
|
||||||
|
|
||||||
|
if tpl.MysqlAdminPassword == "" {
|
||||||
|
tpl.MysqlAdminPassword, err = password.Password(64)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
//go:embed config_template
|
||||||
|
var templateBytes []byte
|
||||||
|
|
||||||
|
// MarshalTo marshals this template into dst
|
||||||
|
func (tpl Template) MarshalTo(dst io.Writer) error {
|
||||||
|
tplVal := reflect.ValueOf(tpl)
|
||||||
|
tplType := reflect.TypeOf(tpl)
|
||||||
|
|
||||||
|
context := make(map[string]string, tplType.NumField())
|
||||||
|
for i := 0; i < tplType.NumField(); i++ {
|
||||||
|
field := tplType.Field(i)
|
||||||
|
|
||||||
|
key := field.Tag.Get("env")
|
||||||
|
value := tplVal.FieldByName(field.Name).String()
|
||||||
|
|
||||||
|
context[key] = value
|
||||||
|
}
|
||||||
|
|
||||||
|
return unpack.WriteTemplate(dst, context, bytes.NewReader(templateBytes))
|
||||||
|
}
|
||||||
|
|
@ -15,10 +15,6 @@ const Executable = "wdcli"
|
||||||
// It should be located inside the deployment directory.
|
// It should be located inside the deployment directory.
|
||||||
const ConfigFile = ".env"
|
const ConfigFile = ".env"
|
||||||
|
|
||||||
// ConfigFileTemplate contains a template for a new configuration file
|
|
||||||
//go:embed bootstrap/env
|
|
||||||
var ConfigFileTemplate []byte
|
|
||||||
|
|
||||||
// OverridesJSON is the name of the json overrides file.
|
// OverridesJSON is the name of the json overrides file.
|
||||||
// It should be located inside the deployment directory.
|
// It should be located inside the deployment directory.
|
||||||
const OverridesJSON = "overrides.json"
|
const OverridesJSON = "overrides.json"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue