2018-10-04 23:22:01 +00:00
|
|
|
package allocrunner
|
2018-08-31 00:13:00 +00:00
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"fmt"
|
|
|
|
|
|
|
|
log "github.com/hashicorp/go-hclog"
|
|
|
|
"github.com/hashicorp/nomad/client/allocdir"
|
|
|
|
"github.com/hashicorp/nomad/client/allocwatcher"
|
|
|
|
)
|
|
|
|
|
|
|
|
// diskMigrationHook migrates ephemeral disk volumes. Depends on alloc dir
|
|
|
|
// being built but must be run before anything else manipulates the alloc dir.
|
|
|
|
type diskMigrationHook struct {
|
|
|
|
allocDir *allocdir.AllocDir
|
|
|
|
allocWatcher allocwatcher.PrevAllocWatcher
|
|
|
|
logger log.Logger
|
|
|
|
}
|
|
|
|
|
|
|
|
func newDiskMigrationHook(logger log.Logger, allocWatcher allocwatcher.PrevAllocWatcher, allocDir *allocdir.AllocDir) *diskMigrationHook {
|
|
|
|
h := &diskMigrationHook{
|
|
|
|
allocDir: allocDir,
|
|
|
|
allocWatcher: allocWatcher,
|
|
|
|
}
|
|
|
|
h.logger = logger.Named(h.Name())
|
|
|
|
return h
|
|
|
|
}
|
|
|
|
|
|
|
|
func (h *diskMigrationHook) Name() string {
|
|
|
|
return "migrate_disk"
|
|
|
|
}
|
|
|
|
|
|
|
|
func (h *diskMigrationHook) Prerun(ctx context.Context) error {
|
|
|
|
// Wait for a previous alloc - if any - to terminate
|
|
|
|
if err := h.allocWatcher.Wait(ctx); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
// Wait for data to be migrated from a previous alloc if applicable
|
|
|
|
if err := h.allocWatcher.Migrate(ctx, h.allocDir); err != nil {
|
|
|
|
if err == context.Canceled {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
// Soft-fail on migration errors
|
|
|
|
h.logger.Warn("error migrating data from previous alloc", "error", err)
|
|
|
|
|
|
|
|
// Recreate alloc dir to ensure a clean slate
|
|
|
|
h.allocDir.Destroy()
|
|
|
|
if err := h.allocDir.Build(); err != nil {
|
|
|
|
return fmt.Errorf("failed to clean task directories after failed migration: %v", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|