github.com/jmitchell/nomad@v0.1.3-0.20151007230021-7ab84c2862d8/client/executor/exec.go (about) 1 // Package exec is used to invoke child processes across various platforms to 2 // provide the following features: 3 // 4 // - Least privilege 5 // - Resource constraints 6 // - Process isolation 7 // 8 // A "platform" may be defined as coarsely as "Windows" or as specifically as 9 // "linux 3.20 with systemd". This allows Nomad to use best-effort, best- 10 // available capabilities of each platform to provide resource constraints, 11 // process isolation, and security features, or otherwise take advantage of 12 // features that are unique to that platform. 13 // 14 // The `semantics of any particular instance are left up to the implementation. 15 // However, these should be completely transparent to the calling context. In 16 // other words, the Java driver should be able to call exec for any platform and 17 // just work. 18 package executor 19 20 import ( 21 "fmt" 22 "os/exec" 23 "path/filepath" 24 25 "github.com/hashicorp/nomad/client/allocdir" 26 "github.com/hashicorp/nomad/nomad/structs" 27 ) 28 29 var errNoResources = fmt.Errorf("No resources are associated with this task") 30 31 // Executor is an interface that any platform- or capability-specific exec 32 // wrapper must implement. You should not need to implement a Java executor. 33 // Rather, you would implement a cgroups executor that the Java driver will use. 34 type Executor interface { 35 // Limit must be called before Start and restricts the amount of resources 36 // the process can use. Note that an error may be returned ONLY IF the 37 // executor implements resource limiting. Otherwise Limit is ignored. 38 Limit(*structs.Resources) error 39 40 // ConfigureTaskDir must be called before Start and ensures that the tasks 41 // directory is properly configured. 42 ConfigureTaskDir(taskName string, alloc *allocdir.AllocDir) error 43 44 // Start the process. This may wrap the actual process in another command, 45 // depending on the capabilities in this environment. Errors that arise from 46 // Limits or Runas may bubble through Start() 47 Start() error 48 49 // Open should be called to restore a previous execution. This might be needed if 50 // nomad is restarted. 51 Open(string) error 52 53 // Wait waits till the user's command is completed. 54 Wait() error 55 56 // Returns a handle that is executor specific for use in reopening. 57 ID() (string, error) 58 59 // Shutdown should use a graceful stop mechanism so the application can 60 // perform checkpointing or cleanup, if such a mechanism is available. 61 // If such a mechanism is not available, Shutdown() should call ForceStop(). 62 Shutdown() error 63 64 // ForceStop will terminate the process without waiting for cleanup. Every 65 // implementations must provide this. 66 ForceStop() error 67 68 // Command provides access the underlying Cmd struct in case the Executor 69 // interface doesn't expose the functionality you need. 70 Command() *cmd 71 } 72 73 // Command is a mirror of exec.Command that returns a platform-specific Executor 74 func Command(name string, arg ...string) Executor { 75 executor := NewExecutor() 76 cmd := executor.Command() 77 cmd.Path = name 78 cmd.Args = append([]string{name}, arg...) 79 80 if filepath.Base(name) == name { 81 if lp, err := exec.LookPath(name); err != nil { 82 // cmd.lookPathErr = err 83 } else { 84 cmd.Path = lp 85 } 86 } 87 return executor 88 } 89 90 // OpenId is similar to executor.Command but will attempt to reopen with the 91 // passed ID. 92 func OpenId(id string) (Executor, error) { 93 executor := NewExecutor() 94 err := executor.Open(id) 95 if err != nil { 96 return nil, err 97 } 98 return executor, nil 99 } 100 101 // Cmd is an extension of exec.Cmd that incorporates functionality for 102 // re-attaching to processes, dropping priviledges, etc., based on platform- 103 // specific implementations. 104 type cmd struct { 105 exec.Cmd 106 107 // Resources is used to limit CPU and RAM used by the process, by way of 108 // cgroups or a similar mechanism. 109 Resources structs.Resources 110 111 // RunAs may be a username or Uid. The implementation will decide how to use it. 112 RunAs string 113 }