This commit adds a new option to the admin interface to purge an instance. This requires the user to manually confirm the name of the instance.
86 lines
2.5 KiB
Go
86 lines
2.5 KiB
Go
package purger
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"io"
|
|
|
|
"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/logging"
|
|
"github.com/tkw1536/goprogram/exit"
|
|
)
|
|
|
|
// Purger purges instances from the distillery
|
|
type Purger struct {
|
|
component.Base
|
|
Dependencies struct {
|
|
Instances *instances.Instances
|
|
Provisionable []component.Provisionable
|
|
}
|
|
}
|
|
|
|
var errPurgeNoDetails = exit.Error{
|
|
Message: "unable to find instance details for purge: %s",
|
|
ExitCode: exit.ExitGeneric,
|
|
}
|
|
var errPurgeGeneric = exit.Error{
|
|
Message: "unable to purge instance %q: %s",
|
|
ExitCode: exit.ExitGeneric,
|
|
}
|
|
|
|
// Purge permanently purges an instance from the distillery.
|
|
// The instance does not have to exist; in which case the resources are also deleted.
|
|
func (purger *Purger) Purge(ctx context.Context, out io.Writer, slug string) error {
|
|
logging.LogMessage(out, ctx, "Checking bookkeeping table")
|
|
instance, err := purger.Dependencies.Instances.WissKI(ctx, slug)
|
|
if err == instances.ErrWissKINotFound {
|
|
fmt.Fprintln(out, "Not found in bookkeeping table, assuming defaults")
|
|
instance, err = purger.Dependencies.Instances.Create(slug)
|
|
}
|
|
if err != nil {
|
|
return errPurgeNoDetails.WithMessageF(err)
|
|
}
|
|
|
|
// remove docker stack
|
|
logging.LogMessage(out, ctx, "Stopping and removing docker container")
|
|
if err := instance.Barrel().Stack().Down(ctx, out); err != nil {
|
|
fmt.Fprintln(out, err)
|
|
}
|
|
|
|
// remove the filesystem
|
|
logging.LogMessage(out, ctx, "Removing from filesystem %s", instance.FilesystemBase)
|
|
if err := purger.Environment.RemoveAll(instance.FilesystemBase); err != nil {
|
|
fmt.Fprintln(out, err)
|
|
}
|
|
|
|
// purge all the instance specific resources
|
|
if err := logging.LogOperation(func() error {
|
|
domain := instance.Domain()
|
|
for _, pc := range purger.Dependencies.Provisionable {
|
|
logging.LogMessage(out, ctx, "Purging %s resources", pc.Name())
|
|
err := pc.Purge(ctx, instance.Instance, domain)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}, out, ctx, "Purging instance-specific resources"); err != nil {
|
|
return errPurgeGeneric.WithMessageF(slug, err)
|
|
}
|
|
|
|
// remove from bookkeeping
|
|
logging.LogMessage(out, ctx, "Removing instance from bookkeeping")
|
|
if err := instance.Bookkeeping().Delete(ctx); err != nil {
|
|
fmt.Fprintln(out, err)
|
|
}
|
|
|
|
// remove the filesystem
|
|
logging.LogMessage(out, ctx, "Remove lock data")
|
|
if instance.Locker().TryUnlock(ctx) {
|
|
fmt.Fprintln(out, "instance was not locked")
|
|
}
|
|
|
|
return nil
|
|
}
|