From 6f1ba24761a5890d235c4409fc7ab3850a6de79f Mon Sep 17 00:00:00 2001 From: Tom Wiesing Date: Thu, 1 Dec 2022 12:42:04 +0100 Subject: [PATCH] Update logging behavior --- cmd/backup.go | 2 +- cmd/bootstrap.go | 12 +++--- cmd/monday.go | 12 +++--- cmd/provision.go | 16 ++++---- cmd/purge.go | 16 ++++---- cmd/reserve.go | 10 ++--- cmd/system_pause.go | 8 ++-- cmd/system_update.go | 20 +++++----- cmd/update_prefix_config.go | 3 +- internal/dis/component/backup.go | 4 +- internal/dis/component/control/home/public.go | 10 ++--- .../dis/component/control/home/redirect.go | 6 +-- internal/dis/component/control/server.go | 5 ++- internal/dis/component/exporter/backup.go | 6 +-- internal/dis/component/exporter/iface.go | 25 ++++++------- internal/dis/component/exporter/prune.go | 5 ++- internal/dis/component/exporter/snapshot.go | 14 +++---- internal/dis/component/instances/runtime.go | 4 +- internal/dis/component/resolver/prefixes.go | 6 +-- internal/dis/component/resolver/resolver.go | 5 ++- internal/dis/component/sql/update.go | 10 ++--- internal/dis/component/ssh2/server.go | 4 +- .../dis/component/ssh2/server_hostkeys.go | 37 ++++++++++--------- internal/dis/component/stack.go | 12 +++--- internal/dis/component/triplestore/update.go | 8 ++-- .../wisski/ingredient/barrel/drush/cron.go | 6 +-- pkg/logging/log.go | 23 +++++++++--- program.go | 24 ++++++++++++ 28 files changed, 176 insertions(+), 137 deletions(-) diff --git a/cmd/backup.go b/cmd/backup.go index 1327055..f09e916 100644 --- a/cmd/backup.go +++ b/cmd/backup.go @@ -42,7 +42,7 @@ func (bk backup) Run(context wisski_distillery.Context) error { if !bk.NoPrune { defer logging.LogOperation(func() error { return dis.Exporter().PruneExports(context.Context, context.Stderr) - }, context.Stderr, "Pruning old backups") + }, context.Stderr, context.Context, "Pruning old backups") } // do the handling diff --git a/cmd/bootstrap.go b/cmd/bootstrap.go index 36d0f93..43d8000 100644 --- a/cmd/bootstrap.go +++ b/cmd/bootstrap.go @@ -84,7 +84,7 @@ func (bs cBootstrap) Run(context wisski_distillery.Context) error { } { - logging.LogMessage(context.Stderr, "Creating root deployment directory") + logging.LogMessage(context.Stderr, context.Context, "Creating root deployment directory") if err := env.MkdirAll(root, environment.DefaultDirPerm); err != nil { return errBootstrapFailedToCreateDirectory.WithMessageF(root) } @@ -109,7 +109,7 @@ func (bs cBootstrap) Run(context wisski_distillery.Context) error { } { - logging.LogMessage(context.Stderr, "Copying over wdcli executable") + logging.LogMessage(context.Stderr, context.Context, "Copying over wdcli executable") exe, err := env.Executable() if err != nil { return errBoostrapFailedToCopyExe.WithMessageF(err) @@ -132,7 +132,7 @@ func (bs cBootstrap) Run(context wisski_distillery.Context) error { defer env.Close() return tpl.MarshalTo(env) - }, context.Stderr, "Installing configuration file"); err != nil { + }, context.Stderr, context.Context, "Installing configuration file"); err != nil { return errBootstrapWriteConfig.WithMessageF(err) } @@ -169,7 +169,7 @@ func (bs cBootstrap) Run(context wisski_distillery.Context) error { } return nil - }, context.Stderr, "Creating additional config files"); err != nil { + }, context.Stderr, context.Context, "Creating additional config files"); err != nil { return errBootstrapCreateFile.WithMessageF(err) } } @@ -177,7 +177,7 @@ func (bs cBootstrap) Run(context wisski_distillery.Context) error { } // re-read the configuration and print it! - logging.LogMessage(context.Stderr, "Configuration is now complete") + logging.LogMessage(context.Stderr, context.Context, "Configuration is now complete") f, err := env.Open(envPath) if err != nil { return errBootstrapOpenConfig.WithMessageF(err) @@ -191,7 +191,7 @@ func (bs cBootstrap) Run(context wisski_distillery.Context) error { context.Println(cfg) // Tell the user how to proceed - logging.LogMessage(context.Stderr, "Bootstrap is complete") + logging.LogMessage(context.Stderr, context.Context, "Bootstrap is complete") context.Printf("Adjust the configuration file at %s\n", envPath) context.Printf("Then make sure 'docker compose' is installed.\n") context.Printf("Finally grab a GraphDB zipped source file and run:\n") diff --git a/cmd/monday.go b/cmd/monday.go index 4892bcf..bcb3010 100644 --- a/cmd/monday.go +++ b/cmd/monday.go @@ -39,36 +39,36 @@ func (monday monday) AfterParse() error { func (monday monday) Run(context wisski_distillery.Context) error { if err := logging.LogOperation(func() error { return context.Exec("backup") - }, context.Stderr, "Running backup"); err != nil { + }, context.Stderr, context.Context, "Running backup"); err != nil { return err } if err := logging.LogOperation(func() error { return context.Exec("system_update", monday.Positionals.GraphdbZip) - }, context.Stderr, "Running system_update"); err != nil { + }, context.Stderr, context.Context, "Running system_update"); err != nil { return err } if err := logging.LogOperation(func() error { return context.Exec("rebuild") - }, context.Stderr, "Running rebuild"); err != nil { + }, context.Stderr, context.Context, "Running rebuild"); err != nil { return err } if err := logging.LogOperation(func() error { return context.Exec("update_prefix_config") - }, context.Stderr, "Running update_prefix_config"); err != nil { + }, context.Stderr, context.Context, "Running update_prefix_config"); err != nil { return err } if monday.UpdateInstances { if err := logging.LogOperation(func() error { return context.Exec("blind_update") - }, context.Stderr, "Running blind_update"); err != nil { + }, context.Stderr, context.Context, "Running blind_update"); err != nil { return err } } - logging.LogMessage(context.Stderr, "Done, have a great week!") + logging.LogMessage(context.Stderr, context.Context, "Done, have a great week!") return nil } diff --git a/cmd/provision.go b/cmd/provision.go index 02d6481..55d08b4 100644 --- a/cmd/provision.go +++ b/cmd/provision.go @@ -44,7 +44,7 @@ func (p provision) Run(context wisski_distillery.Context) error { slug := p.Positionals.Slug // check that it doesn't already exist - logging.LogMessage(context.Stderr, "Provisioning new WissKI instance %s", slug) + logging.LogMessage(context.Stderr, context.Context, "Provisioning new WissKI instance %s", slug) if exists, err := dis.Instances().Has(context.Context, slug); err != nil || exists { return errProvisionAlreadyExists.WithMessageF(slug) } @@ -56,7 +56,7 @@ func (p provision) Run(context wisski_distillery.Context) error { } // check that the base directory does not exist - logging.LogMessage(context.Stderr, "Checking that base directory %s does not exist", instance.FilesystemBase) + logging.LogMessage(context.Stderr, context.Context, "Checking that base directory %s does not exist", instance.FilesystemBase) if fsx.IsDirectory(dis.Environment, instance.FilesystemBase) { return errProvisionAlreadyExists.WithMessageF(slug) } @@ -68,7 +68,7 @@ func (p provision) Run(context wisski_distillery.Context) error { } return nil - }, context.Stderr, "Updating bookkeeping database"); err != nil { + }, context.Stderr, context.Context, "Updating bookkeeping database"); err != nil { return err } @@ -76,7 +76,7 @@ func (p provision) Run(context wisski_distillery.Context) error { if err := logging.LogOperation(func() error { domain := instance.Domain() for _, pc := range dis.Provisionable() { - logging.LogMessage(context.Stderr, "Provisioning %s resources", pc.Name()) + logging.LogMessage(context.Stderr, context.Context, "Provisioning %s resources", pc.Name()) err := pc.Provision(context.Context, instance.Instance, domain) if err != nil { return err @@ -84,7 +84,7 @@ func (p provision) Run(context wisski_distillery.Context) error { } return nil - }, context.Stderr, "Provisioning instance-specific resources"); err != nil { + }, context.Stderr, context.Context, "Provisioning instance-specific resources"); err != nil { return errProvisionGeneric.WithMessageF(slug, err) } @@ -95,18 +95,18 @@ func (p provision) Run(context wisski_distillery.Context) error { } return nil - }, context.Stderr, "Running setup scripts"); err != nil { + }, context.Stderr, context.Context, "Running setup scripts"); err != nil { return err } // start the container! - logging.LogMessage(context.Stderr, "Starting Container") + logging.LogMessage(context.Stderr, context.Context, "Starting Container") if err := instance.Barrel().Stack().Up(context.Context, context.Stderr); err != nil { return err } // and we're done! - logging.LogMessage(context.Stderr, "Instance has been provisioned") + logging.LogMessage(context.Stderr, context.Context, "Instance has been provisioned") context.Printf("URL: %s\n", instance.URL().String()) context.Printf("Username: %s\n", instance.DrupalUsername) context.Printf("Password: %s\n", instance.DrupalPassword) diff --git a/cmd/purge.go b/cmd/purge.go index 94f6540..b45a992 100644 --- a/cmd/purge.go +++ b/cmd/purge.go @@ -58,7 +58,7 @@ func (p purge) Run(context wisski_distillery.Context) error { } // load the instance (first via bookkeeping, then via defaults) - logging.LogMessage(context.Stderr, "Checking bookkeeping table") + logging.LogMessage(context.Stderr, context.Context, "Checking bookkeeping table") instance, err := dis.Instances().WissKI(context.Context, slug) if err == instances.ErrWissKINotFound { context.Println("Not found in bookkeeping table, assuming defaults") @@ -69,13 +69,13 @@ func (p purge) Run(context wisski_distillery.Context) error { } // remove docker stack - logging.LogMessage(context.Stderr, "Stopping and removing docker container") + logging.LogMessage(context.Stderr, context.Context, "Stopping and removing docker container") if err := instance.Barrel().Stack().Down(context.Context, context.Stderr); err != nil { context.EPrintln(err) } // remove the filesystem - logging.LogMessage(context.Stderr, "Removing from filesystem %s", instance.FilesystemBase) + logging.LogMessage(context.Stderr, context.Context, "Removing from filesystem %s", instance.FilesystemBase) if err := dis.Still.Environment.RemoveAll(instance.FilesystemBase); err != nil { context.EPrintln(err) } @@ -84,7 +84,7 @@ func (p purge) Run(context wisski_distillery.Context) error { if err := logging.LogOperation(func() error { domain := instance.Domain() for _, pc := range dis.Provisionable() { - logging.LogMessage(context.Stderr, "Purging %s resources", pc.Name()) + logging.LogMessage(context.Stderr, context.Context, "Purging %s resources", pc.Name()) err := pc.Purge(context.Context, instance.Instance, domain) if err != nil { return err @@ -92,22 +92,22 @@ func (p purge) Run(context wisski_distillery.Context) error { } return nil - }, context.Stderr, "Purging instance-specific resources"); err != nil { + }, context.Stderr, context.Context, "Purging instance-specific resources"); err != nil { return errPurgeGeneric.WithMessageF(slug, err) } // remove from bookkeeping - logging.LogMessage(context.Stderr, "Removing instance from bookkeeping") + logging.LogMessage(context.Stderr, context.Context, "Removing instance from bookkeeping") if err := instance.Bookkeeping().Delete(context.Context); err != nil { context.EPrintln(err) } // remove the filesystem - logging.LogMessage(context.Stderr, "Remove lock data") + logging.LogMessage(context.Stderr, context.Context, "Remove lock data") if instance.Locker().TryUnlock(context.Context) { context.EPrintln("instance was not locked") } - logging.LogMessage(context.Stderr, "Instance %s has been purged", slug) + logging.LogMessage(context.Stderr, context.Context, "Instance %s has been purged", slug) return nil } diff --git a/cmd/reserve.go b/cmd/reserve.go index 37117b5..467b409 100644 --- a/cmd/reserve.go +++ b/cmd/reserve.go @@ -45,7 +45,7 @@ func (r reserve) Run(context wisski_distillery.Context) error { slug := r.Positionals.Slug // check that it doesn't already exist - logging.LogMessage(context.Stderr, "Reserving new WissKI instance %s", slug) + logging.LogMessage(context.Stderr, context.Context, "Reserving new WissKI instance %s", slug) if exists, err := dis.Instances().Has(context.Context, slug); err != nil || exists { return errProvisionAlreadyExists.WithMessageF(slug) } @@ -57,7 +57,7 @@ func (r reserve) Run(context wisski_distillery.Context) error { } // check that the base directory does not exist - logging.LogMessage(context.Stderr, "Checking that base directory %s does not exist", instance.FilesystemBase) + logging.LogMessage(context.Stderr, context.Context, "Checking that base directory %s does not exist", instance.FilesystemBase) if fsx.IsDirectory(dis.Environment, instance.FilesystemBase) { return errProvisionAlreadyExists.WithMessageF(slug) } @@ -67,19 +67,19 @@ func (r reserve) Run(context wisski_distillery.Context) error { { if err := logging.LogOperation(func() error { return s.Install(context.Context, context.Stderr, component.InstallationContext{}) - }, context.Stderr, "Installing docker stack"); err != nil { + }, context.Stderr, context.Context, "Installing docker stack"); err != nil { return err } if err := logging.LogOperation(func() error { return s.Update(context.Context, context.Stderr, true) - }, context.Stderr, "Updating docker stack"); err != nil { + }, context.Stderr, context.Context, "Updating docker stack"); err != nil { return err } } // and we're done! - logging.LogMessage(context.Stderr, "Instance has been reserved") + logging.LogMessage(context.Stderr, context.Context, "Instance has been reserved") context.Printf("URL: %s\n", instance.URL().String()) return nil diff --git a/cmd/system_pause.go b/cmd/system_pause.go index 2131a26..9678a84 100644 --- a/cmd/system_pause.go +++ b/cmd/system_pause.go @@ -53,7 +53,7 @@ func (sp systempause) Run(context wisski_distillery.Context) error { } func (sp systempause) start(context wisski_distillery.Context, dis *dis.Distillery) error { - logging.LogMessage(context.Stderr, "Starting Components") + logging.LogMessage(context.Stderr, context.Context, "Starting Components") // find all the core stacks if err := status.RunErrorGroup(context.Stderr, status.Group[component.Installable, error]{ @@ -69,7 +69,7 @@ func (sp systempause) start(context wisski_distillery.Context, dis *dis.Distille return err } - logging.LogMessage(context.Stderr, "Starting Up WissKIs") + logging.LogMessage(context.Stderr, context.Context, "Starting Up WissKIs") // find the instances wissKIs, err := dis.Instances().All(context.Context) @@ -95,7 +95,7 @@ func (sp systempause) start(context wisski_distillery.Context, dis *dis.Distille } func (sp systempause) stop(context wisski_distillery.Context, dis *dis.Distillery) error { - logging.LogMessage(context.Stderr, "Shutting Down WissKIs") + logging.LogMessage(context.Stderr, context.Context, "Shutting Down WissKIs") // find the instances wissKIs, err := dis.Instances().All(context.Context) @@ -117,7 +117,7 @@ func (sp systempause) stop(context wisski_distillery.Context, dis *dis.Distiller return err } - logging.LogMessage(context.Stderr, "Shutting Down Components") + logging.LogMessage(context.Stderr, context.Context, "Shutting Down Components") // find all the core stacks if err := status.RunErrorGroup(context.Stderr, status.Group[component.Installable, error]{ diff --git a/cmd/system_update.go b/cmd/system_update.go index aa6ed71..6f96980 100644 --- a/cmd/system_update.go +++ b/cmd/system_update.go @@ -66,7 +66,7 @@ func (si systemupdate) Run(context wisski_distillery.Context) error { dis := context.Environment // create all the other directories - logging.LogMessage(context.Stderr, "Ensuring distillery installation directories exist") + logging.LogMessage(context.Stderr, context.Context, "Ensuring distillery installation directories exist") for _, d := range []string{ dis.Config.DeployRoot, dis.Instances().Path(), @@ -81,7 +81,7 @@ func (si systemupdate) Run(context wisski_distillery.Context) error { if si.InstallDocker { // install system updates - logging.LogMessage(context.Stderr, "Updating Operating System Packages") + logging.LogMessage(context.Stderr, context.Context, "Updating Operating System Packages") if err := si.mustExec(context, "", "apt-get", "update"); err != nil { return err } @@ -90,7 +90,7 @@ func (si systemupdate) Run(context wisski_distillery.Context) error { } // install docker - logging.LogMessage(context.Stderr, "Installing / Updating Docker") + logging.LogMessage(context.Stderr, context.Context, "Installing / Updating Docker") if err := si.mustExec(context, "", "apt-get", "install", "curl"); err != nil { return err } @@ -100,19 +100,19 @@ func (si systemupdate) Run(context wisski_distillery.Context) error { } } - logging.LogMessage(context.Stderr, "Checking that 'docker' is installed") + logging.LogMessage(context.Stderr, context.Context, "Checking that 'docker' is installed") if err := si.mustExec(context, "", "docker", "--version", dis.Config.DockerNetworkName); err != nil { return err } - logging.LogMessage(context.Stderr, "Checking that 'docker compose' is available") + logging.LogMessage(context.Stderr, context.Context, "Checking that 'docker compose' is available") if err := si.mustExec(context, "", "docker", "compose", "version"); err != nil { return err } // create the docker network // TODO: Use docker API for this - logging.LogMessage(context.Stderr, "Updating Docker Configuration") + logging.LogMessage(context.Stderr, context.Context, "Updating Docker Configuration") si.mustExec(context, "", "docker", "network", "create", dis.Config.DockerNetworkName) // install and update the various stacks! @@ -155,7 +155,7 @@ func (si systemupdate) Run(context wisski_distillery.Context) error { return ud.Update(context.Context, writer) }, }, dis.Installable()) - }, context.Stderr, "Performing Stack Updates"); err != nil { + }, context.Stderr, context.Context, "Performing Stack Updates"); err != nil { return err } @@ -169,17 +169,17 @@ func (si systemupdate) Run(context wisski_distillery.Context) error { return nil } return item.Update(context.Context, context.Stderr) - }, context.Stderr, "Updating Component: %s", name); err != nil { + }, context.Stderr, context.Context, "Updating Component: %s", name); err != nil { return errBootstrapComponent.WithMessageF(name, err) } } return nil - }, context.Stderr, "Performing Component Updates"); err != nil { + }, context.Stderr, context.Context, "Performing Component Updates"); err != nil { return err } // TODO: Register cronjob in /etc/cron.d! - logging.LogMessage(context.Stderr, "System has been updated") + logging.LogMessage(context.Stderr, context.Context, "System has been updated") return nil } diff --git a/cmd/update_prefix_config.go b/cmd/update_prefix_config.go index 27660f2..7dba0e3 100644 --- a/cmd/update_prefix_config.go +++ b/cmd/update_prefix_config.go @@ -7,6 +7,7 @@ import ( wisski_distillery "github.com/FAU-CDI/wisski-distillery" "github.com/FAU-CDI/wisski-distillery/internal/cli" "github.com/FAU-CDI/wisski-distillery/internal/wisski" + "github.com/FAU-CDI/wisski-distillery/pkg/logging" "github.com/tkw1536/goprogram/exit" "github.com/tkw1536/goprogram/status" @@ -43,7 +44,7 @@ func (upc updateprefixconfig) Run(context wisski_distillery.Context) error { } return status.WriterGroup(context.Stderr, upc.Parallel, func(instance *wisski.WissKI, writer io.Writer) error { - fmt.Fprintln(writer, "reading prefixes") + logging.Progress(writer, context.Context, "reading prefixes") err := instance.Prefixes().Update(context.Context) if err != nil { return errPrefixUpdateFailed.Wrap(err) diff --git a/internal/dis/component/backup.go b/internal/dis/component/backup.go index 15a536c..54375aa 100644 --- a/internal/dis/component/backup.go +++ b/internal/dis/component/backup.go @@ -2,13 +2,13 @@ package component import ( "context" - "fmt" "io" "path/filepath" "github.com/FAU-CDI/wisski-distillery/internal/models" "github.com/FAU-CDI/wisski-distillery/pkg/environment" "github.com/FAU-CDI/wisski-distillery/pkg/fsx" + "github.com/FAU-CDI/wisski-distillery/pkg/logging" "github.com/pkg/errors" ) @@ -93,7 +93,7 @@ func (bc *stagingContext) sendPath(path string) { return } - fmt.Fprintln(bc.progress, dst) + logging.Progress(bc.progress, bc.ctx, dst) bc.manifest <- dst } diff --git a/internal/dis/component/control/home/public.go b/internal/dis/component/control/home/public.go index cee35ff..67ad3bb 100644 --- a/internal/dis/component/control/home/public.go +++ b/internal/dis/component/control/home/public.go @@ -3,7 +3,6 @@ package home import ( "bytes" "context" - "fmt" "io" "time" @@ -11,6 +10,7 @@ import ( "github.com/FAU-CDI/wisski-distillery/internal/dis/component/control/static" "github.com/FAU-CDI/wisski-distillery/internal/status" + "github.com/FAU-CDI/wisski-distillery/pkg/logging" "github.com/FAU-CDI/wisski-distillery/pkg/timex" "golang.org/x/sync/errgroup" ) @@ -18,7 +18,7 @@ import ( func (home *Home) updateInstances(ctx context.Context, progress io.Writer) { go func() { for t := range timex.TickContext(ctx, home.RefreshInterval) { - fmt.Fprintf(progress, "[%s]: reloading instance list\n", t.Format(time.Stamp)) + logging.ProgressF(progress, ctx, "[%s]: reloading instance list\n", t.Format(time.Stamp)) err := (func() error { ctx, cancel := context.WithTimeout(ctx, home.RefreshInterval) @@ -33,7 +33,7 @@ func (home *Home) updateInstances(ctx context.Context, progress io.Writer) { return nil })() if err != nil { - fmt.Fprintf(progress, "error reloading instances: %s", err.Error()) + logging.ProgressF(progress, ctx, "error reloading instances: %s", err.Error()) } } }() @@ -55,7 +55,7 @@ func (home *Home) instanceMap(ctx context.Context) (map[string]struct{}, error) func (home *Home) updateRender(ctx context.Context, progress io.Writer) { go func() { for t := range timex.TickContext(ctx, home.RefreshInterval) { - fmt.Fprintf(progress, "[%s]: reloading home render list\n", t.Format(time.Stamp)) + logging.ProgressF(progress, ctx, "[%s]: reloading home render list\n", t.Format(time.Stamp)) err := (func() error { ctx, cancel := context.WithTimeout(ctx, home.RefreshInterval) @@ -70,7 +70,7 @@ func (home *Home) updateRender(ctx context.Context, progress io.Writer) { return nil })() if err != nil { - fmt.Fprintf(progress, "error reloading instances: %s", err.Error()) + logging.ProgressF(progress, ctx, "error reloading instances: %s", err.Error()) } } }() diff --git a/internal/dis/component/control/home/redirect.go b/internal/dis/component/control/home/redirect.go index a8d48dd..388bf7b 100644 --- a/internal/dis/component/control/home/redirect.go +++ b/internal/dis/component/control/home/redirect.go @@ -3,19 +3,19 @@ package home import ( "context" "encoding/json" - "fmt" "io" "net/http" "strings" "time" + "github.com/FAU-CDI/wisski-distillery/pkg/logging" "github.com/FAU-CDI/wisski-distillery/pkg/timex" ) func (home *Home) updateRedirect(ctx context.Context, progress io.Writer) { go func() { for t := range timex.TickContext(ctx, home.RefreshInterval) { - fmt.Fprintf(progress, "[%s]: reloading overrides\n", t.Format(time.Stamp)) + logging.ProgressF(progress, ctx, "[%s]: reloading overrides\n", t.Format(time.Stamp)) err := (func() error { ctx, cancel := context.WithTimeout(ctx, home.RefreshInterval) @@ -30,7 +30,7 @@ func (home *Home) updateRedirect(ctx context.Context, progress io.Writer) { return nil })() if err != nil { - fmt.Fprintf(progress, "error reloading overrides: %s", err.Error()) + logging.ProgressF(progress, ctx, "error reloading overrides: %s", err.Error()) } } diff --git a/internal/dis/component/control/server.go b/internal/dis/component/control/server.go index 9e75210..d50b2ef 100644 --- a/internal/dis/component/control/server.go +++ b/internal/dis/component/control/server.go @@ -2,9 +2,10 @@ package control import ( "context" - "fmt" "io" "net/http" + + "github.com/FAU-CDI/wisski-distillery/pkg/logging" ) // Server returns an http.Mux that implements the main server instance. @@ -18,7 +19,7 @@ func (control *Control) Server(ctx context.Context, progress io.Writer) (*http.S // add all the servable routes! for _, s := range control.Servables { for _, route := range s.Routes() { - fmt.Fprintf(progress, "mounting %s\n", route) + logging.ProgressF(progress, ctx, "mounting %s\n", route) handler, err := s.Handler(ctx, route, progress) if err != nil { return nil, err diff --git a/internal/dis/component/exporter/backup.go b/internal/dis/component/exporter/backup.go index c7535fc..1920895 100644 --- a/internal/dis/component/exporter/backup.go +++ b/internal/dis/component/exporter/backup.go @@ -64,7 +64,7 @@ func (exporter *Exporter) NewBackup(ctx context.Context, progress io.Writer, des backup.EndTime = time.Now().UTC() return nil - }, progress, "Writing backup files") + }, progress, ctx, "Writing backup files") return } @@ -110,7 +110,7 @@ func (backup *Backup) run(ctx context.Context, progress io.Writer, exporter *Exp } return nil - }, progress, "Backing up core components") + }, progress, ctx, "Backing up core components") // backup instances logging.LogOperation(func() error { @@ -165,6 +165,6 @@ func (backup *Backup) run(ctx context.Context, progress io.Writer, exporter *Exp }) return nil - }, progress, "Creating instance snapshots") + }, progress, ctx, "Creating instance snapshots") } diff --git a/internal/dis/component/exporter/iface.go b/internal/dis/component/exporter/iface.go index ee7cd37..5f035ea 100644 --- a/internal/dis/component/exporter/iface.go +++ b/internal/dis/component/exporter/iface.go @@ -2,7 +2,6 @@ package exporter import ( "context" - "fmt" "io" "path/filepath" @@ -53,7 +52,7 @@ func (exporter *Exporter) MakeExport(ctx context.Context, progress io.Writer, ta } // determine target paths - logging.LogMessage(progress, "Determining target paths") + logging.LogMessage(progress, ctx, "Determining target paths") var stagingDir, archivePath string if task.StagingOnly { stagingDir = task.Dest @@ -69,11 +68,11 @@ func (exporter *Exporter) MakeExport(ctx context.Context, progress io.Writer, ta if !task.StagingOnly && archivePath == "" { archivePath = exporter.NewArchivePath(Slug) } - fmt.Fprintf(progress, "Staging Directory: %s\n", stagingDir) - fmt.Fprintf(progress, "Archive Path: %s\n", archivePath) + logging.ProgressF(progress, ctx, "Staging Directory: %s\n", stagingDir) + logging.ProgressF(progress, ctx, "Archive Path: %s\n", archivePath) // create the staging directory - logging.LogMessage(progress, "Creating staging directory") + logging.LogMessage(progress, ctx, "Creating staging directory") err = exporter.Environment.Mkdir(stagingDir, environment.DefaultDirPerm) if !environment.IsExist(err) && err != nil { return err @@ -83,7 +82,7 @@ func (exporter *Exporter) MakeExport(ctx context.Context, progress io.Writer, ta // we need the staging directory to be deleted at the end if !task.StagingOnly { defer func() { - logging.LogMessage(progress, "Removing staging directory") + logging.LogMessage(progress, ctx, "Removing staging directory") exporter.Environment.RemoveAll(stagingDir) }() } @@ -109,7 +108,7 @@ func (exporter *Exporter) MakeExport(ctx context.Context, progress io.Writer, ta // find the report path reportPath := filepath.Join(stagingDir, "report.txt") - fmt.Fprintln(progress, reportPath) + logging.ProgressF(progress, ctx, reportPath) // create the path report, err := exporter.Environment.Create(reportPath, environment.DefaultFilePerm) @@ -122,26 +121,26 @@ func (exporter *Exporter) MakeExport(ctx context.Context, progress io.Writer, ta _, err := sl.Report(report) return err } - }, progress, "Generating %s", Title) + }, progress, ctx, "Generating %s", Title) // if we only requested staging // all that is left is to write the log entry if task.StagingOnly { - logging.LogMessage(progress, "Writing Log Entry") + logging.LogMessage(progress, ctx, "Writing Log Entry") // write out the log entry entry.Path = stagingDir entry.Packed = false exporter.ExporterLogger.Add(ctx, entry) - fmt.Fprintf(progress, "Wrote %s\n", stagingDir) + logging.ProgressF(progress, ctx, "Wrote %s\n", stagingDir) return nil } // package everything up as an archive! if err := logging.LogOperation(func() error { var count int64 - defer func() { fmt.Fprintf(progress, "Wrote %d byte(s) to %s\n", count, archivePath) }() + defer func() { logging.ProgressF(progress, ctx, "Wrote %d byte(s) to %s\n", count, archivePath) }() st := status.NewWithCompat(progress, 1) st.Start() @@ -152,12 +151,12 @@ func (exporter *Exporter) MakeExport(ctx context.Context, progress io.Writer, ta }) return err - }, progress, "Writing archive"); err != nil { + }, progress, ctx, "Writing archive"); err != nil { return err } // write out the log entry - logging.LogMessage(progress, "Writing Log Entry") + logging.LogMessage(progress, ctx, "Writing Log Entry") entry.Path = archivePath entry.Packed = true exporter.ExporterLogger.Add(ctx, entry) diff --git a/internal/dis/component/exporter/prune.go b/internal/dis/component/exporter/prune.go index 9c68155..5ae75d6 100644 --- a/internal/dis/component/exporter/prune.go +++ b/internal/dis/component/exporter/prune.go @@ -2,10 +2,11 @@ package exporter import ( "context" - "fmt" "io" "path/filepath" "time" + + "github.com/FAU-CDI/wisski-distillery/pkg/logging" ) // ShouldPrune determines if a file with the provided modification time should be @@ -43,7 +44,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) + logging.ProgressF(progress, ctx, "Removing %s cause it is older than %d days\n", path, exporter.Config.MaxBackupAge) if err := exporter.Still.Environment.Remove(path); err != nil { return err diff --git a/internal/dis/component/exporter/snapshot.go b/internal/dis/component/exporter/snapshot.go index bd99be6..84697a9 100644 --- a/internal/dis/component/exporter/snapshot.go +++ b/internal/dis/component/exporter/snapshot.go @@ -46,18 +46,18 @@ type Snapshot struct { // Snapshot creates a new snapshot of this instance into dest func (snapshots *Exporter) NewSnapshot(ctx context.Context, instance *wisski.WissKI, progress io.Writer, desc SnapshotDescription) (snapshot Snapshot) { - logging.LogMessage(progress, "Locking instance") + logging.LogMessage(progress, ctx, "Locking instance") if !instance.Locker().TryLock(ctx) { err := locker.Locked - fmt.Fprintln(progress, err) - logging.LogMessage(progress, "Aborting snapshot creation") + logging.ProgressF(progress, ctx, "%v", err) + logging.LogMessage(progress, ctx, "Aborting snapshot creation") return Snapshot{ ErrPanic: err, } } defer func() { - logging.LogMessage(progress, "Unlocking instance") + logging.LogMessage(progress, ctx, "Unlocking instance") instance.Locker().Unlock(ctx) }() @@ -79,7 +79,7 @@ func (snapshots *Exporter) NewSnapshot(ctx context.Context, instance *wisski.Wis snapshot.EndTime = time.Now().UTC() return nil - }, progress, "Writing snapshot files") + }, progress, ctx, "Writing snapshot files") slices.Sort(snapshot.Manifest) return @@ -89,11 +89,11 @@ func (snapshot *Snapshot) makeParts(ctx context.Context, progress io.Writer, sna if !needsRunning && !snapshot.Description.Keepalive { stack := instance.Barrel().Stack() - logging.LogMessage(progress, "Stopping instance") + logging.LogMessage(progress, ctx, "Stopping instance") snapshot.ErrStop = stack.Down(ctx, progress) defer func() { - logging.LogMessage(progress, "Starting instance") + logging.LogMessage(progress, ctx, "Starting instance") snapshot.ErrStart = stack.Up(ctx, progress) }() } diff --git a/internal/dis/component/instances/runtime.go b/internal/dis/component/instances/runtime.go index f29d738..1812c2d 100644 --- a/internal/dis/component/instances/runtime.go +++ b/internal/dis/component/instances/runtime.go @@ -3,9 +3,9 @@ package instances import ( "context" "embed" - "fmt" "io" + "github.com/FAU-CDI/wisski-distillery/pkg/logging" "github.com/FAU-CDI/wisski-distillery/pkg/unpack" "github.com/tkw1536/goprogram/exit" ) @@ -23,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.Still.Environment, instances.Config.RuntimeDir(), "runtime", runtimeResources, func(dst, src string) { - fmt.Fprintf(progress, "[copy] %s\n", dst) + logging.ProgressF(progress, ctx, "[copy] %s\n", dst) }) if err != nil { return errBootstrapFailedRuntime.Wrap(err) diff --git a/internal/dis/component/resolver/prefixes.go b/internal/dis/component/resolver/prefixes.go index 28458e0..3a61c20 100644 --- a/internal/dis/component/resolver/prefixes.go +++ b/internal/dis/component/resolver/prefixes.go @@ -2,10 +2,10 @@ package resolver import ( "context" - "fmt" "io" "time" + "github.com/FAU-CDI/wisski-distillery/pkg/logging" "github.com/FAU-CDI/wisski-distillery/pkg/timex" ) @@ -13,7 +13,7 @@ import ( func (resolver *Resolver) updatePrefixes(ctx context.Context, progress io.Writer) { go func() { for t := range timex.TickContext(ctx, resolver.RefreshInterval) { - fmt.Fprintf(progress, "[%s]: reloading prefixes\n", t.Format(time.Stamp)) + logging.ProgressF(progress, ctx, "[%s]: reloading prefixes\n", t.Format(time.Stamp)) err := (func() (err error) { ctx, cancel := context.WithTimeout(ctx, resolver.RefreshInterval) @@ -28,7 +28,7 @@ func (resolver *Resolver) updatePrefixes(ctx context.Context, progress io.Writer return nil })() if err != nil { - fmt.Fprintf(progress, "error reloading prefixes: %s", err.Error()) + logging.ProgressF(progress, ctx, "error reloading prefixes: %s", err.Error()) } } }() diff --git a/internal/dis/component/resolver/resolver.go b/internal/dis/component/resolver/resolver.go index 363ae8b..6e0346b 100644 --- a/internal/dis/component/resolver/resolver.go +++ b/internal/dis/component/resolver/resolver.go @@ -13,6 +13,7 @@ import ( "github.com/FAU-CDI/wisski-distillery/internal/dis/component" "github.com/FAU-CDI/wisski-distillery/internal/dis/component/instances" "github.com/FAU-CDI/wisski-distillery/pkg/lazy" + "github.com/FAU-CDI/wisski-distillery/pkg/logging" ) type Resolver struct { @@ -45,13 +46,13 @@ func (resolver *Resolver) Handler(ctx context.Context, route string, progress io domainName := resolver.Config.DefaultDomain if domainName != "" { fallback.Data[fmt.Sprintf("^https?://(.*)\\.%s", regexp.QuoteMeta(domainName))] = fmt.Sprintf("https://$1.%s", domainName) - fmt.Fprintf(progress, "registering default domain %s\n", domainName) + logging.ProgressF(progress, ctx, "registering default domain %s\n", domainName) } // handle the extra domains! for _, domain := range resolver.Config.SelfExtraDomains { fallback.Data[fmt.Sprintf("^https?://(.*)\\.%s", regexp.QuoteMeta(domain))] = fmt.Sprintf("https://$1.%s", domainName) - fmt.Fprintf(progress, "registering legacy domain %s\n", domain) + logging.ProgressF(progress, ctx, "registering legacy domain %s\n", domain) } // start updating prefixes diff --git a/internal/dis/component/sql/update.go b/internal/dis/component/sql/update.go index 7c5fc65..9507974 100644 --- a/internal/dis/component/sql/update.go +++ b/internal/dis/component/sql/update.go @@ -52,7 +52,7 @@ func (sql *SQL) Update(ctx context.Context, progress io.Writer) error { if err := sql.unsafeWaitShell(ctx); err != nil { return err } - logging.LogMessage(progress, "Creating administrative user") + logging.LogMessage(progress, ctx, "Creating administrative user") { username := sql.Config.MysqlAdminUser password := sql.Config.MysqlAdminPassword @@ -63,7 +63,7 @@ func (sql *SQL) Update(ctx context.Context, progress io.Writer) error { } // create the admin user - logging.LogMessage(progress, "Creating sql database") + logging.LogMessage(progress, ctx, "Creating sql database") { if !sqle.IsSafeDatabaseLiteral(sql.Config.DistilleryDatabase) { return errSQLUnsafeDatabaseName @@ -75,7 +75,7 @@ func (sql *SQL) Update(ctx context.Context, progress io.Writer) error { } // wait for the database to come up - logging.LogMessage(progress, "Waiting for database update to be complete") + logging.LogMessage(progress, ctx, "Waiting for database update to be complete") sql.WaitQueryTable(ctx) tables := []struct { @@ -108,7 +108,7 @@ func (sql *SQL) Update(ctx context.Context, progress io.Writer) error { // migrate all of the tables! return logging.LogOperation(func() error { for _, table := range tables { - logging.LogMessage(progress, "migrating %q table", table.name) + logging.LogMessage(progress, ctx, "migrating %q table", table.name) db, err := sql.QueryTable(ctx, false, table.table) if err != nil { return errSQLUnableToMigrate.WithMessageF(table.name, "unable to access table") @@ -119,5 +119,5 @@ func (sql *SQL) Update(ctx context.Context, progress io.Writer) error { } } return nil - }, progress, "migrating database tables") + }, progress, ctx, "migrating database tables") } diff --git a/internal/dis/component/ssh2/server.go b/internal/dis/component/ssh2/server.go index 31f0d0a..b8f335f 100644 --- a/internal/dis/component/ssh2/server.go +++ b/internal/dis/component/ssh2/server.go @@ -13,10 +13,10 @@ const ( ) // Server returns an ssh server that implements the main ssh server -func (ssh2 *SSH2) Server(context context.Context, privateKeyPath string, progress io.Writer) (*ssh.Server, error) { +func (ssh2 *SSH2) Server(ctx context.Context, privateKeyPath string, progress io.Writer) (*ssh.Server, error) { var server ssh.Server - if err := ssh2.setupHostKeys(progress, privateKeyPath, &server); err != nil { + if err := ssh2.setupHostKeys(progress, ctx, privateKeyPath, &server); err != nil { return nil, err } diff --git a/internal/dis/component/ssh2/server_hostkeys.go b/internal/dis/component/ssh2/server_hostkeys.go index 35b80c4..9afeecf 100644 --- a/internal/dis/component/ssh2/server_hostkeys.go +++ b/internal/dis/component/ssh2/server_hostkeys.go @@ -1,37 +1,38 @@ package ssh2 import ( + "context" "crypto/ed25519" "crypto/rand" "crypto/rsa" "crypto/x509" "encoding/pem" - "fmt" "io" "github.com/FAU-CDI/wisski-distillery/pkg/environment" + "github.com/FAU-CDI/wisski-distillery/pkg/logging" "github.com/gliderlabs/ssh" "github.com/pkg/errors" gossh "golang.org/x/crypto/ssh" ) -func (ssh2 *SSH2) setupHostKeys(progress io.Writer, privateKeyPath string, server *ssh.Server) error { - return ssh2.UseOrMakeHostKeys(progress, server, privateKeyPath, nil) +func (ssh2 *SSH2) setupHostKeys(progress io.Writer, ctx context.Context, privateKeyPath string, server *ssh.Server) error { + return ssh2.UseOrMakeHostKeys(progress, ctx, server, privateKeyPath, nil) } // UseOrMakeHostKeys is like UseOrMakeHostKey except that it accepts multiple HostKeyAlgorithms. // For each key algorithm, the privateKeyPath is appended with "_" + the name of the algorithm in question. // // When algorithms is nil, picks a reasonable set of default algorithms. -func (ssh2 *SSH2) UseOrMakeHostKeys(progress io.Writer, server *ssh.Server, privateKeyPath string, algorithms []HostKeyAlgorithm) error { +func (ssh2 *SSH2) UseOrMakeHostKeys(progress io.Writer, ctx context.Context, server *ssh.Server, privateKeyPath string, algorithms []HostKeyAlgorithm) error { if algorithms == nil { algorithms = []HostKeyAlgorithm{RSAAlgorithm, ED25519Algorithm} } for _, algorithm := range algorithms { path := privateKeyPath + "_" + string(algorithm) - if err := ssh2.UseOrMakeHostKey(progress, server, path, algorithm); err != nil { + if err := ssh2.UseOrMakeHostKey(progress, ctx, server, path, algorithm); err != nil { return err } } @@ -44,8 +45,8 @@ func (ssh2 *SSH2) UseOrMakeHostKeys(progress io.Writer, server *ssh.Server, priv // // All parameters except the server are passed to ReadOrMakeHostKey. // Please see the appropriate documentation for that function. -func (ssh2 *SSH2) UseOrMakeHostKey(progress io.Writer, server *ssh.Server, privateKeyPath string, algorithm HostKeyAlgorithm) error { - key, err := ssh2.ReadOrMakeHostKey(progress, privateKeyPath, algorithm) +func (ssh2 *SSH2) UseOrMakeHostKey(progress io.Writer, ctx context.Context, server *ssh.Server, privateKeyPath string, algorithm HostKeyAlgorithm) error { + key, err := ssh2.ReadOrMakeHostKey(progress, ctx, privateKeyPath, algorithm) if err != nil { return err } @@ -60,17 +61,17 @@ func (ssh2 *SSH2) UseOrMakeHostKey(progress io.Writer, server *ssh.Server, priva // // This function assumes that if there is a host key in privateKeyPath it uses the provided HostKeyAlgorithm. // It makes no attempt at verifiying this; the key mail fail to load and return an error, or it may load incorrect data. -func (ssh2 *SSH2) ReadOrMakeHostKey(progress io.Writer, privateKeyPath string, algorithm HostKeyAlgorithm) (key gossh.Signer, err error) { +func (ssh2 *SSH2) ReadOrMakeHostKey(progress io.Writer, ctx context.Context, privateKeyPath string, algorithm HostKeyAlgorithm) (key gossh.Signer, err error) { hostKey := NewHostKey(algorithm) if _, e := ssh2.Environment.Lstat(privateKeyPath); environment.IsNotExist(e) { // path doesn't exist => generate a new key there! - err = ssh2.makeHostKey(progress, hostKey, privateKeyPath) + err = ssh2.makeHostKey(progress, ctx, hostKey, privateKeyPath) if err != nil { err = errors.Wrap(err, "Unable to generate new host key") return } } - err = ssh2.loadHostKey(progress, hostKey, privateKeyPath) + err = ssh2.loadHostKey(progress, ctx, hostKey, privateKeyPath) if err != nil { return nil, err } @@ -78,8 +79,8 @@ func (ssh2 *SSH2) ReadOrMakeHostKey(progress io.Writer, privateKeyPath string, a } // loadHostKey loadsa host key -func (ssh2 *SSH2) loadHostKey(progress io.Writer, key HostKey, path string) (err error) { - fmt.Fprintf(progress, "Loading hostkey (algorithm %s) from %q", key.Algorithm(), path) +func (ssh2 *SSH2) loadHostKey(progress io.Writer, ctx context.Context, key HostKey, path string) (err error) { + logging.ProgressF(progress, ctx, "Loading hostkey (algorithm %s) from %q", key.Algorithm(), path) // read all the bytes from the file privateKeyBytes, err := environment.ReadFile(ssh2.Environment, path) @@ -104,10 +105,10 @@ func (ssh2 *SSH2) loadHostKey(progress io.Writer, key HostKey, path string) (err } // makeHostKey makes a new host key -func (ssh2 *SSH2) makeHostKey(progress io.Writer, key HostKey, path string) error { - fmt.Fprintf(progress, "Writing hostkey (algorithm %s) to %q", key.Algorithm(), path) +func (ssh2 *SSH2) makeHostKey(progress io.Writer, ctx context.Context, key HostKey, path string) error { + logging.ProgressF(progress, ctx, "Writing hostkey (algorithm %s) to %q", key.Algorithm(), path) - if err := key.Generate(0, nil); err != nil { + if err := key.Generate(ctx, 0, nil); err != nil { return errors.Wrap(err, "Failed to generate key") } @@ -137,7 +138,7 @@ type HostKey interface { // // keySize is the desired public key size in bits. When keySize is 0, a sensible default is used. // random is the source of randomness. If random is nil, crypto/rand.Reader will be used. - Generate(keySize int, random io.Reader) error + Generate(ctx context.Context, keySize int, random io.Reader) error // MarshalPEM marshals the private key into a pem.Block to be used for exporting. // The format is not guaranteed to follow any kind of standard, only that it is readable with the corresponding UnmarshalPEM. @@ -191,7 +192,7 @@ func (ek *ed25519HostKey) Algorithm() HostKeyAlgorithm { var errKeySizeUnsupported = errors.New("ed25519HostKey.Generate(): keySize not supported") -func (ek *ed25519HostKey) Generate(keySize int, random io.Reader) (err error) { +func (ek *ed25519HostKey) Generate(ctx context.Context, keySize int, random io.Reader) (err error) { if keySize != 0 && keySize != ed25519.PublicKeySize { return errKeySizeUnsupported } @@ -251,7 +252,7 @@ func (rk *rsaHostKey) Algorithm() HostKeyAlgorithm { return RSAAlgorithm } -func (rk *rsaHostKey) Generate(keySize int, random io.Reader) (err error) { +func (rk *rsaHostKey) Generate(ctx context.Context, keySize int, random io.Reader) (err error) { if keySize == 0 { keySize = rk.defaultBitSize } diff --git a/internal/dis/component/stack.go b/internal/dis/component/stack.go index 5f21d84..1eafe24 100644 --- a/internal/dis/component/stack.go +++ b/internal/dis/component/stack.go @@ -5,13 +5,13 @@ import ( "bufio" "bytes" "context" - "fmt" "io" "io/fs" "path/filepath" "github.com/FAU-CDI/wisski-distillery/pkg/environment" "github.com/FAU-CDI/wisski-distillery/pkg/fsx" + "github.com/FAU-CDI/wisski-distillery/pkg/logging" "github.com/FAU-CDI/wisski-distillery/pkg/unpack" "github.com/pkg/errors" "github.com/tkw1536/goprogram/stream" @@ -231,7 +231,7 @@ func (is StackWithResources) Install(ctx context.Context, progress io.Writer, co is.ContextPath, is.Resources, func(dst, src string) { - fmt.Fprintf(progress, "[install] %s\n", dst) + logging.ProgressF(progress, ctx, "[install] %s\n", dst) }, ); err != nil { return err @@ -241,7 +241,7 @@ func (is StackWithResources) Install(ctx context.Context, progress io.Writer, co // configure .env envDest := filepath.Join(is.Dir, ".env") if is.EnvPath != "" && is.EnvContext != nil { - fmt.Fprintf(progress, "[config] %s\n", envDest) + logging.ProgressF(progress, ctx, "[config] %s\n", envDest) if err := unpack.InstallTemplate( env, envDest, @@ -258,7 +258,7 @@ func (is StackWithResources) Install(ctx context.Context, progress io.Writer, co // find the destination! dst := filepath.Join(is.Dir, name) - fmt.Fprintf(progress, "[make] %s\n", dst) + logging.ProgressF(progress, ctx, "[make] %s\n", dst) if is.MakeDirsPerm == fs.FileMode(0) { is.MakeDirsPerm = environment.DefaultDirPerm } @@ -279,7 +279,7 @@ func (is StackWithResources) Install(ctx context.Context, progress io.Writer, co dst := filepath.Join(is.Dir, name) // copy over file from context - fmt.Fprintf(progress, "[copy] %s (from %s)\n", dst, src) + logging.ProgressF(progress, ctx, "[copy] %s (from %s)\n", dst, src) if err := fsx.CopyFile(ctx, env, dst, src); err != nil { return errors.Wrapf(err, "Unable to copy file %s", src) } @@ -290,7 +290,7 @@ func (is StackWithResources) Install(ctx context.Context, progress io.Writer, co // find the destination! dst := filepath.Join(is.Dir, name) - fmt.Fprintf(progress, "[touch] %s\n", dst) + logging.ProgressF(progress, ctx, "[touch] %s\n", dst) if err := fsx.Touch(env, dst, is.TouchFilesPerm); err != nil { return err } diff --git a/internal/dis/component/triplestore/update.go b/internal/dis/component/triplestore/update.go index 02107bd..77d9fa4 100644 --- a/internal/dis/component/triplestore/update.go +++ b/internal/dis/component/triplestore/update.go @@ -13,12 +13,12 @@ import ( 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 { - logging.LogMessage(progress, "Waiting for Triplestore") + logging.LogMessage(progress, ctx, "Waiting for Triplestore") if err := ts.Wait(ctx); err != nil { return err } - logging.LogMessage(progress, "Resetting admin user password") + logging.LogMessage(progress, ctx, "Resetting admin user password") { res, err := ts.OpenRaw(ctx, "PUT", "/rest/security/users/"+ts.Config.TriplestoreAdminUser, TriplestoreUserPayload{ Password: ts.Config.TriplestoreAdminPassword, @@ -43,14 +43,14 @@ func (ts Triplestore) Update(ctx context.Context, progress io.Writer) error { case http.StatusUnauthorized: // a password is needed => security is already enabled. // the password may or may not work, but that's a problem for later - logging.LogMessage(progress, "Security is already enabled") + logging.LogMessage(progress, ctx, "Security is already enabled") return nil default: return fmt.Errorf("failed to create triplestore user: %s", err) } } - logging.LogMessage(progress, "Enabling Triplestore security") + logging.LogMessage(progress, ctx, "Enabling Triplestore security") { res, err := ts.OpenRaw(ctx, "POST", "/rest/security", true, "", "") if err != nil { diff --git a/internal/wisski/ingredient/barrel/drush/cron.go b/internal/wisski/ingredient/barrel/drush/cron.go index 3387034..fd3f7a8 100644 --- a/internal/wisski/ingredient/barrel/drush/cron.go +++ b/internal/wisski/ingredient/barrel/drush/cron.go @@ -2,7 +2,6 @@ package drush import ( "context" - "fmt" "time" "io" @@ -10,6 +9,7 @@ import ( "github.com/FAU-CDI/wisski-distillery/internal/phpx" "github.com/FAU-CDI/wisski-distillery/internal/status" "github.com/FAU-CDI/wisski-distillery/internal/wisski/ingredient" + "github.com/FAU-CDI/wisski-distillery/pkg/logging" "github.com/tkw1536/goprogram/exit" "github.com/tkw1536/goprogram/stream" ) @@ -22,12 +22,12 @@ var errCronFailed = exit.Error{ func (drush *Drush) Cron(ctx context.Context, progress io.Writer) error { code, err := drush.Barrel.Shell(ctx, stream.NonInteractive(progress), "/runtime/cron.sh") if err != nil { - fmt.Fprintln(progress, err) + logging.ProgressF(progress, ctx, "%v", err) } if code != 0 { // keep going, because we want to run as many crons as possible err = errCronFailed.WithMessageF(drush.Slug, code) - fmt.Fprintln(progress, err) + logging.ProgressF(progress, ctx, "%v", err) } return nil diff --git a/pkg/logging/log.go b/pkg/logging/log.go index 76ae243..5ce3835 100644 --- a/pkg/logging/log.go +++ b/pkg/logging/log.go @@ -1,6 +1,7 @@ package logging import ( + "context" "fmt" "io" "strings" @@ -9,20 +10,30 @@ import ( ) // LogOperation logs a message that is displayed to the user, and then increases the log indent level. -func LogOperation(operation func() error, progress io.Writer, format string, args ...interface{}) error { - logOperation(progress, getIndent(progress), format, args...) +func LogOperation(operation func() error, progress io.Writer, ctx context.Context, format string, args ...interface{}) error { + logOperation(progress, ctx, getIndent(progress), format, args...) incIndent(progress) defer decIndent(progress) return operation() } -// LogMessage logs a message that is displayed to the user -func LogMessage(progress io.Writer, format string, args ...interface{}) (int, error) { - return logOperation(progress, getIndent(progress), format, args...) +// Progress writes a progress message to the given progress writer. +func Progress(progress io.Writer, ctx context.Context, message string) { + io.WriteString(progress, message) } -func logOperation(progress io.Writer, indent int, format string, args ...interface{}) (int, error) { +// ProgressF is like progress, but uses fmt.Sprintf() +func ProgressF(progress io.Writer, ctx context.Context, format string, args ...interface{}) { + Progress(progress, ctx, fmt.Sprintf(format, args...)) +} + +// LogMessage logs a message that is displayed to the user +func LogMessage(progress io.Writer, ctx context.Context, format string, args ...interface{}) (int, error) { + return logOperation(progress, ctx, getIndent(progress), format, args...) +} + +func logOperation(progress io.Writer, ctx context.Context, indent int, format string, args ...interface{}) (int, error) { message := "\033[1m" + strings.Repeat(" ", indent+1) + "=> " + format + "\033[0m\n" if !streamIsTerminal(progress) { message = " => " + format + "\n" diff --git a/program.go b/program.go index 2150cce..4b3cc88 100644 --- a/program.go +++ b/program.go @@ -22,6 +22,29 @@ type wdCliFlags = cli.Flags type Program = goprogram.Program[wdcliEnv, wdcliParameters, wdCliFlags, wdcliRequirements] type Command = goprogram.Command[wdcliEnv, wdcliParameters, wdCliFlags, wdcliRequirements] + +// Context holds the context passed to any wdcli command. +// +// The context contains a reference to a "context.Context" as well as an IOStream. +// +// The context.Context holds a global context. +// It is initialized in the NewContext function below. +// +// It is cancelled if the user sends SIGINT or SIGKILL. +// Despite the context being a pseudo-global, it is passed to (almost) every function using the variable name "ctx". +// +// The IOStream is typically used in three ways: +// +// - Standard output is used to log events +// - Standard error is used to interactively display progress +// - Standard input is passed to a (few) interactive programs +// +// The standard output writer is passed directly into the context, see the "pkg/logging" package for conventions. +// Other parts are passed around (standard error using the variable name "progress") as required. +// +// The IOStream as a whole is only passed to functions that exist directly under cmd/. +// +// TODO(twiesing): The logging on the standard logger is still to be done. type Context = goprogram.Context[wdcliEnv, wdcliParameters, wdCliFlags, wdcliRequirements] type Arguments = goprogram.Arguments[wdCliFlags] type ContextCleanupFunc = goprogram.ContextCleanupFunc[wdcliEnv, wdcliParameters, wdCliFlags, wdcliRequirements] @@ -58,6 +81,7 @@ func NewProgram() Program { return parent, nil, nil } ctx, stop := signal.NotifyContext(parent, os.Interrupt) + // ctx = zerolog.New(zerolog.NewConsoleWriter()).WithContext(ctx) return ctx, func(context *Context) { stop() }, nil },