d018fcbff7
Tools like `nomad-nodesim` are unable to implement a minimal implementation of an allocrunner so that we can test the client communication without having to lug around the entire allocrunner/taskrunner code base. The allocrunner was implemented with an interface specifically for this purpose, but there were circular imports that made it challenging to use in practice. Move the AllocRunner interface into an inner package and provide a factory function type. Provide a minimal test that exercises the new function so that consumers have some idea of what the minimum implementation required is.
62 lines
1.5 KiB
Go
62 lines
1.5 KiB
Go
// Copyright (c) HashiCorp, Inc.
|
|
// SPDX-License-Identifier: MPL-2.0
|
|
|
|
package allocrunner
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
log "github.com/hashicorp/go-hclog"
|
|
"github.com/hashicorp/nomad/client/allocdir"
|
|
"github.com/hashicorp/nomad/client/config"
|
|
)
|
|
|
|
// 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 config.PrevAllocMigrator
|
|
logger log.Logger
|
|
}
|
|
|
|
func newDiskMigrationHook(logger log.Logger, allocWatcher config.PrevAllocMigrator, 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() error {
|
|
ctx := context.TODO()
|
|
|
|
// 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
|
|
}
|