diff --git a/cmd/purge.go b/cmd/purge.go index 7183fbf..e5f5e5e 100644 --- a/cmd/purge.go +++ b/cmd/purge.go @@ -75,38 +75,21 @@ func (p purge) Run(context wisski_distillery.Context) error { context.EPrintln(err) } - // remove the triplestore - ts := dis.Triplestore() - logging.LogOperation(func() error { - logging.LogMessage(context.IOStream, "Removing user %s", instance.GraphDBUsername) - if err := ts.PurgeUser(instance.GraphDBUsername); err != nil { - context.EPrintln(err) - } - - logging.LogMessage(context.IOStream, "Removing repository %s", instance.GraphDBRepository) - if err := ts.PurgeRepo(instance.GraphDBRepository); err != nil { - context.EPrintln(err) + // purge all the instance specific resources + if err := logging.LogOperation(func() error { + domain := instance.Domain() + for _, pc := range dis.Provisionable() { + logging.LogMessage(context.IOStream, "Purging %s resources", pc.Name()) + err := pc.Purge(instance.Instance, domain) + if err != nil { + return err + } } return nil - }, context.IOStream, "Removing from Triplestore") - - // remove the sql - logging.LogOperation(func() error { - sql := dis.SQL() - - logging.LogMessage(context.IOStream, "Removing user %s", instance.SqlUsername) - if err := sql.PurgeUser(instance.SqlUsername); err != nil { - context.EPrintln(err) - } - - logging.LogMessage(context.IOStream, "Removing database %s", instance.SqlDatabase) - if err := sql.PurgeDatabase(instance.SqlDatabase); err != nil { - context.EPrintln(err) - } - - return nil - }, context.IOStream, "Removing from SQL") + }, context.IOStream, "Purging instance-specific resources"); err != nil { + return errProvisionGeneric.WithMessageF(slug, err) + } // remove from bookkeeping logging.LogMessage(context.IOStream, "Removing instance from bookkeeping") diff --git a/internal/component/provision.go b/internal/component/provision.go index dd42145..0054422 100644 --- a/internal/component/provision.go +++ b/internal/component/provision.go @@ -4,11 +4,15 @@ import ( "github.com/FAU-CDI/wisski-distillery/internal/models" ) -// Provisionable represents a component with a Provision method. +// Provisionable represents a component with a Provision and a Purge method. type Provisionable interface { Component // Provision provisions resources specific to the provided instance. // Domain holds the full (unique) domain name of the given instance. Provision(instance models.Instance, domain string) error + + // Purge purges resources specific to the provided instance. + // Domain holds the full (unique) domain name of the given instance. + Purge(instance models.Instance, domain string) error } diff --git a/internal/component/sql/provision.go b/internal/component/sql/provision.go index b0dc4e4..ba1a43f 100644 --- a/internal/component/sql/provision.go +++ b/internal/component/sql/provision.go @@ -4,17 +4,26 @@ import ( "errors" "github.com/FAU-CDI/wisski-distillery/internal/models" + "github.com/FAU-CDI/wisski-distillery/pkg/errorx" "github.com/FAU-CDI/wisski-distillery/pkg/sqle" ) var errProvisionInvalidDatabaseParams = errors.New("Provision: Invalid parameters") var errProvisionInvalidGrant = errors.New("Provision: Grant failed") -// ProvisionInstance provisions sql-specific resource for the given instance +// Provision provisions sql-specific resource for the given instance func (sql *SQL) Provision(instance models.Instance, domain string) error { return sql.CreateDatabase(instance.SqlDatabase, instance.SqlUsername, instance.SqlPassword) } +// Purge purges sql-specific resources for the given instance +func (sql *SQL) Purge(instance models.Instance, domain string) error { + return errorx.First( + sql.PurgeDatabase(instance.SqlDatabase), + sql.PurgeUser(instance.SqlUsername), + ) +} + // CreateDatabase creates a new database with the given name. // It then generates a new user, with the name 'user' and the password 'password', that is then granted access to this database. // diff --git a/internal/component/triplestore/provision.go b/internal/component/triplestore/provision.go index 3ec7496..47a5713 100644 --- a/internal/component/triplestore/provision.go +++ b/internal/component/triplestore/provision.go @@ -7,6 +7,7 @@ import ( _ "embed" "github.com/FAU-CDI/wisski-distillery/internal/models" + "github.com/FAU-CDI/wisski-distillery/pkg/errorx" "github.com/FAU-CDI/wisski-distillery/pkg/unpack" "github.com/tkw1536/goprogram/exit" ) @@ -23,6 +24,13 @@ func (ts *Triplestore) Provision(instance models.Instance, domain string) error return ts.CreateRepository(instance.GraphDBRepository, domain, instance.GraphDBUsername, instance.GraphDBPassword) } +func (ts *Triplestore) Purge(instance models.Instance, domain string) error { + return errorx.First( + ts.PurgeRepo(instance.GraphDBRepository), + ts.PurgeUser(instance.GraphDBUsername), + ) +} + func (ts *Triplestore) CreateRepository(name, domain, user, password string) error { if err := ts.Wait(); err != nil { return err diff --git a/pkg/errorx/errorx.go b/pkg/errorx/errorx.go new file mode 100644 index 0000000..7c4528f --- /dev/null +++ b/pkg/errorx/errorx.go @@ -0,0 +1,11 @@ +package errorx + +// First returns the first non-nil error, or nil otherwise. +func First(errors ...error) error { + for _, err := range errors { + if err != nil { + return err + } + } + return nil +}