mirror of
https://github.com/kemko/nomad.git
synced 2026-01-02 16:35:44 +03:00
178 lines
4.8 KiB
Go
178 lines
4.8 KiB
Go
package structs
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"io"
|
|
"io/ioutil"
|
|
"os"
|
|
"time"
|
|
|
|
"github.com/hashicorp/nomad/client/lib/fifo"
|
|
cstructs "github.com/hashicorp/nomad/client/structs"
|
|
)
|
|
|
|
// Executor is the interface which allows a driver to launch and supervise
|
|
// a process
|
|
type Executor interface {
|
|
// Launch a user process configured by the given ExecCommand
|
|
Launch(launchCmd *ExecCommand) (*ProcessState, error)
|
|
|
|
// Wait blocks until the process exits or an error occures
|
|
Wait(ctx context.Context) (*ProcessState, error)
|
|
|
|
// Shutdown will shutdown the executor by stopping the user process,
|
|
// cleaning up and resources created by the executor. The shutdown sequence
|
|
// will first send the given signal to the process. This defaults to "SIGINT"
|
|
// if not specified. The executor will then wait for the process to exit
|
|
// before cleaning up other resources. If the executor waits longer than the
|
|
// given grace period, the process is forcefully killed.
|
|
//
|
|
// To force kill the user process, gracePeriod can be set to 0.
|
|
Shutdown(signal string, gracePeriod time.Duration) error
|
|
|
|
// UpdateResources updates any resource isolation enforcement with new
|
|
// constraints if supported.
|
|
UpdateResources(*Resources) error
|
|
|
|
// Version returns the executor API version
|
|
Version() (*ExecutorVersion, error)
|
|
|
|
// Stats fetchs process usage stats for the executor and each pid if available
|
|
Stats() (*cstructs.TaskResourceUsage, error)
|
|
|
|
// Signal sends the given signal to the user process
|
|
Signal(os.Signal) error
|
|
|
|
// Exec executes the given command and args inside the executor context
|
|
// and returns the output and exit code.
|
|
Exec(deadline time.Time, cmd string, args []string) ([]byte, int, error)
|
|
}
|
|
|
|
// Resources describes the resource isolation required
|
|
type Resources struct {
|
|
CPU int
|
|
MemoryMB int
|
|
DiskMB int
|
|
IOPS int
|
|
}
|
|
|
|
// ExecCommand holds the user command, args, and other isolation related
|
|
// settings.
|
|
type ExecCommand struct {
|
|
// Cmd is the command that the user wants to run.
|
|
Cmd string
|
|
|
|
// Args is the args of the command that the user wants to run.
|
|
Args []string
|
|
|
|
// Resources defined by the task
|
|
Resources *Resources
|
|
|
|
// StdoutPath is the path the process stdout should be written to
|
|
StdoutPath string
|
|
stdout io.WriteCloser
|
|
|
|
// StderrPath is the path the process stderr should be written to
|
|
StderrPath string
|
|
stderr io.WriteCloser
|
|
|
|
// Env is the list of KEY=val pairs of environment variables to be set
|
|
Env []string
|
|
|
|
// User is the user which the executor uses to run the command.
|
|
User string
|
|
|
|
// TaskDir is the directory path on the host where for the task
|
|
TaskDir string
|
|
|
|
// ResourceLimits determines whether resource limits are enforced by the
|
|
// executor.
|
|
ResourceLimits bool
|
|
|
|
// Cgroup marks whether we put the process in a cgroup. Setting this field
|
|
// doesn't enforce resource limits. To enforce limits, set ResourceLimits.
|
|
// Using the cgroup does allow more precise cleanup of processes.
|
|
BasicProcessCgroup bool
|
|
}
|
|
|
|
// SetWriters sets the writer for the process stdout and stderr. This should
|
|
// not be used if writing to a file path such as a fifo file. SetStdoutWriter
|
|
// is mainly used for unit testing purposes.
|
|
func (c *ExecCommand) SetWriters(out io.WriteCloser, err io.WriteCloser) {
|
|
c.stdout = out
|
|
c.stderr = err
|
|
}
|
|
|
|
// GetWriters returns the unexported io.WriteCloser for the stdout and stderr
|
|
// handles. This is mainly used for unit testing purposes.
|
|
func (c *ExecCommand) GetWriters() (stdout io.WriteCloser, stderr io.WriteCloser) {
|
|
return c.stdout, c.stderr
|
|
}
|
|
|
|
type nopCloser struct {
|
|
io.Writer
|
|
}
|
|
|
|
func (nopCloser) Close() error { return nil }
|
|
|
|
// Stdout returns a writer for the configured file descriptor
|
|
func (c *ExecCommand) Stdout() (io.WriteCloser, error) {
|
|
if c.stdout == nil {
|
|
if c.StdoutPath != "" {
|
|
f, err := fifo.Open(c.StdoutPath)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to create stdout: %v", err)
|
|
}
|
|
c.stdout = f
|
|
} else {
|
|
c.stdout = nopCloser{ioutil.Discard}
|
|
}
|
|
}
|
|
return c.stdout, nil
|
|
}
|
|
|
|
// Stderr returns a writer for the configured file descriptor
|
|
func (c *ExecCommand) Stderr() (io.WriteCloser, error) {
|
|
if c.stderr == nil {
|
|
if c.StderrPath != "" {
|
|
f, err := fifo.Open(c.StderrPath)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to create stderr: %v", err)
|
|
}
|
|
c.stderr = f
|
|
} else {
|
|
c.stderr = nopCloser{ioutil.Discard}
|
|
}
|
|
}
|
|
return c.stderr, nil
|
|
}
|
|
|
|
func (c *ExecCommand) Close() {
|
|
stdout, err := c.Stdout()
|
|
if err == nil {
|
|
stdout.Close()
|
|
}
|
|
stderr, err := c.Stderr()
|
|
if err == nil {
|
|
stderr.Close()
|
|
}
|
|
}
|
|
|
|
// ProcessState holds information about the state of a user process.
|
|
type ProcessState struct {
|
|
Pid int
|
|
ExitCode int
|
|
Signal int
|
|
Time time.Time
|
|
}
|
|
|
|
// ExecutorVersion is the version of the executor
|
|
type ExecutorVersion struct {
|
|
Version string
|
|
}
|
|
|
|
func (v *ExecutorVersion) GoString() string {
|
|
return v.Version
|
|
}
|