diff --git a/internal/dis/component/auth/api/api.go b/internal/dis/component/auth/api/api.go index c3efc3d..d8aed16 100644 --- a/internal/dis/component/auth/api/api.go +++ b/internal/dis/component/auth/api/api.go @@ -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"}, diff --git a/internal/dis/component/auth/next/next.go b/internal/dis/component/auth/next/next.go index b00628e..1d5b472 100644 --- a/internal/dis/component/auth/next/next.go +++ b/internal/dis/component/auth/next/next.go @@ -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 } diff --git a/internal/dis/component/auth/panel/ssh.go b/internal/dis/component/auth/panel/ssh.go index 1d867e0..455f26f 100644 --- a/internal/dis/component/auth/panel/ssh.go +++ b/internal/dis/component/auth/panel/ssh.go @@ -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 { diff --git a/internal/dis/component/auth/panel/tokens.go b/internal/dis/component/auth/panel/tokens.go index e9fc2d3..06a72c0 100644 --- a/internal/dis/component/auth/panel/tokens.go +++ b/internal/dis/component/auth/panel/tokens.go @@ -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, diff --git a/internal/dis/component/auth/panel/user.go b/internal/dis/component/auth/panel/user.go index d444dfb..c94e1f9 100644 --- a/internal/dis/component/auth/panel/user.go +++ b/internal/dis/component/auth/panel/user.go @@ -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) } diff --git a/internal/dis/component/auth/session.go b/internal/dis/component/auth/session.go index 09c6ac2..773b1be 100644 --- a/internal/dis/component/auth/session.go +++ b/internal/dis/component/auth/session.go @@ -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) } diff --git a/internal/dis/component/binder/binder.go b/internal/dis/component/binder/binder.go index 1c51359..b30c639 100644 --- a/internal/dis/component/binder/binder.go +++ b/internal/dis/component/binder/binder.go @@ -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(), }, }) } diff --git a/internal/dis/component/component.go b/internal/dis/component/component.go index bf0ffbd..fbb7021 100644 --- a/internal/dis/component/component.go +++ b/internal/dis/component/component.go @@ -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 diff --git a/internal/dis/component/exporter/exporter.go b/internal/dis/component/exporter/exporter.go index cc970f0..8d5c442 100644 --- a/internal/dis/component/exporter/exporter.go +++ b/internal/dis/component/exporter/exporter.go @@ -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. diff --git a/internal/dis/component/exporter/extras_config.go b/internal/dis/component/exporter/extras_config.go index 728b611..6ed4997 100644 --- a/internal/dis/component/exporter/extras_config.go +++ b/internal/dis/component/exporter/extras_config.go @@ -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, } } diff --git a/internal/dis/component/exporter/prune.go b/internal/dis/component/exporter/prune.go index 7949494..df28725 100644 --- a/internal/dis/component/exporter/prune.go +++ b/internal/dis/component/exporter/prune.go @@ -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 diff --git a/internal/dis/component/instances/create.go b/internal/dis/component/instances/create.go index 0cb67e3..119beda 100644 --- a/internal/dis/component/instances/create.go +++ b/internal/dis/component/instances/create.go @@ -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 } diff --git a/internal/dis/component/instances/instances.go b/internal/dis/component/instances/instances.go index 6c300d1..ad7b006 100644 --- a/internal/dis/component/instances/instances.go +++ b/internal/dis/component/instances/instances.go @@ -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 diff --git a/internal/dis/component/instances/runtime.go b/internal/dis/component/instances/runtime.go index 19c3155..344e1de 100644 --- a/internal/dis/component/instances/runtime.go +++ b/internal/dis/component/instances/runtime.go @@ -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 { diff --git a/internal/dis/component/resolver/api.go b/internal/dis/component/resolver/api.go index d72f932..91d3e45 100644 --- a/internal/dis/component/resolver/api.go +++ b/internal/dis/component/resolver/api.go @@ -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"}, diff --git a/internal/dis/component/resolver/resolver.go b/internal/dis/component/resolver/resolver.go index 70f319f..9306814 100644 --- a/internal/dis/component/resolver/resolver.go +++ b/internal/dis/component/resolver/resolver.go @@ -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") } diff --git a/internal/dis/component/server/admin/index.go b/internal/dis/component/server/admin/index.go index 7c85be4..478deac 100644 --- a/internal/dis/component/server/admin/index.go +++ b/internal/dis/component/server/admin/index.go @@ -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 } diff --git a/internal/dis/component/server/admin/instance_ssh.go b/internal/dis/component/server/admin/instance_ssh.go index e727761..becca5f 100644 --- a/internal/dis/component/server/admin/instance_ssh.go +++ b/internal/dis/component/server/admin/instance_ssh.go @@ -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 { diff --git a/internal/dis/component/server/cron/cron.go b/internal/dis/component/server/cron/cron.go index dfd56bf..249fd30 100644 --- a/internal/dis/component/server/cron/cron.go +++ b/internal/dis/component/server/cron/cron.go @@ -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: diff --git a/internal/dis/component/server/handling/handling.go b/internal/dis/component/server/handling/handling.go index e9cf3df..17815de 100644 --- a/internal/dis/component/server/handling/handling.go +++ b/internal/dis/component/server/handling/handling.go @@ -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) diff --git a/internal/dis/component/server/home/home.go b/internal/dis/component/server/home/home.go index 18e054e..d8d8c8d 100644 --- a/internal/dis/component/server/home/home.go +++ b/internal/dis/component/server/home/home.go @@ -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) diff --git a/internal/dis/component/server/home/public.go b/internal/dis/component/server/home/public.go index 9c78075..4692ec5 100644 --- a/internal/dis/component/server/home/public.go +++ b/internal/dis/component/server/home/public.go @@ -48,14 +48,14 @@ type publicContext struct { const logoHTML = template.HTML(``) 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 }) diff --git a/internal/dis/component/server/home/redirect.go b/internal/dis/component/server/home/redirect.go index 6d96ba0..8633a11 100644 --- a/internal/dis/component/server/home/redirect.go +++ b/internal/dis/component/server/home/redirect.go @@ -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 } diff --git a/internal/dis/component/server/list/api.go b/internal/dis/component/server/list/api.go index 1db49bb..769fd4f 100644 --- a/internal/dis/component/server/list/api.go +++ b/internal/dis/component/server/list/api.go @@ -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"}, diff --git a/internal/dis/component/server/list/list.go b/internal/dis/component/server/list/list.go index d5704cc..e535bf7 100644 --- a/internal/dis/component/server/list/list.go +++ b/internal/dis/component/server/list/list.go @@ -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 diff --git a/internal/dis/component/server/news/api.go b/internal/dis/component/server/news/api.go index 3059771..c7a8fc3 100644 --- a/internal/dis/component/server/news/api.go +++ b/internal/dis/component/server/news/api.go @@ -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"}, diff --git a/internal/dis/component/server/server.go b/internal/dis/component/server/server.go index 5b11cc5..8005a63 100644 --- a/internal/dis/component/server/server.go +++ b/internal/dis/component/server/server.go @@ -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 diff --git a/internal/dis/component/server/stack.go b/internal/dis/component/server/stack.go index 028760a..d815074 100644 --- a/internal/dis/component/server/stack.go +++ b/internal/dis/component/server/stack.go @@ -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? } } diff --git a/internal/dis/component/server/templating/assets.go b/internal/dis/component/server/templating/assets.go index b94a934..5b94787 100644 --- a/internal/dis/component/server/templating/assets.go +++ b/internal/dis/component/server/templating/assets.go @@ -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 { diff --git a/internal/dis/component/solr/solr.go b/internal/dis/component/solr/solr.go index b2a6295..970c3e6 100644 --- a/internal/dis/component/solr/solr.go +++ b/internal/dis/component/solr/solr.go @@ -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{ diff --git a/internal/dis/component/sql/connect.go b/internal/dis/component/sql/connect.go index 043cba9..fefba9b 100644 --- a/internal/dis/component/sql/connect.go +++ b/internal/dis/component/sql/connect.go @@ -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 diff --git a/internal/dis/component/sql/sql.go b/internal/dis/component/sql/sql.go index 39c5dad..ffce408 100644 --- a/internal/dis/component/sql/sql.go +++ b/internal/dis/component/sql/sql.go @@ -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 } diff --git a/internal/dis/component/sql/update.go b/internal/dis/component/sql/update.go index 6e58c87..b1e6f88 100644 --- a/internal/dis/component/sql/update.go +++ b/internal/dis/component/sql/update.go @@ -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 } diff --git a/internal/dis/component/ssh2/api.go b/internal/dis/component/ssh2/api.go index 7bc1401..720f663 100644 --- a/internal/dis/component/ssh2/api.go +++ b/internal/dis/component/ssh2/api.go @@ -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 diff --git a/internal/dis/component/ssh2/server_forward.go b/internal/dis/component/ssh2/server_forward.go index 3bf0117..1cd8f8a 100644 --- a/internal/dis/component/ssh2/server_forward.go +++ b/internal/dis/component/ssh2/server_forward.go @@ -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 diff --git a/internal/dis/component/ssh2/server_handler.go b/internal/dis/component/ssh2/server_handler.go index f1ae256..730c00e 100644 --- a/internal/dis/component/ssh2/server_handler.go +++ b/internal/dis/component/ssh2/server_handler.go @@ -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]) } diff --git a/internal/dis/component/ssh2/stack.go b/internal/dis/component/ssh2/stack.go index 194e203..da85add 100644 --- a/internal/dis/component/ssh2/stack.go +++ b/internal/dis/component/ssh2/stack.go @@ -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? } } diff --git a/internal/dis/component/triplestore/database.go b/internal/dis/component/triplestore/database.go index a4ac824..8e3a605 100644 --- a/internal/dis/component/triplestore/database.go +++ b/internal/dis/component/triplestore/database.go @@ -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 != "" { diff --git a/internal/dis/component/triplestore/triplestore.go b/internal/dis/component/triplestore/triplestore.go index 1bb6c52..4a606f8 100644 --- a/internal/dis/component/triplestore/triplestore.go +++ b/internal/dis/component/triplestore/triplestore.go @@ -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 } diff --git a/internal/dis/component/triplestore/update.go b/internal/dis/component/triplestore/update.go index 3af4437..d9f56d0 100644 --- a/internal/dis/component/triplestore/update.go +++ b/internal/dis/component/triplestore/update.go @@ -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, diff --git a/internal/dis/component/web/web.go b/internal/dis/component/web/web.go index ffaf0e1..c3f5ecb 100644 --- a/internal/dis/component/web/web.go +++ b/internal/dis/component/web/web.go @@ -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"} diff --git a/internal/wisski/ingredient/barrel/composer/update.go b/internal/wisski/ingredient/barrel/composer/update.go index 55656f2..415fc06 100644 --- a/internal/wisski/ingredient/barrel/composer/update.go +++ b/internal/wisski/ingredient/barrel/composer/update.go @@ -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 diff --git a/internal/wisski/ingredient/barrel/drush/cron.go b/internal/wisski/ingredient/barrel/drush/cron.go index 9aaa3d3..f119734 100644 --- a/internal/wisski/ingredient/barrel/drush/cron.go +++ b/internal/wisski/ingredient/barrel/drush/cron.go @@ -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 diff --git a/internal/wisski/ingredient/barrel/manager/provision.go b/internal/wisski/ingredient/barrel/manager/provision.go index 095c566..135a81a 100644 --- a/internal/wisski/ingredient/barrel/manager/provision.go +++ b/internal/wisski/ingredient/barrel/manager/provision.go @@ -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 diff --git a/internal/wisski/ingredient/barrel/running.go b/internal/wisski/ingredient/barrel/running.go index 0e1457c..36029bf 100644 --- a/internal/wisski/ingredient/barrel/running.go +++ b/internal/wisski/ingredient/barrel/running.go @@ -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. diff --git a/internal/wisski/ingredient/barrel/ssh/ssh.go b/internal/wisski/ingredient/barrel/ssh/ssh.go index 36dd5e3..0c13aa6 100644 --- a/internal/wisski/ingredient/barrel/ssh/ssh.go +++ b/internal/wisski/ingredient/barrel/ssh/ssh.go @@ -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 } diff --git a/internal/wisski/ingredient/barrel/stack.go b/internal/wisski/ingredient/barrel/stack.go index daf7fe8..3a029a4 100644 --- a/internal/wisski/ingredient/barrel/stack.go +++ b/internal/wisski/ingredient/barrel/stack.go @@ -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"}, diff --git a/internal/wisski/ingredient/barrel/system/settings.go b/internal/wisski/ingredient/barrel/system/settings.go index de8a68f..c6d3bd6 100644 --- a/internal/wisski/ingredient/barrel/system/settings.go +++ b/internal/wisski/ingredient/barrel/system/settings.go @@ -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 } } diff --git a/internal/wisski/ingredient/barrel/system/system.go b/internal/wisski/ingredient/barrel/system/system.go index 86e4410..fdc3e54 100644 --- a/internal/wisski/ingredient/barrel/system/system.go +++ b/internal/wisski/ingredient/barrel/system/system.go @@ -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 } diff --git a/internal/wisski/ingredient/bookkeeping/bookkeeping.go b/internal/wisski/ingredient/bookkeeping/bookkeeping.go index c443d81..832898a 100644 --- a/internal/wisski/ingredient/bookkeeping/bookkeeping.go +++ b/internal/wisski/ingredient/bookkeeping/bookkeeping.go @@ -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 } diff --git a/internal/wisski/ingredient/info/info.go b/internal/wisski/ingredient/info/info.go index 604accc..e1af897 100644 --- a/internal/wisski/ingredient/info/info.go +++ b/internal/wisski/ingredient/info/info.go @@ -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 } diff --git a/internal/wisski/ingredient/info/snapshots.go b/internal/wisski/ingredient/info/snapshots.go index 4c83d31..6539ed7 100644 --- a/internal/wisski/ingredient/info/snapshots.go +++ b/internal/wisski/ingredient/info/snapshots.go @@ -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 } diff --git a/internal/wisski/ingredient/ingredient.go b/internal/wisski/ingredient/ingredient.go index a6c28e2..e3a5d64 100644 --- a/internal/wisski/ingredient/ingredient.go +++ b/internal/wisski/ingredient/ingredient.go @@ -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()) } diff --git a/internal/wisski/ingredient/locker/lock.go b/internal/wisski/ingredient/locker/lock.go index ec2d887..b664bef 100644 --- a/internal/wisski/ingredient/locker/lock.go +++ b/internal/wisski/ingredient/locker/lock.go @@ -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 } diff --git a/internal/wisski/ingredient/locker/locked.go b/internal/wisski/ingredient/locker/locked.go index 20c6dbe..a1750b7 100644 --- a/internal/wisski/ingredient/locker/locked.go +++ b/internal/wisski/ingredient/locker/locked.go @@ -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 } diff --git a/internal/wisski/ingredient/php/extras/prefixes.go b/internal/wisski/ingredient/php/extras/prefixes.go index 63401ba..afbf18a 100644 --- a/internal/wisski/ingredient/php/extras/prefixes.go +++ b/internal/wisski/ingredient/php/extras/prefixes.go @@ -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 { diff --git a/internal/wisski/ingredient/php/extras/requirements.go b/internal/wisski/ingredient/php/extras/requirements.go index cfbb5e6..cfea984 100644 --- a/internal/wisski/ingredient/php/extras/requirements.go +++ b/internal/wisski/ingredient/php/extras/requirements.go @@ -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 { diff --git a/internal/wisski/ingredient/php/users/policy.go b/internal/wisski/ingredient/php/users/policy.go index dae30b9..284e500 100644 --- a/internal/wisski/ingredient/php/users/policy.go +++ b/internal/wisski/ingredient/php/users/policy.go @@ -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 } diff --git a/internal/wisski/ingredient/php/users/users.go b/internal/wisski/ingredient/php/users/users.go index 4ab7c0d..1e24a4e 100644 --- a/internal/wisski/ingredient/php/users/users.go +++ b/internal/wisski/ingredient/php/users/users.go @@ -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 } diff --git a/internal/wisski/ingredient/reserve/reserve.go b/internal/wisski/ingredient/reserve/reserve.go index 90e1488..3d0f709 100644 --- a/internal/wisski/ingredient/reserve/reserve.go +++ b/internal/wisski/ingredient/reserve/reserve.go @@ -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(), }, } } diff --git a/internal/wisski/ingredient/trb/trb.go b/internal/wisski/ingredient/trb/trb.go index e555f05..d6fc348 100644 --- a/internal/wisski/ingredient/trb/trb.go +++ b/internal/wisski/ingredient/trb/trb.go @@ -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 diff --git a/internal/wisski/liquid/domain.go b/internal/wisski/liquid/domain.go index ed062cf..9626fdf 100644 --- a/internal/wisski/liquid/domain.go +++ b/internal/wisski/liquid/domain.go @@ -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" diff --git a/internal/wisski/liquid/liquid.go b/internal/wisski/liquid/liquid.go index ac0ddd5..4f1d289 100644 --- a/internal/wisski/liquid/liquid.go +++ b/internal/wisski/liquid/liquid.go @@ -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