Require access to Still via method
This commit adds a safeguard to accessing the still from a specific component by requiring access via the component.GetStill method.
This commit is contained in:
parent
81fa84c244
commit
8235ea9105
63 changed files with 288 additions and 197 deletions
|
|
@ -36,8 +36,9 @@ type AuthInfo struct {
|
|||
}
|
||||
|
||||
func (a *API) HandleRoute(ctx context.Context, path string) (http.Handler, error) {
|
||||
|
||||
return &Handler[AuthInfo]{
|
||||
Config: a.Config,
|
||||
Config: component.GetStill(a).Config,
|
||||
Auth: a.dependencies.Auth,
|
||||
|
||||
Methods: []string{"GET"},
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ func (next *Next) getInstance(r *http.Request) (wisski *wisski.WissKI, path stri
|
|||
}
|
||||
|
||||
// find the slug
|
||||
slug, ok := next.Config.HTTP.SlugFromHost(url.Host)
|
||||
slug, ok := component.GetStill(next).Config.HTTP.SlugFromHost(url.Host)
|
||||
if slug == "" || !ok {
|
||||
return nil, "", httpx.ErrBadRequest
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import (
|
|||
"errors"
|
||||
"net/http"
|
||||
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/auth"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/assets"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/templating"
|
||||
|
|
@ -64,9 +65,10 @@ func (panel *UserPanel) sshRoute(ctx context.Context) http.Handler {
|
|||
return sc, err
|
||||
}
|
||||
|
||||
sc.Domain = panel.Config.HTTP.PrimaryDomain
|
||||
sc.PanelDomain = panel.Config.HTTP.PanelDomain()
|
||||
sc.Port = panel.Config.Listen.SSHPort
|
||||
config := component.GetStill(panel).Config
|
||||
sc.Domain = config.HTTP.PrimaryDomain
|
||||
sc.PanelDomain = config.HTTP.PanelDomain()
|
||||
sc.Port = config.Listen.SSHPort
|
||||
|
||||
// pick the first domain that the user has access to as an example
|
||||
grants, err := panel.dependencies.Policy.User(r.Context(), user.User.User)
|
||||
|
|
@ -75,7 +77,7 @@ func (panel *UserPanel) sshRoute(ctx context.Context) http.Handler {
|
|||
} else {
|
||||
sc.Slug = "example"
|
||||
}
|
||||
sc.Hostname = panel.Config.HTTP.HostFromSlug(sc.Slug)
|
||||
sc.Hostname = config.HTTP.HostFromSlug(sc.Slug)
|
||||
|
||||
sc.Keys, err = panel.dependencies.Keys.Keys(r.Context(), user.User.User)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import (
|
|||
"html/template"
|
||||
"net/http"
|
||||
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/auth"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/assets"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/templating"
|
||||
|
|
@ -52,7 +53,7 @@ func (panel *UserPanel) tokensRoute(ctx context.Context) http.Handler {
|
|||
return tc, err
|
||||
}
|
||||
|
||||
tc.Domain = template.URL(panel.Config.HTTP.JoinPath().String())
|
||||
tc.Domain = template.URL(component.GetStill(panel).Config.HTTP.JoinPath().String())
|
||||
|
||||
// get the tokens
|
||||
tc.Tokens, err = panel.dependencies.Tokens.Tokens(r.Context(), user.User.User)
|
||||
|
|
@ -178,7 +179,7 @@ func (panel *UserPanel) tokensAddRoute(ctx context.Context) http.Handler {
|
|||
// render the created context
|
||||
return panel.dependencies.Handling.WriteHTML(
|
||||
tplDone.Context(r, TokenCreateContext{
|
||||
Domain: template.URL(panel.Config.HTTP.JoinPath().String()),
|
||||
Domain: template.URL(component.GetStill(panel).Config.HTTP.JoinPath().String()),
|
||||
Token: tok,
|
||||
}),
|
||||
nil,
|
||||
|
|
|
|||
|
|
@ -46,8 +46,7 @@ func (panel *UserPanel) routeUser(ctx context.Context) http.Handler {
|
|||
menuTOTPAction,
|
||||
menuSSH,
|
||||
}
|
||||
|
||||
if panel.Config.HTTP.API.Value {
|
||||
if component.GetStill(panel).Config.HTTP.API.Value {
|
||||
actions = append(actions, menuTokens)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ func (auth *Auth) checkUser(ctx context.Context, name string) (user *AuthUser, e
|
|||
// If the session is not set, creates a new session.
|
||||
func (auth *Auth) session(r *http.Request) (*sessions.Session, error) {
|
||||
return auth.store.Get(func() sessions.Store {
|
||||
return sessions.NewCookieStore([]byte(auth.Config.SessionSecret))
|
||||
return sessions.NewCookieStore([]byte(component.GetStill(auth).Config.SessionSecret))
|
||||
}).Get(r, server.SessionCookie)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ var (
|
|||
)
|
||||
|
||||
func (binder *Binder) Path() string {
|
||||
return filepath.Join(binder.Still.Config.Paths.Root, "core", "binder")
|
||||
return filepath.Join(component.GetStill(binder).Config.Paths.Root, "core", "binder")
|
||||
}
|
||||
|
||||
func (binder *Binder) Context(parent component.InstallationContext) component.InstallationContext {
|
||||
|
|
@ -29,17 +29,20 @@ func (binder *Binder) Context(parent component.InstallationContext) component.In
|
|||
var composeTemplate embed.FS
|
||||
|
||||
func (binder *Binder) Stack() component.StackWithResources {
|
||||
config := component.GetStill(binder).Config
|
||||
|
||||
return component.MakeStack(binder, component.StackWithResources{
|
||||
ContextPath: ".",
|
||||
Resources: composeTemplate,
|
||||
|
||||
ComposerYML: func(root *yaml.Node) (*yaml.Node, error) {
|
||||
ports := binder.Config.Listen.ComposePorts("8000")
|
||||
|
||||
ports := config.Listen.ComposePorts("8000")
|
||||
if err := yamlx.ReplaceWith(root, ports, "services", "binder", "ports"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
command := binder.Config.HTTP.TCPMuxCommand("0.0.0.0:8000", "http:80", "http:443", "ssh:2222")
|
||||
command := config.HTTP.TCPMuxCommand("0.0.0.0:8000", "http:80", "http:443", "ssh:2222")
|
||||
if err := yamlx.ReplaceWith(root, command, "services", "binder", "command"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -48,7 +51,7 @@ func (binder *Binder) Stack() component.StackWithResources {
|
|||
},
|
||||
|
||||
EnvContext: map[string]string{
|
||||
"DOCKER_NETWORK_NAME": binder.Config.Docker.Network(),
|
||||
"DOCKER_NETWORK_NAME": config.Docker.Network(),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ type Component interface {
|
|||
// Base is embedded into every Component
|
||||
type Base struct {
|
||||
name, id string // name and id of this component
|
||||
Still // the underlying still of the distillery
|
||||
still Still // the underlying still of the distillery
|
||||
}
|
||||
|
||||
//lint:ignore U1000 used to implement the private methods of [Component]
|
||||
|
|
@ -45,7 +45,7 @@ func (cb *Base) getBase() *Base {
|
|||
// Init is only initended to be used within a lifetime.Lifetime[Component,Still].
|
||||
func Init(component Component, core Still) {
|
||||
base := component.getBase() // pointer to a struct
|
||||
base.Still = core
|
||||
base.still = core
|
||||
|
||||
tp := reflect.TypeOf(component).Elem()
|
||||
base.name = strings.ToLower(tp.Name())
|
||||
|
|
@ -60,8 +60,13 @@ func (cb Base) ID() string {
|
|||
return cb.id
|
||||
}
|
||||
|
||||
// GetStill returns the still underlying the provided component.
|
||||
func GetStill(c Component) Still {
|
||||
return c.getBase().still
|
||||
}
|
||||
|
||||
// Still represents the central part of a distillery.
|
||||
// It is used inside the main distillery struct, as well as every component via [ComponentBase].
|
||||
// It holds configuration of the distillery.
|
||||
type Still struct {
|
||||
Config *config.Config // the configuration of the distillery
|
||||
Upstream Upstream
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ type Exporter struct {
|
|||
|
||||
// Path returns the path that contains all snapshot related data.
|
||||
func (dis *Exporter) Path() string {
|
||||
return filepath.Join(dis.Config.Paths.Root, "snapshots")
|
||||
return filepath.Join(component.GetStill(dis).Config.Paths.Root, "snapshots")
|
||||
}
|
||||
|
||||
// StagingPath returns the path to the directory containing a temporary staging area for snapshots.
|
||||
|
|
|
|||
|
|
@ -36,10 +36,11 @@ func (control *Config) Backup(scontext *component.StagingContext) error {
|
|||
|
||||
// backupfiles lists the files to be backed up.
|
||||
func (control *Config) backupFiles() []string {
|
||||
config := component.GetStill(control).Config
|
||||
return []string{
|
||||
control.Config.ConfigPath,
|
||||
control.Config.Paths.ExecutablePath(),
|
||||
control.Config.Paths.OverridesJSON,
|
||||
control.Config.Paths.ResolverBlocks,
|
||||
config.ConfigPath,
|
||||
config.Paths.ExecutablePath(),
|
||||
config.Paths.OverridesJSON,
|
||||
config.Paths.ResolverBlocks,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,12 +7,14 @@ import (
|
|||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
|
||||
)
|
||||
|
||||
// ShouldPrune determines if a file with the provided modification time should be
|
||||
// removed from the export log.
|
||||
func (exporter *Exporter) ShouldPrune(modtime time.Time) bool {
|
||||
return time.Since(modtime) > exporter.Config.MaxBackupAge
|
||||
return time.Since(modtime) > component.GetStill(exporter).Config.MaxBackupAge
|
||||
}
|
||||
|
||||
// Prune prunes all old exports
|
||||
|
|
@ -44,7 +46,7 @@ func (exporter *Exporter) PruneExports(ctx context.Context, progress io.Writer)
|
|||
|
||||
// assemble path, and then remove the file!
|
||||
path := filepath.Join(sPath, entry.Name())
|
||||
fmt.Fprintf(progress, "Removing %s cause it is older than %d days\n", path, exporter.Config.MaxBackupAge)
|
||||
fmt.Fprintf(progress, "Removing %s cause it is older than %d days\n", path, component.GetStill(exporter).Config.MaxBackupAge)
|
||||
|
||||
if err := os.Remove(path); err != nil {
|
||||
return err
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import (
|
|||
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/config"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/config/validators"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/models"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/wisski"
|
||||
)
|
||||
|
|
@ -37,22 +38,24 @@ func (instances *Instances) Create(slug string, system models.System) (wissKI *w
|
|||
wissKI.Liquid.Instance.OwnerEmail = ""
|
||||
wissKI.Liquid.Instance.AutoBlindUpdateEnabled = true
|
||||
|
||||
config := component.GetStill(instances).Config
|
||||
|
||||
// sql
|
||||
|
||||
wissKI.Liquid.Instance.SqlDatabase = instances.Config.SQL.DataPrefix + slug
|
||||
wissKI.Liquid.Instance.SqlUsername = instances.Config.SQL.UserPrefix + slug
|
||||
wissKI.Liquid.Instance.SqlDatabase = config.SQL.DataPrefix + slug
|
||||
wissKI.Liquid.Instance.SqlUsername = config.SQL.UserPrefix + slug
|
||||
|
||||
wissKI.Liquid.Instance.SqlPassword, err = instances.Config.NewPassword()
|
||||
wissKI.Liquid.Instance.SqlPassword, err = config.NewPassword()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// triplestore
|
||||
|
||||
wissKI.Liquid.Instance.GraphDBRepository = instances.Config.TS.DataPrefix + slug
|
||||
wissKI.Liquid.Instance.GraphDBUsername = instances.Config.TS.UserPrefix + slug
|
||||
wissKI.Liquid.Instance.GraphDBRepository = config.TS.DataPrefix + slug
|
||||
wissKI.Liquid.Instance.GraphDBUsername = config.TS.UserPrefix + slug
|
||||
|
||||
wissKI.Liquid.Instance.GraphDBPassword, err = instances.Config.NewPassword()
|
||||
wissKI.Liquid.Instance.GraphDBPassword, err = config.NewPassword()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -61,7 +64,7 @@ func (instances *Instances) Create(slug string, system models.System) (wissKI *w
|
|||
|
||||
wissKI.Liquid.DrupalUsername = "admin" // TODO: Change this!
|
||||
|
||||
wissKI.Liquid.DrupalPassword, err = instances.Config.NewPassword()
|
||||
wissKI.Liquid.DrupalPassword, err = config.NewPassword()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ type Instances struct {
|
|||
}
|
||||
|
||||
func (instances *Instances) Path() string {
|
||||
return filepath.Join(instances.Still.Config.Paths.Root, "instances")
|
||||
return filepath.Join(component.GetStill(instances).Config.Paths.Root, "instances")
|
||||
}
|
||||
|
||||
// ErrWissKINotFound is returned when a WissKI is not found
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import (
|
|||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
|
||||
"github.com/FAU-CDI/wisski-distillery/pkg/unpack"
|
||||
"github.com/tkw1536/goprogram/exit"
|
||||
)
|
||||
|
|
@ -22,7 +23,7 @@ var runtimeResources embed.FS
|
|||
|
||||
// Update installs or updates runtime components needed by this component.
|
||||
func (instances *Instances) Update(ctx context.Context, progress io.Writer) error {
|
||||
err := unpack.InstallDir(instances.Config.Paths.RuntimeDir(), "runtime", runtimeResources, func(dst, src string) {
|
||||
err := unpack.InstallDir(component.GetStill(instances).Config.Paths.RuntimeDir(), "runtime", runtimeResources, func(dst, src string) {
|
||||
fmt.Fprintf(progress, "[copy] %s\n", dst)
|
||||
})
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ func (api *API) Routes() component.Routes {
|
|||
|
||||
func (a *API) HandleRoute(ctx context.Context, path string) (http.Handler, error) {
|
||||
return &api.Handler[string]{
|
||||
Config: a.Config,
|
||||
Config: component.GetStill(a).Config,
|
||||
Auth: a.dependencies.Auth,
|
||||
|
||||
Methods: []string{"GET"},
|
||||
|
|
|
|||
|
|
@ -85,15 +85,17 @@ func (resolver *Resolver) HandleRoute(ctx context.Context, route string) (http.H
|
|||
Data: map[string]string{},
|
||||
}
|
||||
|
||||
config := component.GetStill(resolver).Config
|
||||
|
||||
// handle the default domain name!
|
||||
domainName := resolver.Config.HTTP.PrimaryDomain
|
||||
domainName := config.HTTP.PrimaryDomain
|
||||
if domainName != "" {
|
||||
fallback.Data[fmt.Sprintf("^https?://(.*)\\.%s", regexp.QuoteMeta(domainName))] = fmt.Sprintf("https://$1.%s", domainName)
|
||||
logger.Info().Str("name", domainName).Msg("registering default domain")
|
||||
}
|
||||
|
||||
// handle the extra domains!
|
||||
for _, domain := range resolver.Config.HTTP.ExtraDomains {
|
||||
for _, domain := range config.HTTP.ExtraDomains {
|
||||
fallback.Data[fmt.Sprintf("^https?://(.*)\\.%s", regexp.QuoteMeta(domain))] = fmt.Sprintf("https://$1.%s", domainName)
|
||||
logger.Info().Str("name", domainName).Msg("registering legacy domain")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ func (admin *Admin) Status(ctx context.Context, QuickInformation bool) (target s
|
|||
|
||||
func (admin *Admin) Fetch(flags component.FetcherFlags, target *status.Distillery) error {
|
||||
target.Time = time.Now().UTC()
|
||||
target.Config = admin.Config
|
||||
target.Config = component.GetStill(admin).Config
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -56,9 +56,10 @@ func (admin *Admin) instanceSSH(ctx context.Context) http.Handler {
|
|||
return ctx, nil, httpx.ErrNotFound
|
||||
}
|
||||
|
||||
config := component.GetStill(admin).Config
|
||||
ctx.Hostname = ctx.Instance.Domain()
|
||||
ctx.PanelDomain = admin.Config.HTTP.PanelDomain()
|
||||
ctx.Port = admin.Config.Listen.SSHPort
|
||||
ctx.PanelDomain = config.HTTP.PanelDomain()
|
||||
ctx.Port = config.Listen.SSHPort
|
||||
|
||||
keys, err := ctx.Instance.SSH().Keys(r.Context())
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -99,11 +99,12 @@ func (control *Cron) Once(ctx context.Context) {
|
|||
//
|
||||
// The returned channel is closed once no more cron tasks are active.
|
||||
func (control *Cron) Start(ctx context.Context, signal <-chan struct{}) <-chan struct{} {
|
||||
zerolog.Ctx(ctx).Info().Dur("interval", control.Config.CronInterval).Msg("Scheduling Cron() tasks")
|
||||
interval := component.GetStill(control).Config.CronInterval
|
||||
zerolog.Ctx(ctx).Info().Dur("interval", interval).Msg("Scheduling Cron() tasks")
|
||||
|
||||
// run runs cron tasks with the configured timeout
|
||||
run := func() {
|
||||
ctx, done := context.WithTimeout(ctx, control.Config.CronInterval)
|
||||
ctx, done := context.WithTimeout(ctx, interval)
|
||||
defer done()
|
||||
|
||||
control.Once(ctx)
|
||||
|
|
@ -123,7 +124,7 @@ func (control *Cron) Start(ctx context.Context, signal <-chan struct{}) <-chan s
|
|||
defer timex.ReleaseTimer(t)
|
||||
for {
|
||||
timex.StopTimer(t)
|
||||
t.Reset(control.Config.CronInterval)
|
||||
t.Reset(interval)
|
||||
|
||||
select {
|
||||
case <-t.C:
|
||||
|
|
|
|||
|
|
@ -37,7 +37,8 @@ func (h *Handling) interceptor(parent httpx.ErrInterceptor) httpx.ErrInterceptor
|
|||
pf = func(r *http.Request, err error) {}
|
||||
}
|
||||
|
||||
parent.RenderError = h.Config.HTTP.Debug.Set && h.Config.HTTP.Debug.Value
|
||||
config := component.GetStill(h).Config
|
||||
parent.RenderError = config.HTTP.Debug.Set && config.HTTP.Debug.Value
|
||||
parent.OnFallback = func(r *http.Request, err error) {
|
||||
pf(r, err)
|
||||
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ func (home *Home) Routes() component.Routes {
|
|||
MatchAllDomains: true,
|
||||
CSRF: false,
|
||||
|
||||
MenuTitle: home.Config.Home.Title,
|
||||
MenuTitle: component.GetStill(home).Config.Home.Title,
|
||||
MenuSticky: true,
|
||||
MenuPriority: component.MenuHome,
|
||||
}
|
||||
|
|
@ -45,7 +45,7 @@ func (home *Home) HandleRoute(ctx context.Context, route string) (http.Handler,
|
|||
dflt.Fallback = home.publicHandler(ctx)
|
||||
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
slug, ok := home.Config.HTTP.NormSlugFromHost(r.Host)
|
||||
slug, ok := component.GetStill(home).Config.HTTP.NormSlugFromHost(r.Host)
|
||||
switch {
|
||||
case !ok:
|
||||
http.NotFound(w, r)
|
||||
|
|
|
|||
|
|
@ -48,14 +48,14 @@ type publicContext struct {
|
|||
const logoHTML = template.HTML(`<img src="/logo.svg" alt="WissKI Distillery Logo" class="biglogo">`)
|
||||
|
||||
func (home *Home) publicHandler(ctx context.Context) http.Handler {
|
||||
title := home.Config.Home.Title
|
||||
config := component.GetStill(home).Config.Home
|
||||
|
||||
tpl := publicTemplate.Prepare(
|
||||
home.dependencies.Templating,
|
||||
// set title and menu item
|
||||
templating.Title(title),
|
||||
templating.Title(config.Title),
|
||||
templating.Crumbs(
|
||||
component.MenuItem{Title: title, Path: "/"},
|
||||
component.MenuItem{Title: config.Title, Path: "/"},
|
||||
),
|
||||
)
|
||||
|
||||
|
|
@ -73,7 +73,7 @@ func (home *Home) publicHandler(ctx context.Context) http.Handler {
|
|||
// prepare about
|
||||
pc.aboutContext.Logo = logoHTML
|
||||
pc.aboutContext.Instances = home.dependencies.ListInstances.Infos()
|
||||
pc.aboutContext.SelfRedirect = home.Config.Home.SelfRedirect.String()
|
||||
pc.aboutContext.SelfRedirect = config.SelfRedirect.String()
|
||||
|
||||
// render the about template
|
||||
|
||||
|
|
@ -88,7 +88,7 @@ func (home *Home) publicHandler(ctx context.Context) http.Handler {
|
|||
pc.ListEnabled = home.dependencies.ListInstances.ShouldShowList(r)
|
||||
|
||||
// title of the list
|
||||
pc.ListTitle = home.Config.Home.List.Title
|
||||
pc.ListTitle = config.List.Title
|
||||
|
||||
return
|
||||
})
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ import (
|
|||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
|
||||
)
|
||||
|
||||
func (home *Home) loadRedirect(ctx context.Context) (redirect Redirect, err error) {
|
||||
|
|
@ -19,7 +21,7 @@ func (home *Home) loadRedirect(ctx context.Context) (redirect Redirect, err erro
|
|||
redirect.Permanent = false
|
||||
|
||||
// load the overrides file
|
||||
overrides, err := os.Open(home.Config.Paths.OverridesJSON)
|
||||
overrides, err := os.Open(component.GetStill(home).Config.Paths.OverridesJSON)
|
||||
if err != nil {
|
||||
return redirect, err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ type APISystem struct {
|
|||
|
||||
func (a *API) HandleRoute(ctx context.Context, path string) (http.Handler, error) {
|
||||
return &api.Handler[[]APISystem]{
|
||||
Config: a.Config,
|
||||
Config: component.GetStill(a).Config,
|
||||
Auth: a.dependencies.Auth,
|
||||
|
||||
Methods: []string{"GET"},
|
||||
|
|
|
|||
|
|
@ -35,8 +35,9 @@ func (li *ListInstances) Infos() []status.WissKI {
|
|||
|
||||
// ShouldShowList determines if a list should be shown for the given request
|
||||
func (li *ListInstances) ShouldShowList(r *http.Request) bool {
|
||||
allowPrivate := li.Config.Home.List.Private.Value
|
||||
allowPublic := li.Config.Home.List.Public.Value
|
||||
config := component.GetStill(li).Config.Home.List
|
||||
allowPrivate := config.Private.Value
|
||||
allowPublic := config.Public.Value
|
||||
|
||||
if allowPrivate == allowPublic {
|
||||
return allowPrivate
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ func (api *API) Routes() component.Routes {
|
|||
|
||||
func (a *API) HandleRoute(ctx context.Context, path string) (http.Handler, error) {
|
||||
return &api.Handler[[]Item]{
|
||||
Config: a.Config,
|
||||
Config: component.GetStill(a).Config,
|
||||
Auth: a.dependencies.Auth,
|
||||
|
||||
Methods: []string{"GET"},
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ func (server *Server) Server(ctx context.Context, progress io.Writer) (public ht
|
|||
}()
|
||||
|
||||
// determine if we are on a slug from a host
|
||||
slug, ok := server.Config.HTTP.NormSlugFromHost(r.Host)
|
||||
slug, ok := component.GetStill(server).Config.HTTP.NormSlugFromHost(r.Host)
|
||||
|
||||
rctx := component.WithRouteContext(r.Context(), component.RouteContext{
|
||||
DefaultDomain: slug == "" && ok,
|
||||
|
|
@ -126,13 +126,15 @@ func (server *Server) Server(ctx context.Context, progress io.Writer) (public ht
|
|||
|
||||
// CSRF returns a CSRF handler for the given function
|
||||
func (server *Server) csrf() func(http.Handler) http.Handler {
|
||||
config := component.GetStill(server).Config
|
||||
|
||||
var opts []csrf.Option
|
||||
opts = append(opts, csrf.Secure(server.Config.HTTP.HTTPSEnabled()))
|
||||
opts = append(opts, csrf.Secure(config.HTTP.HTTPSEnabled()))
|
||||
opts = append(opts, csrf.SameSite(csrf.SameSiteStrictMode))
|
||||
opts = append(opts, csrf.Path("/"))
|
||||
opts = append(opts, csrf.CookieName(CSRFCookie))
|
||||
opts = append(opts, csrf.FieldName(CSRFCookieField))
|
||||
return csrf.Protect(server.Config.CSRFSecret(), opts...)
|
||||
return csrf.Protect(config.CSRFSecret(), opts...)
|
||||
}
|
||||
|
||||
// WithCSP adds a Content-Security-Policy header to every response
|
||||
|
|
|
|||
|
|
@ -11,28 +11,30 @@ import (
|
|||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
|
||||
)
|
||||
|
||||
func (control Server) Path() string {
|
||||
return filepath.Join(control.Still.Config.Paths.Root, "core", "dis")
|
||||
func (server *Server) Path() string {
|
||||
return filepath.Join(component.GetStill(server).Config.Paths.Root, "core", "dis")
|
||||
}
|
||||
|
||||
//go:embed all:server
|
||||
var resources embed.FS
|
||||
|
||||
func (server *Server) Stack() component.StackWithResources {
|
||||
config := component.GetStill(server).Config
|
||||
|
||||
return component.MakeStack(server, component.StackWithResources{
|
||||
Resources: resources,
|
||||
ContextPath: "server",
|
||||
|
||||
EnvContext: map[string]string{
|
||||
"DOCKER_NETWORK_NAME": server.Config.Docker.Network(),
|
||||
"HOST_RULE": server.Config.HTTP.PanelHostRule(),
|
||||
"HTTPS_ENABLED": server.Config.HTTP.HTTPSEnabledEnv(),
|
||||
"DOCKER_NETWORK_NAME": config.Docker.Network(),
|
||||
"HOST_RULE": config.HTTP.PanelHostRule(),
|
||||
"HTTPS_ENABLED": config.HTTP.HTTPSEnabledEnv(),
|
||||
|
||||
"CONFIG_PATH": server.Config.ConfigPath,
|
||||
"DEPLOY_ROOT": server.Config.Paths.Root,
|
||||
"CONFIG_PATH": config.ConfigPath,
|
||||
"DEPLOY_ROOT": config.Paths.Root,
|
||||
|
||||
"SELF_OVERRIDES_FILE": server.Config.Paths.OverridesJSON,
|
||||
"SELF_RESOLVER_BLOCK_FILE": server.Config.Paths.ResolverBlocks,
|
||||
"SELF_OVERRIDES_FILE": config.Paths.OverridesJSON,
|
||||
"SELF_RESOLVER_BLOCK_FILE": config.Paths.ResolverBlocks,
|
||||
|
||||
"CUSTOM_ASSETS_PATH": server.dependencies.Templating.CustomAssetsPath(),
|
||||
},
|
||||
|
|
@ -48,6 +50,6 @@ func (server *Server) Trigger(ctx context.Context) error {
|
|||
|
||||
func (server *Server) Context(parent component.InstallationContext) component.InstallationContext {
|
||||
return component.InstallationContext{
|
||||
bootstrap.Executable: server.Config.Paths.CurrentExecutable(), // TODO: Does this make sense?
|
||||
bootstrap.Executable: component.GetStill(server).Config.Paths.CurrentExecutable(), // TODO: Does this make sense?
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import (
|
|||
|
||||
// CustomAssetsPath is the path custom assets are stored at
|
||||
func (tpl *Templating) CustomAssetsPath() string {
|
||||
return filepath.Join(tpl.Config.Paths.Root, "core", "assets")
|
||||
return filepath.Join(component.GetStill(tpl).Config.Paths.Root, "core", "assets")
|
||||
}
|
||||
|
||||
func (tpl *Templating) CustomAssetPath(name string) string {
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ var (
|
|||
)
|
||||
|
||||
func (s *Solr) Path() string {
|
||||
return filepath.Join(s.Still.Config.Paths.Root, "core", "solr")
|
||||
return filepath.Join(component.GetStill(s).Config.Paths.Root, "core", "solr")
|
||||
}
|
||||
|
||||
func (*Solr) Context(parent component.InstallationContext) component.InstallationContext {
|
||||
|
|
@ -37,7 +37,7 @@ func (solr *Solr) Stack() component.StackWithResources {
|
|||
ContextPath: "solr",
|
||||
|
||||
EnvContext: map[string]string{
|
||||
"DOCKER_NETWORK_NAME": solr.Config.Docker.Network(),
|
||||
"DOCKER_NETWORK_NAME": component.GetStill(solr).Config.Docker.Network(),
|
||||
},
|
||||
|
||||
MakeDirs: []string{
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ func (sql *SQL) QueryTable(ctx context.Context, table component.Table) (*gorm.DB
|
|||
|
||||
// queryTable returns a gorm.DB to connect to the provided distillery database table
|
||||
func (sql *SQL) queryTable(ctx context.Context, silent bool, table string) (*gorm.DB, error) {
|
||||
conn, err := sql.connect(sql.Config.SQL.Database)
|
||||
conn, err := sql.connect(component.GetStill(sql).Config.SQL.Database)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -113,8 +113,9 @@ func (ssql *SQL) connect(database string) (*sql.DB, error) {
|
|||
|
||||
// dsn returns a dsn fof connecting to the database
|
||||
func (sql *SQL) dsn(database string) string {
|
||||
user := sql.Config.SQL.AdminUsername
|
||||
pass := sql.Config.SQL.AdminPassword
|
||||
config := component.GetStill(sql).Config.SQL
|
||||
user := config.AdminUsername
|
||||
pass := config.AdminPassword
|
||||
network := "tcp"
|
||||
server := sql.ServerURL
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import (
|
|||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/config"
|
||||
config_package "github.com/FAU-CDI/wisski-distillery/internal/config"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
|
||||
"github.com/tkw1536/pkglib/fsx/umaskfree"
|
||||
"github.com/tkw1536/pkglib/yamlx"
|
||||
|
|
@ -32,7 +32,7 @@ var (
|
|||
)
|
||||
|
||||
func (sql *SQL) Path() string {
|
||||
return filepath.Join(sql.Still.Config.Paths.Root, "core", "sql")
|
||||
return filepath.Join(component.GetStill(sql).Config.Paths.Root, "core", "sql")
|
||||
}
|
||||
|
||||
func (*SQL) Context(parent component.InstallationContext) component.InstallationContext {
|
||||
|
|
@ -43,19 +43,20 @@ func (*SQL) Context(parent component.InstallationContext) component.Installation
|
|||
var resources embed.FS
|
||||
|
||||
func (sql *SQL) Stack() component.StackWithResources {
|
||||
config := component.GetStill(sql).Config
|
||||
return component.MakeStack(sql, component.StackWithResources{
|
||||
Resources: resources,
|
||||
ContextPath: "sql",
|
||||
|
||||
EnvContext: map[string]string{
|
||||
"DOCKER_NETWORK_NAME": sql.Config.Docker.Network(),
|
||||
"HTTPS_ENABLED": sql.Config.HTTP.HTTPSEnabledEnv(),
|
||||
"HOST_RULE": sql.Config.HTTP.HostRule(config.PHPMyAdminDomain.Domain()),
|
||||
"DOCKER_NETWORK_NAME": config.Docker.Network(),
|
||||
"HTTPS_ENABLED": config.HTTP.HTTPSEnabledEnv(),
|
||||
"HOST_RULE": config.HTTP.HostRule(config_package.PHPMyAdminDomain.Domain()),
|
||||
},
|
||||
|
||||
ComposerYML: func(root *yaml.Node) (*yaml.Node, error) {
|
||||
// phpmyadmin is exposed => everything is fine
|
||||
if sql.Config.HTTP.PhpMyAdmin.Set && sql.Config.HTTP.PhpMyAdmin.Value {
|
||||
if config.HTTP.PhpMyAdmin.Set && config.HTTP.PhpMyAdmin.Value {
|
||||
return root, nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import (
|
|||
"reflect"
|
||||
"time"
|
||||
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
|
||||
"github.com/FAU-CDI/wisski-distillery/pkg/logging"
|
||||
"github.com/tkw1536/goprogram/exit"
|
||||
"github.com/tkw1536/pkglib/sqlx"
|
||||
|
|
@ -68,6 +69,7 @@ var errSQLUnableToMigrate = exit.Error{
|
|||
|
||||
// Update initializes or updates the SQL database.
|
||||
func (sql *SQL) Update(ctx context.Context, progress io.Writer) error {
|
||||
config := component.GetStill(sql).Config.SQL
|
||||
|
||||
// unsafely create the admin user!
|
||||
{
|
||||
|
|
@ -76,8 +78,8 @@ func (sql *SQL) Update(ctx context.Context, progress io.Writer) error {
|
|||
}
|
||||
logging.LogMessage(progress, "Creating administrative user")
|
||||
{
|
||||
username := sql.Config.SQL.AdminUsername
|
||||
password := sql.Config.SQL.AdminPassword
|
||||
username := config.AdminUsername
|
||||
password := config.AdminPassword
|
||||
if err := sql.CreateSuperuser(ctx, username, password, true); err != nil {
|
||||
return errSQLUnableToCreateUser
|
||||
}
|
||||
|
|
@ -87,10 +89,10 @@ func (sql *SQL) Update(ctx context.Context, progress io.Writer) error {
|
|||
// create the admin user
|
||||
logging.LogMessage(progress, "Creating sql database")
|
||||
{
|
||||
if !sqlx.IsSafeDatabaseLiteral(sql.Config.SQL.Database) {
|
||||
if !sqlx.IsSafeDatabaseLiteral(config.Database) {
|
||||
return errSQLUnsafeDatabaseName
|
||||
}
|
||||
createDBSQL := fmt.Sprintf("CREATE DATABASE IF NOT EXISTS `%s`;", sql.Config.SQL.Database)
|
||||
createDBSQL := fmt.Sprintf("CREATE DATABASE IF NOT EXISTS `%s`;", config.Database)
|
||||
if err := sql.Exec(createDBSQL); err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ func (ssh2 *SSH2) HandleRoute(ctx context.Context, path string) (http.Handler, e
|
|||
}
|
||||
|
||||
// find the host
|
||||
slug, ok := ssh2.Config.HTTP.SlugFromHost(r.Host)
|
||||
slug, ok := component.GetStill(ssh2).Config.HTTP.SlugFromHost(r.Host)
|
||||
if slug == "" || !ok {
|
||||
httpx.TextInterceptor.Intercept(w, r, httpx.ErrNotFound)
|
||||
return
|
||||
|
|
|
|||
|
|
@ -58,10 +58,11 @@ func (i Intercept) Intercept(req component.HostPort) (intercepted bool, ok bool,
|
|||
}
|
||||
|
||||
func (ssh2 *SSH2) Intercepts() []Intercept {
|
||||
upstream := component.GetStill(ssh2).Upstream
|
||||
return ssh2.interceptsC.Get(func() []Intercept {
|
||||
return []Intercept{
|
||||
{Description: "Triplestore", Match: component.HostPort{Host: "triplestore", Port: 7200}, Dest: ssh2.Upstream.Triplestore},
|
||||
{Description: "SQL", Match: component.HostPort{Host: "sql", Port: 3306}, Dest: ssh2.Upstream.SQL},
|
||||
{Description: "Triplestore", Match: component.HostPort{Host: "triplestore", Port: 7200}, Dest: upstream.Triplestore},
|
||||
{Description: "SQL", Match: component.HostPort{Host: "sql", Port: 3306}, Dest: upstream.SQL},
|
||||
{Description: "PHPMyAdmin", Match: component.HostPort{Host: "phpmyadmin", Port: 80}, Dest: component.HostPort{Host: "phpmyadmin", Port: 80}},
|
||||
}
|
||||
})
|
||||
|
|
@ -77,13 +78,15 @@ func (ssh2 *SSH2) getForwardDest(req component.HostPort, ctx ssh.Context) (ok bo
|
|||
return ok, dest, rejectReason
|
||||
}
|
||||
|
||||
config := component.GetStill(ssh2).Config
|
||||
|
||||
// then check the instances
|
||||
slug, ok := ssh2.Config.HTTP.SlugFromHost(req.Host)
|
||||
slug, ok := config.HTTP.SlugFromHost(req.Host)
|
||||
if !ok || req.Port != 22 || !hasPermission(ctx, slug) {
|
||||
return false, dest, "permission denied"
|
||||
}
|
||||
|
||||
return true, component.HostPort{Host: slug + "." + ssh2.Config.HTTP.PrimaryDomain + ".wisski", Port: 22}, ""
|
||||
return true, component.HostPort{Host: slug + "." + config.HTTP.PrimaryDomain + ".wisski", Port: 22}, ""
|
||||
}
|
||||
|
||||
// handleDirectTCP handles a direct tcp connection for the server
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import (
|
|||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
|
||||
"github.com/gliderlabs/ssh"
|
||||
)
|
||||
|
||||
|
|
@ -38,17 +39,18 @@ Press CTRL-C to close this connection.
|
|||
`
|
||||
|
||||
func (ssh2 *SSH2) handleConnection(session ssh.Session) {
|
||||
config := component.GetStill(ssh2).Config
|
||||
slug, _ := getAnyPermission(session.Context())
|
||||
|
||||
banner := welcomeMessage
|
||||
for _, oldnew := range [][2]string{
|
||||
{"${SLUG}", slug},
|
||||
{"${HOSTNAME}", slug + "." + ssh2.Config.HTTP.PrimaryDomain},
|
||||
{"${HOSTNAME}", slug + "." + config.HTTP.PrimaryDomain},
|
||||
|
||||
{"${DOMAIN}", ssh2.Config.HTTP.PanelDomain()},
|
||||
{"${PORT}", strconv.FormatUint(uint64(ssh2.Config.Listen.SSHPort), 10)},
|
||||
{"${DOMAIN}", config.HTTP.PanelDomain()},
|
||||
{"${PORT}", strconv.FormatUint(uint64(config.Listen.SSHPort), 10)},
|
||||
|
||||
{"${HELP_URL}", ssh2.Config.HTTP.JoinPath("user", "ssh").String()},
|
||||
{"${HELP_URL}", config.HTTP.JoinPath("user", "ssh").String()},
|
||||
} {
|
||||
banner = strings.ReplaceAll(banner, oldnew[0], oldnew[1])
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,25 +9,26 @@ import (
|
|||
)
|
||||
|
||||
func (ssh *SSH2) Path() string {
|
||||
return filepath.Join(ssh.Still.Config.Paths.Root, "core", "ssh2")
|
||||
return filepath.Join(component.GetStill(ssh).Config.Paths.Root, "core", "ssh2")
|
||||
}
|
||||
|
||||
//go:embed all:ssh2
|
||||
var resources embed.FS
|
||||
|
||||
func (ssh *SSH2) Stack() component.StackWithResources {
|
||||
config := component.GetStill(ssh).Config
|
||||
return component.MakeStack(ssh, component.StackWithResources{
|
||||
Resources: resources,
|
||||
ContextPath: "ssh2",
|
||||
|
||||
EnvContext: map[string]string{
|
||||
"DOCKER_NETWORK_NAME": ssh.Config.Docker.Network(),
|
||||
"DOCKER_NETWORK_NAME": config.Docker.Network(),
|
||||
|
||||
"CONFIG_PATH": ssh.Config.ConfigPath,
|
||||
"DEPLOY_ROOT": ssh.Config.Paths.Root,
|
||||
"CONFIG_PATH": config.ConfigPath,
|
||||
"DEPLOY_ROOT": config.Paths.Root,
|
||||
|
||||
"SELF_OVERRIDES_FILE": ssh.Config.Paths.OverridesJSON,
|
||||
"SELF_RESOLVER_BLOCK_FILE": ssh.Config.Paths.ResolverBlocks,
|
||||
"SELF_OVERRIDES_FILE": config.Paths.OverridesJSON,
|
||||
"SELF_RESOLVER_BLOCK_FILE": config.Paths.ResolverBlocks,
|
||||
},
|
||||
|
||||
CopyContextFiles: []string{bootstrap.Executable},
|
||||
|
|
@ -36,6 +37,6 @@ func (ssh *SSH2) Stack() component.StackWithResources {
|
|||
|
||||
func (ssh *SSH2) Context(parent component.InstallationContext) component.InstallationContext {
|
||||
return component.InstallationContext{
|
||||
bootstrap.Executable: ssh.Config.Paths.CurrentExecutable(), // TODO: Does this make sense?
|
||||
bootstrap.Executable: component.GetStill(ssh).Config.Paths.CurrentExecutable(), // TODO: Does this make sense?
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import (
|
|||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/rs/zerolog"
|
||||
"github.com/tkw1536/pkglib/timex"
|
||||
|
|
@ -58,12 +59,12 @@ func (rh *RequestHeaders) With(headers RequestHeaders) *RequestHeaders {
|
|||
}
|
||||
|
||||
// DoRest performs a (raw) http request to the without a body.
|
||||
func (ts Triplestore) DoRest(ctx context.Context, timeout time.Duration, method, url string, headers *RequestHeaders) (*http.Response, error) {
|
||||
func (ts *Triplestore) DoRest(ctx context.Context, timeout time.Duration, method, url string, headers *RequestHeaders) (*http.Response, error) {
|
||||
return ts.DoRestWithReader(ctx, timeout, method, url, headers, nil)
|
||||
}
|
||||
|
||||
// DoRestWithForm performs a http request where the body are all bytes read from fieldvalue.
|
||||
func (ts Triplestore) DoRestWithForm(ctx context.Context, timeout time.Duration, method, url string, headers *RequestHeaders, fieldname string, fieldvalue io.Reader) (*http.Response, error) {
|
||||
func (ts *Triplestore) DoRestWithForm(ctx context.Context, timeout time.Duration, method, url string, headers *RequestHeaders, fieldname string, fieldvalue io.Reader) (*http.Response, error) {
|
||||
var buffer bytes.Buffer
|
||||
|
||||
// write the file to it
|
||||
|
|
@ -83,7 +84,7 @@ func (ts Triplestore) DoRestWithForm(ctx context.Context, timeout time.Duration,
|
|||
|
||||
// DoRestWithReader performs a http request where the body is copied from the given io.Reader.
|
||||
// The caller must ensure the reader is closed.
|
||||
func (ts Triplestore) DoRestWithMarshal(ctx context.Context, timeout time.Duration, method, url string, headers *RequestHeaders, body any) (*http.Response, error) {
|
||||
func (ts *Triplestore) DoRestWithMarshal(ctx context.Context, timeout time.Duration, method, url string, headers *RequestHeaders, body any) (*http.Response, error) {
|
||||
// encode into a buffer
|
||||
var buffer bytes.Buffer
|
||||
if err := json.NewEncoder(&buffer).Encode(body); err != nil {
|
||||
|
|
@ -95,7 +96,7 @@ func (ts Triplestore) DoRestWithMarshal(ctx context.Context, timeout time.Durati
|
|||
|
||||
// DoRestWithReader performs a http request where the body is copied from the given io.Reader.
|
||||
// The caller must ensure the reader is closed.
|
||||
func (ts Triplestore) DoRestWithReader(ctx context.Context, timeout time.Duration, method string, url string, headers *RequestHeaders, body io.Reader) (*http.Response, error) {
|
||||
func (ts *Triplestore) DoRestWithReader(ctx context.Context, timeout time.Duration, method string, url string, headers *RequestHeaders, body io.Reader) (*http.Response, error) {
|
||||
// create the request object
|
||||
client := &http.Client{
|
||||
Timeout: timeout,
|
||||
|
|
@ -104,12 +105,14 @@ func (ts Triplestore) DoRestWithReader(ctx context.Context, timeout time.Duratio
|
|||
},
|
||||
}
|
||||
|
||||
config := component.GetStill(ts).Config.TS
|
||||
|
||||
// create the request and authentication
|
||||
req, err := http.NewRequestWithContext(ctx, method, ts.BaseURL+url, body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req.SetBasicAuth(ts.Config.TS.AdminUsername, ts.Config.TS.AdminPassword)
|
||||
req.SetBasicAuth(config.AdminUsername, config.AdminPassword)
|
||||
|
||||
// add extra headers
|
||||
if headers != nil && headers.Accept != "" {
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import (
|
|||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/config"
|
||||
config_package "github.com/FAU-CDI/wisski-distillery/internal/config"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
|
||||
"github.com/tkw1536/pkglib/yamlx"
|
||||
"gopkg.in/yaml.v3"
|
||||
|
|
@ -27,7 +27,7 @@ var (
|
|||
)
|
||||
|
||||
func (ts *Triplestore) Path() string {
|
||||
return filepath.Join(ts.Still.Config.Paths.Root, "core", "triplestore")
|
||||
return filepath.Join(component.GetStill(ts).Config.Paths.Root, "core", "triplestore")
|
||||
}
|
||||
|
||||
func (Triplestore) Context(parent component.InstallationContext) component.InstallationContext {
|
||||
|
|
@ -38,6 +38,7 @@ func (Triplestore) Context(parent component.InstallationContext) component.Insta
|
|||
var resources embed.FS
|
||||
|
||||
func (ts *Triplestore) Stack() component.StackWithResources {
|
||||
config := component.GetStill(ts).Config
|
||||
return component.MakeStack(ts, component.StackWithResources{
|
||||
Resources: resources,
|
||||
ContextPath: "triplestore",
|
||||
|
|
@ -45,14 +46,14 @@ func (ts *Triplestore) Stack() component.StackWithResources {
|
|||
CopyContextFiles: []string{"graphdb.zip"}, // TODO: Move into constant?
|
||||
|
||||
EnvContext: map[string]string{
|
||||
"DOCKER_NETWORK_NAME": ts.Config.Docker.Network(),
|
||||
"HOST_RULE": ts.Config.HTTP.HostRule(config.TriplestoreDomain.Domain()),
|
||||
"HTTPS_ENABLED": ts.Config.HTTP.HTTPSEnabledEnv(),
|
||||
"DOCKER_NETWORK_NAME": config.Docker.Network(),
|
||||
"HOST_RULE": config.HTTP.HostRule(config_package.TriplestoreDomain.Domain()),
|
||||
"HTTPS_ENABLED": config.HTTP.HTTPSEnabledEnv(),
|
||||
},
|
||||
|
||||
ComposerYML: func(root *yaml.Node) (*yaml.Node, error) {
|
||||
// ts is exposed => everything is fine
|
||||
if ts.Config.HTTP.TS.Set && ts.Config.HTTP.TS.Value {
|
||||
if config.HTTP.TS.Set && config.HTTP.TS.Value {
|
||||
return root, nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,13 +6,14 @@ import (
|
|||
"io"
|
||||
"net/http"
|
||||
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
|
||||
"github.com/FAU-CDI/wisski-distillery/pkg/logging"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
var errTriplestoreFailedSecurity = errors.New("failed to enable triplestore security: request did not succeed with HTTP 200 OK")
|
||||
|
||||
func (ts Triplestore) Update(ctx context.Context, progress io.Writer) error {
|
||||
func (ts *Triplestore) Update(ctx context.Context, progress io.Writer) error {
|
||||
logging.LogMessage(progress, "Waiting for Triplestore")
|
||||
if err := ts.Wait(ctx); err != nil {
|
||||
return err
|
||||
|
|
@ -20,8 +21,10 @@ func (ts Triplestore) Update(ctx context.Context, progress io.Writer) error {
|
|||
|
||||
logging.LogMessage(progress, "Resetting admin user password")
|
||||
{
|
||||
res, err := ts.DoRestWithMarshal(ctx, tsTrivialTimeout, http.MethodPut, "/rest/security/users/"+ts.Config.TS.AdminUsername, nil, TriplestoreUserPayload{
|
||||
Password: ts.Config.TS.AdminPassword,
|
||||
config := component.GetStill(ts).Config.TS
|
||||
|
||||
res, err := ts.DoRestWithMarshal(ctx, tsTrivialTimeout, http.MethodPut, "/rest/security/users/"+config.AdminUsername, nil, TriplestoreUserPayload{
|
||||
Password: config.AdminPassword,
|
||||
AppSettings: TriplestoreUserAppSettings{
|
||||
DefaultInference: true,
|
||||
DefaultVisGraphSchema: true,
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ var (
|
|||
)
|
||||
|
||||
func (web *Web) Path() string {
|
||||
return filepath.Join(web.Still.Config.Paths.Root, "core", "web")
|
||||
return filepath.Join(component.GetStill(web).Config.Paths.Root, "core", "web")
|
||||
}
|
||||
|
||||
func (*Web) Context(parent component.InstallationContext) component.InstallationContext {
|
||||
|
|
@ -37,12 +37,13 @@ var dockerComposeHTTPS []byte
|
|||
func (web *Web) Stack() component.StackWithResources {
|
||||
var stack component.StackWithResources
|
||||
|
||||
config := component.GetStill(web).Config
|
||||
stack.EnvContext = map[string]string{
|
||||
"DOCKER_NETWORK_NAME": web.Config.Docker.Network(),
|
||||
"CERT_EMAIL": web.Config.HTTP.CertbotEmail,
|
||||
"DOCKER_NETWORK_NAME": config.Docker.Network(),
|
||||
"CERT_EMAIL": config.HTTP.CertbotEmail,
|
||||
}
|
||||
|
||||
if web.Config.HTTP.HTTPSEnabled() {
|
||||
if config.HTTP.HTTPSEnabled() {
|
||||
stack.ComposerYML = readYaml(dockerComposeHTTPS)
|
||||
stack.TouchFilesPerm = 0600
|
||||
stack.TouchFiles = []string{"acme.json"}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,8 @@ var errBlindUpdateFailed = exit.Error{
|
|||
|
||||
// Update performs a blind drush update
|
||||
func (composer *Composer) Update(ctx context.Context, progress io.Writer) (err error) {
|
||||
defer errBlindUpdateFailed.WithMessageF(composer.Slug).DeferWrap(&err)
|
||||
|
||||
defer errBlindUpdateFailed.WithMessageF(ingredient.GetLiquid(composer).Slug).DeferWrap(&err)
|
||||
|
||||
if err := composer.FixPermission(ctx, progress); err != nil {
|
||||
return err
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ func (drush *Drush) Cron(ctx context.Context, progress io.Writer) error {
|
|||
if err != nil {
|
||||
code := err.(barrel.ExitError).Code
|
||||
// keep going, because we want to run as many crons as possible
|
||||
fmt.Fprintf(progress, "%v", errCronFailed.WithMessageF(drush.Slug, code))
|
||||
fmt.Fprintf(progress, "%v", errCronFailed.WithMessageF(ingredient.GetLiquid(drush).Slug, code))
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import (
|
|||
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/models"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/wisski/ingredient"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/wisski/ingredient/barrel"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/wisski/ingredient/barrel/composer"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/wisski/ingredient/php/extras"
|
||||
|
|
@ -106,7 +107,9 @@ func (provision *Manager) bootstrap(ctx context.Context, progress io.Writer, fla
|
|||
}
|
||||
}
|
||||
|
||||
var sqlDBURL = "mysql://" + provision.SqlUsername + ":" + provision.SqlPassword + "@sql/" + provision.SqlDatabase
|
||||
liquid := ingredient.GetLiquid(provision)
|
||||
|
||||
var sqlDBURL = "mysql://" + liquid.SqlUsername + ":" + liquid.SqlPassword + "@sql/" + liquid.SqlDatabase
|
||||
|
||||
// Use 'drush' to run the site-installation.
|
||||
// Here we need to use the username, password and database creds we made above.
|
||||
|
|
@ -115,8 +118,8 @@ func (provision *Manager) bootstrap(ctx context.Context, progress io.Writer, fla
|
|||
if err := provision.dependencies.Drush.Exec(
|
||||
ctx, progress,
|
||||
"site-install",
|
||||
"standard", "--yes", "--site-name="+provision.Domain(),
|
||||
"--account-name="+provision.DrupalUsername, "--account-pass="+provision.DrupalPassword,
|
||||
"standard", "--yes", "--site-name="+liquid.Domain(),
|
||||
"--account-name="+liquid.DrupalUsername, "--account-pass="+liquid.DrupalPassword,
|
||||
"--db-url="+sqlDBURL,
|
||||
); err != nil {
|
||||
return err
|
||||
|
|
@ -166,11 +169,11 @@ func (provision *Manager) bootstrap(ctx context.Context, progress io.Writer, fla
|
|||
if err := provision.dependencies.Adapters.CreateDistilleryAdapter(ctx, nil, extras.DistilleryAdapter{
|
||||
Label: "Default WissKI Distillery Adapter",
|
||||
MachineName: "default",
|
||||
Description: "Default Adapter for " + provision.Domain(),
|
||||
InstanceDomain: provision.Domain(),
|
||||
GraphDBRepository: provision.GraphDBRepository,
|
||||
GraphDBUsername: provision.GraphDBUsername,
|
||||
GraphDBPassword: provision.GraphDBPassword,
|
||||
Description: "Default Adapter for " + liquid.Domain(),
|
||||
InstanceDomain: liquid.Domain(),
|
||||
GraphDBRepository: liquid.GraphDBRepository,
|
||||
GraphDBUsername: liquid.GraphDBUsername,
|
||||
GraphDBPassword: liquid.GraphDBPassword,
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -185,9 +188,9 @@ func (provision *Manager) bootstrap(ctx context.Context, progress io.Writer, fla
|
|||
|
||||
logging.LogMessage(progress, "Provisioning is now complete")
|
||||
{
|
||||
fmt.Fprintf(progress, "URL: %s\n", provision.URL())
|
||||
fmt.Fprintf(progress, "Username: %s\n", provision.DrupalUsername)
|
||||
fmt.Fprintf(progress, "Password: %s\n", provision.DrupalPassword)
|
||||
fmt.Fprintf(progress, "URL: %s\n", liquid.URL())
|
||||
fmt.Fprintf(progress, "Username: %s\n", liquid.DrupalUsername)
|
||||
fmt.Fprintf(progress, "Password: %s\n", liquid.DrupalPassword)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import (
|
|||
|
||||
// Running checks if this WissKI is currently running.
|
||||
func (barrel *Barrel) Running(ctx context.Context) (bool, error) {
|
||||
containers, err := barrel.Docker.Containers(ctx, barrel.Stack().Dir)
|
||||
containers, err := ingredient.GetLiquid(barrel).Docker.Containers(ctx, barrel.Stack().Dir)
|
||||
if err != nil {
|
||||
// The compose file is gone => the stack doesn't exist.
|
||||
// Probably means some purging got interrupted.
|
||||
|
|
|
|||
|
|
@ -18,7 +18,8 @@ var (
|
|||
)
|
||||
|
||||
func (ssh *SSH) Keys(ctx context.Context) (keys []ssh.PublicKey, err error) {
|
||||
grants, err := ssh.Liquid.Policy.Instance(ctx, ssh.Slug)
|
||||
liquid := ingredient.GetLiquid(ssh)
|
||||
grants, err := liquid.Policy.Instance(ctx, liquid.Slug)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -28,7 +29,7 @@ func (ssh *SSH) Keys(ctx context.Context) (keys []ssh.PublicKey, err error) {
|
|||
if !grant.DrupalAdminRole {
|
||||
continue
|
||||
}
|
||||
ukeys, err := ssh.Liquid.Keys.Keys(ctx, grant.User)
|
||||
ukeys, err := liquid.Keys.Keys(ctx, grant.User)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -50,7 +51,7 @@ func (ssh *SSH) AllKeys(ctx context.Context) (keys []ssh.PublicKey, err error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
gkeys, err := ssh.Liquid.Keys.Admin(ctx)
|
||||
gkeys, err := ingredient.GetLiquid(ssh).Keys.Admin(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import (
|
|||
"path/filepath"
|
||||
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/wisski/ingredient"
|
||||
)
|
||||
|
||||
//go:embed all:barrel
|
||||
|
|
@ -17,9 +18,12 @@ var localSettingsTemplate string
|
|||
|
||||
// Barrel returns a stack representing the running WissKI Instance
|
||||
func (barrel *Barrel) Stack() component.StackWithResources {
|
||||
liquid := ingredient.GetLiquid(barrel)
|
||||
config := ingredient.GetStill(barrel).Config
|
||||
|
||||
return component.StackWithResources{
|
||||
Stack: component.Stack{
|
||||
Dir: barrel.FilesystemBase,
|
||||
Dir: liquid.FilesystemBase,
|
||||
},
|
||||
|
||||
Resources: barrelResources,
|
||||
|
|
@ -30,23 +34,23 @@ func (barrel *Barrel) Stack() component.StackWithResources {
|
|||
},
|
||||
|
||||
EnvContext: map[string]string{
|
||||
"DOCKER_NETWORK_NAME": barrel.Malt.Config.Docker.Network(),
|
||||
"DOCKER_NETWORK_NAME": config.Docker.Network(),
|
||||
|
||||
"SLUG": barrel.Slug,
|
||||
"HOST_RULE": barrel.HostRule(),
|
||||
"WISSKI_HOSTNAME": barrel.Hostname(),
|
||||
"HTTPS_ENABLED": barrel.Malt.Config.HTTP.HTTPSEnabledEnv(),
|
||||
"SLUG": liquid.Slug,
|
||||
"HOST_RULE": liquid.HostRule(),
|
||||
"WISSKI_HOSTNAME": liquid.Hostname(),
|
||||
"HTTPS_ENABLED": config.HTTP.HTTPSEnabledEnv(),
|
||||
|
||||
"DATA_PATH": filepath.Join(barrel.FilesystemBase, "data"),
|
||||
"RUNTIME_DIR": barrel.Malt.Config.Paths.RuntimeDir(),
|
||||
"DATA_PATH": filepath.Join(liquid.FilesystemBase, "data"),
|
||||
"RUNTIME_DIR": config.Paths.RuntimeDir(),
|
||||
|
||||
"LOCAL_SETTINGS_PATH": filepath.Join(barrel.FilesystemBase, localSettingsName),
|
||||
"LOCAL_SETTINGS_PATH": filepath.Join(liquid.FilesystemBase, localSettingsName),
|
||||
"LOCAL_SETTINGS_MOUNT": LocalSettingsPath,
|
||||
|
||||
"BARREL_BASE_IMAGE": barrel.GetDockerBaseImage(),
|
||||
"IIP_SERVER_ENABLED": barrel.GetIIPServerEnabled(),
|
||||
"OPCACHE_MODE": barrel.OpCacheMode(),
|
||||
"CONTENT_SECURITY_POLICY": barrel.ContentSecurityPolicy,
|
||||
"BARREL_BASE_IMAGE": liquid.GetDockerBaseImage(),
|
||||
"IIP_SERVER_ENABLED": liquid.GetIIPServerEnabled(),
|
||||
"OPCACHE_MODE": liquid.OpCacheMode(),
|
||||
"CONTENT_SECURITY_POLICY": liquid.ContentSecurityPolicy,
|
||||
},
|
||||
|
||||
MakeDirs: []string{"data", ".composer"},
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import (
|
|||
"context"
|
||||
"io"
|
||||
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/wisski/ingredient"
|
||||
"github.com/FAU-CDI/wisski-distillery/pkg/logging"
|
||||
)
|
||||
|
||||
|
|
@ -12,7 +13,7 @@ import (
|
|||
func (smanager *SystemManager) BuildSettings(ctx context.Context, progress io.Writer) (err error) {
|
||||
logging.LogMessage(progress, "Updating TRUSTED_HOST_PATTERNS in settings.php")
|
||||
{
|
||||
if err := smanager.dependencies.Settings.SetTrustedDomain(ctx, nil, smanager.Domain()); err != nil {
|
||||
if err := smanager.dependencies.Settings.SetTrustedDomain(ctx, nil, ingredient.GetLiquid(smanager).Domain()); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ func (smanager *SystemManager) ApplyInitial(ctx context.Context, progress io.Wri
|
|||
// start inidicates if the image should be started afterwards
|
||||
func (smanager *SystemManager) apply(ctx context.Context, progress io.Writer, system models.System, start bool) error {
|
||||
// store the new system configuration
|
||||
smanager.Instance.System = system
|
||||
ingredient.GetLiquid(smanager).Instance.System = system
|
||||
if err := smanager.dependencies.Bookkeeping.Save(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,32 +13,34 @@ type Bookkeeping struct {
|
|||
|
||||
// Save saves this instance in the bookkeeping table
|
||||
func (bk *Bookkeeping) Save(ctx context.Context) error {
|
||||
sdb, err := bk.Malt.SQL.QueryTable(ctx, bk.Malt.InstanceTable)
|
||||
liquid := ingredient.GetLiquid(bk)
|
||||
sdb, err := ingredient.GetLiquid(bk).Malt.SQL.QueryTable(ctx, liquid.Malt.InstanceTable)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// it has never been created => we need to create it in the database
|
||||
if bk.Instance.Created.IsZero() {
|
||||
return sdb.Create(&bk.Instance).Error
|
||||
if liquid.Instance.Created.IsZero() {
|
||||
return sdb.Create(&liquid.Instance).Error
|
||||
}
|
||||
|
||||
// Update based on the primary key!
|
||||
return sdb.Select("*").Save(&bk.Instance).Error
|
||||
return sdb.Select("*").Save(&liquid.Instance).Error
|
||||
}
|
||||
|
||||
// Delete deletes this instance from the bookkeeping table
|
||||
func (bk *Bookkeeping) Delete(ctx context.Context) error {
|
||||
sdb, err := bk.Malt.SQL.QueryTable(ctx, bk.Malt.InstanceTable)
|
||||
liquid := ingredient.GetLiquid(bk)
|
||||
sdb, err := liquid.SQL.QueryTable(ctx, liquid.InstanceTable)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// doesn't exist => nothing to delete
|
||||
if bk.Instance.Created.IsZero() {
|
||||
if liquid.Instance.Created.IsZero() {
|
||||
return nil
|
||||
}
|
||||
|
||||
// delete it directly
|
||||
return sdb.Delete(&bk.Instance).Error
|
||||
return sdb.Delete(&liquid.Instance).Error
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ var (
|
|||
)
|
||||
|
||||
// Information fetches information about this WissKI.
|
||||
func (wisski *Info) Information(ctx context.Context, quick bool) (info status.WissKI, err error) {
|
||||
func (nfo *Info) Information(ctx context.Context, quick bool) (info status.WissKI, err error) {
|
||||
// setup flags
|
||||
flags := ingredient.FetcherFlags{
|
||||
Quick: quick,
|
||||
|
|
@ -43,7 +43,7 @@ func (wisski *Info) Information(ctx context.Context, quick bool) (info status.Wi
|
|||
Limit: 5,
|
||||
New: func() *phpx.Server {
|
||||
atomic.AddUint64(&serversUsed, 1)
|
||||
return wisski.dependencies.PHP.NewServer()
|
||||
return nfo.dependencies.PHP.NewServer()
|
||||
},
|
||||
Discard: func(s *phpx.Server) {
|
||||
s.Close()
|
||||
|
|
@ -53,7 +53,7 @@ func (wisski *Info) Information(ctx context.Context, quick bool) (info status.Wi
|
|||
|
||||
// setup a dictionary to record data about how long each operation took.
|
||||
// we use a slice as opposed to a map to avoid having to mutex!
|
||||
fetcherTimes := make([]time.Duration, len(wisski.dependencies.Fetchers))
|
||||
fetcherTimes := make([]time.Duration, len(nfo.dependencies.Fetchers))
|
||||
recordTime := func(i int) func() {
|
||||
start := time.Now()
|
||||
return func() {
|
||||
|
|
@ -64,7 +64,7 @@ func (wisski *Info) Information(ctx context.Context, quick bool) (info status.Wi
|
|||
start := time.Now()
|
||||
{
|
||||
var group errgroup.Group
|
||||
for i, fetcher := range wisski.dependencies.Fetchers {
|
||||
for i, fetcher := range nfo.dependencies.Fetchers {
|
||||
fetcher, flags, i := fetcher, flags, i
|
||||
group.Go(func() error {
|
||||
// quick: don't need to create servers
|
||||
|
|
@ -101,7 +101,7 @@ func (wisski *Info) Information(ctx context.Context, quick bool) (info status.Wi
|
|||
|
||||
// get a map of how long each fetcher took
|
||||
times := zerolog.Dict()
|
||||
for i, fetcher := range wisski.dependencies.Fetchers {
|
||||
for i, fetcher := range nfo.dependencies.Fetchers {
|
||||
tookSum += fetcherTimes[i]
|
||||
times = times.Dur(fetcher.Name(), fetcherTimes[i])
|
||||
}
|
||||
|
|
@ -115,9 +115,11 @@ func (wisski *Info) Information(ctx context.Context, quick bool) (info status.Wi
|
|||
return
|
||||
}
|
||||
|
||||
func (wisski *Info) Fetch(flags ingredient.FetcherFlags, info *status.WissKI) error {
|
||||
func (nfo *Info) Fetch(flags ingredient.FetcherFlags, info *status.WissKI) error {
|
||||
liquid := ingredient.GetLiquid(nfo)
|
||||
|
||||
info.Time = time.Now().UTC()
|
||||
info.Slug = wisski.Slug
|
||||
info.URL = wisski.URL().String()
|
||||
info.Slug = liquid.Slug
|
||||
info.URL = liquid.URL().String()
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,6 @@ func (lbr *SnapshotsFetcher) Fetch(flags ingredient.FetcherFlags, info *status.W
|
|||
return
|
||||
}
|
||||
|
||||
info.Snapshots, _ = lbr.Snapshots(flags.Context)
|
||||
info.Snapshots, _ = ingredient.GetLiquid(lbr).Snapshots(flags.Context)
|
||||
return
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import (
|
|||
"reflect"
|
||||
"strings"
|
||||
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/wisski/liquid"
|
||||
)
|
||||
|
||||
|
|
@ -25,8 +26,18 @@ type Ingredient interface {
|
|||
|
||||
// Base is embedded into every Ingredient
|
||||
type Base struct {
|
||||
name string // name is the name of this ingredient
|
||||
*liquid.Liquid // the underlying liquid
|
||||
name string // name is the name of this ingredient
|
||||
liquid *liquid.Liquid // the underlying liquid
|
||||
}
|
||||
|
||||
// GetLiquid gets the liquid of this Ingredient
|
||||
func GetLiquid(i Ingredient) *liquid.Liquid {
|
||||
return i.getBase().liquid
|
||||
}
|
||||
|
||||
// GetStill returns the still of the distillery associated with the provided ingredient.
|
||||
func GetStill(i Ingredient) component.Still {
|
||||
return component.GetStill(GetLiquid(i).Malt)
|
||||
}
|
||||
|
||||
//lint:ignore U1000 used to implement the private methods of [Component]
|
||||
|
|
@ -38,7 +49,7 @@ func (cb *Base) getBase() *Base {
|
|||
// Init is only intended to be used within a lifetime.Lifetime[Ingredient,*Liquid].
|
||||
func Init(ingredient Ingredient, liquid *liquid.Liquid) {
|
||||
base := ingredient.getBase() // pointer to a struct
|
||||
base.Liquid = liquid
|
||||
base.liquid = liquid
|
||||
base.name = strings.ToLower(reflect.TypeOf(ingredient).Elem().Name())
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -26,26 +26,30 @@ var Locked = exit.Error{
|
|||
|
||||
// TryLock attemps to lock this WissKI and returns if it suceeded
|
||||
func (lock *Locker) TryLock(ctx context.Context) bool {
|
||||
table, err := lock.Malt.SQL.QueryTable(ctx, lock.Malt.LockTable)
|
||||
liquid := ingredient.GetLiquid(lock)
|
||||
|
||||
table, err := liquid.SQL.QueryTable(ctx, liquid.LockTable)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
result := table.FirstOrCreate(&models.Lock{}, models.Lock{Slug: lock.Slug})
|
||||
result := table.FirstOrCreate(&models.Lock{}, models.Lock{Slug: liquid.Slug})
|
||||
return result.Error == nil && result.RowsAffected == 1
|
||||
}
|
||||
|
||||
// TryUnlock attempts to unlock this WissKI and reports if it succeeded.
|
||||
// An Unlock is also attempted when ctx is cancelled.
|
||||
func (lock *Locker) TryUnlock(ctx context.Context) bool {
|
||||
liquid := ingredient.GetLiquid(lock)
|
||||
|
||||
ctx, close := contextx.Anyways(ctx, time.Second)
|
||||
defer close()
|
||||
|
||||
table, err := lock.Malt.SQL.QueryTable(ctx, lock.Malt.LockTable)
|
||||
table, err := liquid.SQL.QueryTable(ctx, liquid.LockTable)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
result := table.Where("slug = ?", lock.Slug).Delete(&models.Lock{})
|
||||
result := table.Where("slug = ?", liquid.Slug).Delete(&models.Lock{})
|
||||
return result.Error == nil && result.RowsAffected == 1
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,13 +10,15 @@ import (
|
|||
// Locked checks if this WissKI is currently locked.
|
||||
// If an error occurs, the instance is considered not locked.
|
||||
func (lock *Locker) Locked(ctx context.Context) (locked bool) {
|
||||
table, err := lock.Malt.SQL.QueryTable(ctx, lock.Malt.LockTable)
|
||||
liquid := ingredient.GetLiquid(lock)
|
||||
|
||||
table, err := liquid.SQL.QueryTable(ctx, liquid.LockTable)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
// check if this instance is locked
|
||||
table.Select("count(*) > 0").Where("slug = ?", lock.Slug).Find(&locked)
|
||||
table.Select("count(*) > 0").Where("slug = ?", liquid.Slug).Find(&locked)
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -35,8 +35,10 @@ var (
|
|||
// NoPrefix checks if this WissKI instance is excluded from generating prefixes.
|
||||
// TODO: Move this to the database!
|
||||
func (prefixes *Prefixes) NoPrefix() bool {
|
||||
liquid := ingredient.GetLiquid(prefixes)
|
||||
|
||||
// FIXME: Ignoring error here!
|
||||
exists, _ := fsx.IsRegular(filepath.Join(prefixes.FilesystemBase, "prefixes.skip"), false)
|
||||
exists, _ := fsx.IsRegular(filepath.Join(liquid.FilesystemBase, "prefixes.skip"), false)
|
||||
return exists
|
||||
}
|
||||
|
||||
|
|
@ -63,9 +65,8 @@ func (prefixes *Prefixes) All(ctx context.Context, server *phpx.Server) ([]strin
|
|||
|
||||
// getLivePrefixes get the list of prefixes found within the live system
|
||||
func (prefixes *Prefixes) getLivePrefixes(ctx context.Context, server *phpx.Server) (pfs []string, err error) {
|
||||
useTS := !(prefixes.Config.TS.DangerouslyUseAdapterPrefixes.Set && prefixes.Config.TS.DangerouslyUseAdapterPrefixes.Value)
|
||||
|
||||
if useTS {
|
||||
danger := ingredient.GetStill(prefixes).Config.TS.DangerouslyUseAdapterPrefixes
|
||||
if !(danger.Set && danger.Value) {
|
||||
pfs, err = prefixes.getTSPrefixes(ctx, server)
|
||||
} else {
|
||||
// danger danger danger: Use the adapter prefixes
|
||||
|
|
@ -107,9 +108,11 @@ func (wisski *Prefixes) getTSPrefixes(ctx context.Context, server *phpx.Server)
|
|||
}
|
||||
|
||||
func (prefixes *Prefixes) blocked() ([]string, error) {
|
||||
config := ingredient.GetStill(prefixes).Config
|
||||
|
||||
// open the resolver block file
|
||||
// TODO: move this to the distillery
|
||||
file, err := os.Open(prefixes.Malt.Config.Paths.ResolverBlocks)
|
||||
file, err := os.Open(config.Paths.ResolverBlocks)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -145,7 +148,7 @@ func hasAnyPrefix(candidate string, prefixes []string) bool {
|
|||
}
|
||||
|
||||
func (wisski *Prefixes) filePrefixes() (prefixes []string, err error) {
|
||||
path := filepath.Join(wisski.FilesystemBase, "prefixes")
|
||||
path := filepath.Join(ingredient.GetLiquid(wisski).FilesystemBase, "prefixes")
|
||||
|
||||
// check that the prefixes path exists
|
||||
{
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ var requirementsPHP string
|
|||
|
||||
// Create creates a new block with the given title and html content
|
||||
func (requirements *Requirements) Get(ctx context.Context, server *phpx.Server) (data []status.Requirement, err error) {
|
||||
err = requirements.dependencies.PHP.ExecScript(ctx, server, &data, requirementsPHP, "get_requirements", requirements.URL().String())
|
||||
err = requirements.dependencies.PHP.ExecScript(ctx, server, &data, requirementsPHP, "get_requirements", ingredient.GetLiquid(requirements).URL().String())
|
||||
if err == nil {
|
||||
// sort first by weight, then by id!
|
||||
slices.SortFunc(data, func(a, b status.Requirement) int {
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ func (up *UserPolicy) Fetch(flags ingredient.FetcherFlags, target *status.WissKI
|
|||
}
|
||||
|
||||
// read the grants into the info struct
|
||||
target.Grants, err = up.Malt.Policy.Instance(flags.Context, up.Slug)
|
||||
liquid := ingredient.GetLiquid(up)
|
||||
target.Grants, err = liquid.Policy.Instance(flags.Context, liquid.Slug)
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ func (u *Users) LoginWithOpt(ctx context.Context, server *phpx.Server, username
|
|||
}
|
||||
|
||||
// and resolve the (possibly relative) reference
|
||||
dest = u.URL().ResolveReference(dest)
|
||||
dest = ingredient.GetLiquid(u).URL().ResolveReference(dest)
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,20 +19,22 @@ var reserveResources embed.FS
|
|||
|
||||
// Stack returns a stack representing the reserve instance
|
||||
func (reserve *Reserve) Stack() component.StackWithResources {
|
||||
liquid := ingredient.GetLiquid(reserve)
|
||||
config := ingredient.GetStill(reserve).Config
|
||||
return component.StackWithResources{
|
||||
Stack: component.Stack{
|
||||
Dir: reserve.FilesystemBase,
|
||||
Dir: liquid.FilesystemBase,
|
||||
},
|
||||
|
||||
Resources: reserveResources,
|
||||
ContextPath: filepath.Join("reserve"),
|
||||
|
||||
EnvContext: map[string]string{
|
||||
"DOCKER_NETWORK_NAME": reserve.Malt.Config.Docker.Network(),
|
||||
"DOCKER_NETWORK_NAME": config.Docker.Network(),
|
||||
|
||||
"SLUG": reserve.Slug,
|
||||
"HOST_RULE": reserve.HostRule(),
|
||||
"HTTPS_ENABLED": reserve.Malt.Config.HTTP.HTTPSEnabledEnv(),
|
||||
"SLUG": liquid.Slug,
|
||||
"HOST_RULE": liquid.HostRule(),
|
||||
"HTTPS_ENABLED": config.HTTP.HTTPSEnabledEnv(),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,13 +46,15 @@ func (trb *TRB) RebuildTriplestore(ctx context.Context, out io.Writer, allowEmpt
|
|||
}
|
||||
fmt.Printf("Wrote %q\n", dumpPath)
|
||||
|
||||
liquid := ingredient.GetLiquid(trb)
|
||||
|
||||
logging.LogMessage(out, "Purging triplestore")
|
||||
if err := trb.Malt.TS.Purge(ctx, trb.Instance, trb.Domain()); err != nil {
|
||||
if err := liquid.TS.Purge(ctx, liquid.Instance, liquid.Domain()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
logging.LogMessage(out, "Provising triplestore")
|
||||
if err := trb.Malt.TS.Provision(ctx, trb.Instance, trb.Domain()); err != nil {
|
||||
if err := liquid.TS.Provision(ctx, liquid.Instance, liquid.Domain()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
@ -82,7 +84,9 @@ func (trb *TRB) makeBackup(ctx context.Context, allowEmptyRepository bool) (path
|
|||
zippedFile := gzip.NewWriter(file)
|
||||
defer zippedFile.Close()
|
||||
|
||||
count, err := trb.Malt.TS.SnapshotDB(ctx, zippedFile, trb.GraphDBRepository)
|
||||
liquid := ingredient.GetLiquid(trb)
|
||||
|
||||
count, err := liquid.TS.SnapshotDB(ctx, zippedFile, liquid.GraphDBRepository)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
|
@ -107,7 +111,8 @@ func (trb *TRB) restoreBackup(ctx context.Context, path string) (err error) {
|
|||
}
|
||||
defer decompressedReader.Close()
|
||||
|
||||
if err := trb.Malt.TS.RestoreDB(ctx, trb.GraphDBRepository, decompressedReader); err != nil {
|
||||
liquid := ingredient.GetLiquid(trb)
|
||||
if err := liquid.TS.RestoreDB(ctx, liquid.GraphDBRepository, decompressedReader); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
|
|
|
|||
|
|
@ -4,11 +4,12 @@ import (
|
|||
"net/url"
|
||||
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/config"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
|
||||
)
|
||||
|
||||
// Domain returns the full domain name of this WissKI
|
||||
func (liquid *Liquid) Domain() string {
|
||||
return liquid.Config.HTTP.HostFromSlug(liquid.Slug)
|
||||
return component.GetStill(liquid).Config.HTTP.HostFromSlug(liquid.Slug)
|
||||
}
|
||||
|
||||
func (liquid *Liquid) Hostname() string {
|
||||
|
|
@ -29,7 +30,7 @@ func (liquid *Liquid) URL() *url.URL {
|
|||
}
|
||||
|
||||
// use http or https scheme depending on if the distillery has it enabled
|
||||
if liquid.Malt.Config.HTTP.HTTPSEnabled() {
|
||||
if component.GetStill(liquid.Malt).Config.HTTP.HTTPSEnabled() {
|
||||
url.Scheme = "https"
|
||||
} else {
|
||||
url.Scheme = "http"
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import (
|
|||
// Liquid is the core of a WissKI Instance and used in every ingredient.
|
||||
type Liquid struct {
|
||||
*malt.Malt
|
||||
models.Instance
|
||||
models.Instance // TODO: move this into an explicit field
|
||||
|
||||
DrupalUsername string
|
||||
DrupalPassword string
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue