agent

package
v0.2.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 26, 2018 License: GPL-3.0 Imports: 20 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// SvcName is the name of the service that will be installed
	SvcName = "laforge-agent"

	// SvcDisplayName is the proper name of the installed agent
	SvcDisplayName = `Laforge Provisioning Agent`

	// SvcDescription is the description of the agent
	SvcDescription = `Provides a programmatic interface for configuration of this host.`
)

Variables

View Source
var (
	// Agent is the primary singleton engine object
	Agent *Engine

	// AsyncWorker is the primary singleton object that does work
	AsyncWorker *Worker

	// Logger is the singleton logger of the Agent
	Logger *logrus.Logger

	// LogFile is the open file handle for the singleton logger
	LogFile *os.File
)
View Source
var (
	// AgentHomeDir is the location where the agent will reside
	AgentHomeDir = `/opt/laforge-agent`

	// ExePath is the location of the laforge agent
	ExePath = `/usr/local/bin/laforge-agent`
)
View Source
var (
	// ErrAwaitingReboot is thrown when the state is awaiting a reboot
	ErrAwaitingReboot = errors.New("awaiting reboot for step")

	// ErrInProgress is triggered when a step is already in the process of executing
	ErrInProgress = errors.New("step currently in progress")

	// ErrStepFailure is thrown when a step has errored out
	ErrStepFailure = errors.New("current step has errored")
)
View Source
var (
	// ErrWorkerBusy is thrown when the work is already executing
	ErrWorkerBusy = errors.New("agent worker busy")

	// ErrLoadTimedOut is thrown when an attempt to Load(statefile) is not responsive after a few seconds
	ErrLoadTimedOut = errors.New("agent worker timed out loading state")

	// ErrStaleRevision is thrown when the config attempting to be loaded has an out of date revision
	ErrStaleRevision = errors.New("requested revision is out of date")

	// ErrRevisionMismatch is thrown when the config attempting to be loaded has a future revision
	ErrRevisionMismatch = errors.New("requested revision is ahead of currently running")

	// ErrDuplicateRevision is thrown when a config of the same revision is attempted to be loaded
	ErrDuplicateRevision = errors.New("duplicate revision already loaded")
)
View Source
var ServerPort = 9971

ServerPort is the port the agent API server runs on

Functions

func AssetDir

func AssetDir() string

AssetDir returns the absolute path to the asset directory

func AssetPath

func AssetPath(name string) string

AssetPath returns the absolute path to an asset of the provided name

func ConfigFile

func ConfigFile() string

ConfigFile returns the absolute path to the config file

func CreateAgentDir

func CreateAgentDir() error

CreateAgentDir attempts to create the agent directory

func GetService

func GetService() (service.Service, error)

GetService returns the service object

func GetServiceConfig

func GetServiceConfig() *service.Config

GetServiceConfig returns the installable service config

func InitFile

func InitFile() string

InitFile returns the absolute path to the initialized file

func Initialized

func Initialized() bool

Initialized describes whether the local machine has been initialized

func LogFilePath

func LogFilePath() string

LogFilePath returns the absolute path of the agent's log

func StartLogger

func StartLogger() error

StartLogger starts the file logger

func StepLogDir

func StepLogDir() string

StepLogDir is where step stdout/stderr is logged to

func TouchInitFile

func TouchInitFile() error

TouchInitFile touches the systems initialized file

Types

type Engine

type Engine struct {
	Config  *State
	Server  *gin.Engine
	Service service.Service
}

Engine is the primary engine type within the provisioning agent

func NewEngine

func NewEngine() *Engine

NewEngine creates a bare engine

func (*Engine) GetStatus

func (e *Engine) GetStatus() *Status

GetStatus returns the current status of the engine

func (*Engine) LoadConfig

func (e *Engine) LoadConfig() error

LoadConfig loads the base configuration of the host

func (*Engine) ReqGetAwaitingSteps

func (e *Engine) ReqGetAwaitingSteps(c *gin.Context)

ReqGetAwaitingSteps returns the list of steps awaiting run

func (*Engine) ReqGetCompletedSteps

func (e *Engine) ReqGetCompletedSteps(c *gin.Context)

ReqGetCompletedSteps returns the list of completed steps

func (*Engine) ReqGetCurrentStep

func (e *Engine) ReqGetCurrentStep(c *gin.Context)

ReqGetCurrentStep returns the currently working step (if there is one)

func (*Engine) ReqGetSpecificStep

func (e *Engine) ReqGetSpecificStep(c *gin.Context)

ReqGetSpecificStep returns details about a specified step

func (*Engine) ReqGetState

func (e *Engine) ReqGetState(c *gin.Context)

ReqGetState returns a full dump of the agent's state

func (*Engine) ReqGetStatus

func (e *Engine) ReqGetStatus(c *gin.Context)

ReqGetStatus returns the current agent status

func (*Engine) ReqGetStepLogAll

func (e *Engine) ReqGetStepLogAll(c *gin.Context)

ReqGetStepLogAll returns the step's logs, combined into one streaming chunk

func (*Engine) ReqGetStepLogStderr

func (e *Engine) ReqGetStepLogStderr(c *gin.Context)

ReqGetStepLogStderr returns the step's stderr, streaming if it's in progress

func (*Engine) ReqGetStepLogStdout

func (e *Engine) ReqGetStepLogStdout(c *gin.Context)

ReqGetStepLogStdout returns the step's stdout, streaming if it's in progress

func (*Engine) ReqGetSteps

func (e *Engine) ReqGetSteps(c *gin.Context)

ReqGetSteps returns a full dump of the agent's steps

func (*Engine) ReqInitialize

func (e *Engine) ReqInitialize(c *gin.Context)

ReqInitialize is used to initialize the configuration state

func (*Engine) ReqPushProvision

func (e *Engine) ReqPushProvision(c *gin.Context)

ReqPushProvision is what kicks off the provisioning process

func (*Engine) ReqSelfDestruct

func (e *Engine) ReqSelfDestruct(c *gin.Context)

ReqSelfDestruct removes all sensitive data and deletes the server

func (*Engine) Serve

func (e *Engine) Serve()

Serve is the long running loop for the Engine's API

func (*Engine) Start

func (e *Engine) Start(s service.Service) error

Start implements the Interface type for service functionality

func (*Engine) Stop

func (e *Engine) Stop(s service.Service) error

Stop implements the Interface type for service functionality

type LoadRequest

type LoadRequest struct {
	Source string
	Ack    chan bool
	Err    chan error
}

LoadRequest is a stub type that lets the Engine communicate config Load's to the worker without breaking async execution

type State

type State struct {
	sync.RWMutex
	Source          string                `json:"-"`
	Host            *core.Host            `json:"host,omitempty"`
	Network         *core.Network         `json:"network,omitempty"`
	Environment     *core.Environment     `json:"environment,omitempty"`
	Competition     *core.Competition     `json:"competition,omitempty"`
	Team            *core.Team            `json:"team,omitempty"`
	ProvisionedHost *core.ProvisionedHost `json:"provisioned_host,omitempty"`
	RenderedAt      time.Time             `json:"rendered_at,omitempty"`
	InitializedAt   time.Time             `json:"initialized_at,omitempty"`
	CompletedAt     time.Time             `json:"completed_at,omitempty"`
	CurrentState    string                `json:"current_state,omitempty"`
	Steps           []*Step               `json:"steps,omitempty"`
	Pending         map[int]*Step         `json:"pending_steps"`
	Completed       map[int]*Step         `json:"completed_steps"`
	CurrentStep     *Step                 `json:"current_step,omitempty"`
	Revision        int64                 `json:"revision,omitempty"`
	Errored         bool                  `json:"errored,omitempty"`
	ErrorMessage    string                `json:"error_message,omitempty"`
}

State is the global state of this server and all required information

func LoadStateFile

func LoadStateFile(location string) (*State, error)

LoadStateFile parses a JSON state file into a state object

func (*State) DoNextStep

func (s *State) DoNextStep() error

DoNextStep attempts to execute the subsequent step in the execution chain

func (*State) Finalize

func (s *State) Finalize() error

Finalize closes out all states in the provisioning config and saves it to disk

func (*State) Normalize

func (s *State) Normalize() error

Normalize attempts to normalize the known state and prepare it for any further step cycles

func (*State) ResolveNextStep

func (s *State) ResolveNextStep() (*Step, error)

ResolveNextStep attempts to locate the next step in the provisioning chain

func (*State) WorkExists

func (s *State) WorkExists() bool

WorkExists returns whether any further steps can be executed

func (*State) WriteStateFile

func (s *State) WriteStateFile(location string) error

WriteStateFile writes a JSON state file to disk

type Status

type Status struct {
	Code           StatusCode    `json:"code,omitempty"`
	StartedAt      time.Time     `json:"started_at,omitempty"`
	ElapsedTime    time.Duration `json:"elapsed_time,omitempty"`
	CompletedAt    time.Time     `json:"completed_at,omitempty"`
	Uptime         int64         `json:"uptime,omitempty"`
	CurrentStep    *Step         `json:"current_step,omitempty"`
	TotalSteps     int           `json:"total_steps,omitempty"`
	CompletedSteps int           `json:"completed_steps,omitempty"`
}

Status is a response object to API calls

func NewEmptyStatus

func NewEmptyStatus() *Status

NewEmptyStatus returns a status object empty except for uptime

type StatusCode

type StatusCode string

StatusCode is returned as part of an API response

const (
	// StatusBootingUp is returned when the host is online, but not ready to receive API calls
	StatusBootingUp StatusCode = "BOOTING_UP"

	// StatusIdle is returned when the host is online, and the Engine's API is currently idle
	StatusIdle StatusCode = "IDLE"

	// StatusAwaitingReboot is returned when the host has been scheduled for a reboot, but it has not happened yet
	StatusAwaitingReboot StatusCode = "AWAITING_REBOOT"

	// StatusRunningStep is returned when a step is currently being run by the machine
	StatusRunningStep StatusCode = "RUNNING_STEP"

	// StatusRefreshing is returned in between steps being run to modify the state on disk
	StatusRefreshing StatusCode = "REFRESHING"

	// StatusDestroying is returned when the agent is in the process of destroying sensitive information
	StatusDestroying StatusCode = "DESTROYING"
)

type Step

type Step struct {
	ID          int                    `json:"id,omitempty"`
	Revision    string                 `json:"revision,omitempty"`
	Name        string                 `json:"name,omitempty"`
	Description string                 `json:"description,omitempty"`
	StepType    string                 `json:"step_type,omitempty"`
	Source      string                 `json:"source,omitempty"`
	Destination string                 `json:"destination,omitempty"`
	Metadata    map[string]interface{} `json:"metadata,omitempty"`
	Status      string                 `json:"status,omitempty"`
	StartedAt   time.Time              `json:"started_at,omitempty"`
	EndedAt     time.Time              `json:"ended_at,omitempty"`
	StdoutFile  string                 `json:"stdout_file,omitempty"`
	StderrFile  string                 `json:"stderr_file,omitempty"`
	Stdout      *bytes.Buffer          `json:"-"`
	Stderr      *bytes.Buffer          `json:"-"`
	ExitStatus  int                    `json:"exit_status,omitempty"`
	ExitError   error                  `json:"exit_error,omitempty"`
}

Step is a unique action to be taken on the local machine

func (*Step) CanProceed

func (s *Step) CanProceed() bool

CanProceed returns whether the step is safe to proceed onto the next one

func (*Step) CopyFile

func (s *Step) CopyFile() error

CopyFile attempts to move the target file from one place to the next

func (*Step) ExecuteLinux

func (s *Step) ExecuteLinux() error

ExecuteLinux makes the script executable and runs it in Linux

func (*Step) ExecutePowershell

func (s *Step) ExecutePowershell() error

ExecutePowershell attempts to execute the script source as a powershell -File argument

func (*Step) ExecuteWindows

func (s *Step) ExecuteWindows() error

ExecuteWindows simply executes the source file

func (*Step) Perform

func (s *Step) Perform() error

Perform actually performs the step's functions

func (*Step) Prepare

func (s *Step) Prepare() error

Prepare sets some values for the Step function to be performed

func (*Step) RunCommand

func (s *Step) RunCommand(base string, args ...string) error

RunCommand is a generic executor for local commands in a way that preserves the STDERR and STDOUT by logging to a file as well as to a buffer which can be streamed.

func (*Step) StderrFilename

func (s *Step) StderrFilename() string

StderrFilename returns the templated filename for a step's stderr log

func (*Step) StdoutFilename

func (s *Step) StdoutFilename() string

StdoutFilename returns the templated filename for a step's stdout log

type Worker

type Worker struct {
	Heartbeat  int64
	Busy       bool
	Config     *State
	ConfigFile string
	Tasks      chan LoadRequest
}

Worker is the base unit that performs the step execution of the agent

func (*Worker) Available

func (w *Worker) Available() bool

Available is a helper function to check to see if the worker is currently working

func (*Worker) Do

func (w *Worker) Do()

Do is the primary loop of the worker's execution

func (*Worker) Handle

func (w *Worker) Handle(lr LoadRequest)

Handle is the primary loop for managing the execution of a Config's lifecycle

func (*Worker) Load

func (w *Worker) Load(statefile string) error

Load will create a LoadRequest and pass it into the Worker's task queue, blocking until the Worker Ack's or an error is thrown

func (*Worker) Rest

func (w *Worker) Rest()

Rest simply pauses the worker function for a period of time to cooldown and handle graceful exits by scripts

func (*Worker) Spawn

func (w *Worker) Spawn()

Spawn creates the task queue and launches the worker loop in a separate goroutine

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL