github.com/anth0d/nomad@v0.0.0-20221214183521-ae3a0a2cad06/client/allocrunner/taskrunner/task_dir_hook.go (about)

     1  package taskrunner
     2  
     3  import (
     4  	"context"
     5  	"strings"
     6  
     7  	log "github.com/hashicorp/go-hclog"
     8  
     9  	"github.com/hashicorp/nomad/client/allocdir"
    10  	"github.com/hashicorp/nomad/client/allocrunner/interfaces"
    11  	cconfig "github.com/hashicorp/nomad/client/config"
    12  	"github.com/hashicorp/nomad/client/taskenv"
    13  	"github.com/hashicorp/nomad/nomad/structs"
    14  	"github.com/hashicorp/nomad/plugins/drivers"
    15  )
    16  
    17  const (
    18  	// TaskDirHookIsDoneDataKey is used to mark whether the hook is done. We
    19  	// do not use the Done response value because we still need to set the
    20  	// environment variables every time a task starts.
    21  	// TODO(0.9.1): Use the resp.Env map and switch to resp.Done. We need to
    22  	// remove usage of the envBuilder
    23  	TaskDirHookIsDoneDataKey = "is_done"
    24  )
    25  
    26  type taskDirHook struct {
    27  	runner *TaskRunner
    28  	logger log.Logger
    29  }
    30  
    31  func newTaskDirHook(runner *TaskRunner, logger log.Logger) *taskDirHook {
    32  	td := &taskDirHook{
    33  		runner: runner,
    34  	}
    35  	td.logger = logger.Named(td.Name())
    36  	return td
    37  }
    38  
    39  func (h *taskDirHook) Name() string {
    40  	// Copied in client/state when upgrading from <0.9 schemas, so if you
    41  	// change it here you also must change it there.
    42  	return "task_dir"
    43  }
    44  
    45  func (h *taskDirHook) Prestart(ctx context.Context, req *interfaces.TaskPrestartRequest, resp *interfaces.TaskPrestartResponse) error {
    46  	fsi := h.runner.driverCapabilities.FSIsolation
    47  	if v, ok := req.PreviousState[TaskDirHookIsDoneDataKey]; ok && v == "true" {
    48  		setEnvvars(h.runner.envBuilder, fsi, h.runner.taskDir, h.runner.clientConfig)
    49  		resp.State = map[string]string{
    50  			TaskDirHookIsDoneDataKey: "true",
    51  		}
    52  		return nil
    53  	}
    54  
    55  	cc := h.runner.clientConfig
    56  	chroot := cconfig.DefaultChrootEnv
    57  	if len(cc.ChrootEnv) > 0 {
    58  		chroot = cc.ChrootEnv
    59  	}
    60  
    61  	// Emit the event that we are going to be building the task directory
    62  	h.runner.EmitEvent(structs.NewTaskEvent(structs.TaskSetup).SetMessage(structs.TaskBuildingTaskDir))
    63  
    64  	// Build the task directory structure
    65  	err := h.runner.taskDir.Build(fsi == drivers.FSIsolationChroot, chroot)
    66  	if err != nil {
    67  		return err
    68  	}
    69  
    70  	// Update the environment variables based on the built task directory
    71  	setEnvvars(h.runner.envBuilder, fsi, h.runner.taskDir, h.runner.clientConfig)
    72  	resp.State = map[string]string{
    73  		TaskDirHookIsDoneDataKey: "true",
    74  	}
    75  	return nil
    76  }
    77  
    78  // setEnvvars sets path and host env vars depending on the FS isolation used.
    79  func setEnvvars(envBuilder *taskenv.Builder, fsi drivers.FSIsolation, taskDir *allocdir.TaskDir, conf *cconfig.Config) {
    80  
    81  	envBuilder.SetClientTaskRoot(taskDir.Dir)
    82  	envBuilder.SetClientSharedAllocDir(taskDir.SharedAllocDir)
    83  	envBuilder.SetClientTaskLocalDir(taskDir.LocalDir)
    84  	envBuilder.SetClientTaskSecretsDir(taskDir.SecretsDir)
    85  
    86  	// Set driver-specific environment variables
    87  	switch fsi {
    88  	case drivers.FSIsolationNone:
    89  		// Use host paths
    90  		envBuilder.SetAllocDir(taskDir.SharedAllocDir)
    91  		envBuilder.SetTaskLocalDir(taskDir.LocalDir)
    92  		envBuilder.SetSecretsDir(taskDir.SecretsDir)
    93  	default:
    94  		// filesystem isolation; use container paths
    95  		envBuilder.SetAllocDir(allocdir.SharedAllocContainerPath)
    96  		envBuilder.SetTaskLocalDir(allocdir.TaskLocalContainerPath)
    97  		envBuilder.SetSecretsDir(allocdir.TaskSecretsContainerPath)
    98  	}
    99  
   100  	// Set the host environment variables for non-image based drivers
   101  	if fsi != drivers.FSIsolationImage {
   102  		// COMPAT(1.0) using inclusive language, blacklist is kept for backward compatibility.
   103  		filter := strings.Split(conf.ReadAlternativeDefault(
   104  			[]string{"env.denylist", "env.blacklist"},
   105  			cconfig.DefaultEnvDenylist,
   106  		), ",")
   107  		envBuilder.SetHostEnvvars(filter)
   108  	}
   109  }