cmgr

package
v0.13.1 Latest Latest
Warning

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

Go to latest
Published: Apr 26, 2022 License: Apache-2.0 Imports: 37 Imported by: 0

Documentation

Index

Examples

Constants

View Source
const (
	DB_ENV             string = "CMGR_DB"
	DIR_ENV            string = "CMGR_DIR"
	ARTIFACT_DIR_ENV   string = "CMGR_ARTIFACT_DIR"
	REGISTRY_ENV       string = "CMGR_REGISTRY"
	REGISTRY_USER_ENV  string = "CMGR_REGISTRY_USER"
	REGISTRY_TOKEN_ENV string = "CMGR_REGISTRY_TOKEN"
	LOGGING_ENV        string = "CMGR_LOGGING"
	IFACE_ENV          string = "CMGR_INTERFACE"
	PORTS_ENV          string = "CMGR_PORTS"
	DISK_QUOTA_ENV     string = "CMGR_ENABLE_DISK_QUOTAS"

	DYNAMIC_INSTANCES int = -1
	LOCKED            int = -2
)

Variables

This section is empty.

Functions

func Version added in v0.8.10

func Version() string

Returns the version string associated with the build (results of `git describe --tags`) or "unknown" if it was not set at build time.

Types

type BuildId

type BuildId int64

type BuildMetadata

type BuildMetadata struct {
	Id BuildId `json:"id"`

	Flag       string            `json:"flag"`
	LookupData map[string]string `json:"lookup_data,omitempty"`

	Seed         int                 `json:"seed"`
	Format       string              `json:"format"`
	Images       []Image             `json:"images"`
	HasArtifacts bool                `json:"has_artifacts"`
	LastSolved   int64               `json:"last_solved"`
	Challenge    ChallengeId         `json:"challenge_id"`
	Instances    []*InstanceMetadata `json:"instances,omitempty"`

	Schema        string `json:"schema"`
	InstanceCount int    `json:"instance_count"`
}

type BuildSpecification added in v0.5.0

type BuildSpecification struct {
	Seeds         []int `json:"seeds"          yaml:"seeds"`
	InstanceCount int   `json:"instance_count" yaml:"instance_count"`
}

type ChallengeId

type ChallengeId string

type ChallengeMetadata

type ChallengeMetadata struct {
	Id               ChallengeId         `json:"id"`
	Name             string              `json:"name,omitempty"`
	Namespace        string              `json:"namespace"`
	ChallengeType    string              `json:"challenge_type"`
	Description      string              `json:"description,omitempty"`
	Details          string              `json:"details,omitempty"`
	Hints            []string            `json:"hints,omitempty"`
	SourceChecksum   uint32              `json:"source_checksum"`
	MetadataChecksum uint32              `json:"metadata_checksum"`
	Path             string              `json:"path"`
	Templatable      bool                `json:"templatable,omitempty"`
	PortMap          map[string]PortInfo `json:"port_map,omitempty"`
	Hosts            []HostInfo          `json:"hosts"`
	MaxUsers         int                 `json:"max_users,omitempty"`
	Category         string              `json:"category,omitempty"`
	Points           int                 `json:"points,omitempty"`
	Tags             []string            `json:"tags,omitempty"`
	Attributes       map[string]string   `json:"attributes,omitempty"`
	ChallengeOptions ChallengeOptions    `json:"challenge_options,omitempty"`

	SolveScript bool             `json:"solve_script,omitempty"`
	Builds      []*BuildMetadata `json:"builds,omitempty"`
}

type ChallengeOptions added in v0.11.2

type ChallengeOptions struct {
	NetworkOptions   `yaml:",inline"`
	ContainerOptions `yaml:",inline"`
	Overrides        map[string]ContainerOptions `json:"overrides,omitempty" yaml:"overrides"`
}

type ChallengeUpdates

type ChallengeUpdates struct {
	Added      []*ChallengeMetadata `json:"added"`
	Refreshed  []*ChallengeMetadata `json:"refreshed"`
	Updated    []*ChallengeMetadata `json:"updated"`
	Removed    []*ChallengeMetadata `json:"removed"`
	Unmodified []*ChallengeMetadata `json:"unmodified"`
	Errors     []error              `json:"errors"`
}

type ContainerOptions added in v0.11.2

type ContainerOptions struct {
	Init            bool     `json:"init,omitempty"            yaml:"init"`
	Cpus            string   `json:"cpus,omitempty"            yaml:"cpus"`
	Memory          string   `json:"memory,omitempty"          yaml:"memory"`
	Ulimits         []string `json:"ulimits,omitempty"         yaml:"ulimits"`
	PidsLimit       int64    `json:"pidslimit,omitempty"       yaml:"pidslimit"`
	ReadonlyRootfs  bool     `json:"readonlyrootfs,omitempty"  yaml:"readonlyrootfs"`
	DroppedCaps     []string `json:"droppedcaps,omitempty"     yaml:"droppedcaps"`
	NoNewPrivileges bool     `json:"nonewprivileges,omitempty" yaml:"nonewprivileges"`
	DiskQuota       string   `json:"diskquota,omitempty"       yaml:"diskquota"`
	CgroupParent    string   `json:"cgroupparent,omitempty"    yaml:"cgroupparent"`
}

type HostInfo added in v0.8.0

type HostInfo struct {
	Name   string `json:"name"`
	Target string `json:"target,omitempty"`
}

type Image

type Image struct {
	Id    ImageId  `json:"id"`
	Host  string   `json:"host"`
	Ports []string `json:"exposed_ports"`
	Build BuildId  `json:"build"`
}

type ImageId

type ImageId int64

type InstanceId

type InstanceId int64

type InstanceMetadata

type InstanceMetadata struct {
	Id         InstanceId     `json:"id"`
	Ports      map[string]int `json:"ports,omitempty"`
	Containers []string       `json:"containers"`
	LastSolved int64          `json:"last_solved"`
	Build      BuildId        `json:"build_id"`
}

type LogLevel

type LogLevel int
const (
	DISABLED LogLevel = iota
	ERROR
	WARN
	INFO
	DEBUG
)

type Manager

type Manager struct {
	// contains filtered or unexported fields
}

func NewManager

func NewManager(logLevel LogLevel) *Manager

Creates a new instance of the challenge manager validating the appropriate environment variables in the process. A return value of `nil` indicates a fatal error occurred during intitialization.

func (*Manager) Build

func (m *Manager) Build(challenge ChallengeId, seeds []int, flagFormat string) ([]*BuildMetadata, error)

Templates out a "challenge" and generates concrete images, flags, and lookup values for the seeds provided which is called a "build" and returns a list of identifiers that can be used to reference the build in other API functions. This function may take a significant amount of time because it will implicitly download base docker images and build the artifacts.

NOTE: if `CMGR_REGISTRY` is specified and the specified challenge and challenge hash are found in the repository, then that image will be used for the build cache. This can reduce the risk of dependency changes breaking functioning challenges, but can may also make debugging challenges harder. This feature is opt-in by setting the `CMGR_REGISTRY` environment variable.

func (*Manager) CheckInstance

func (m *Manager) CheckInstance(instance InstanceId) error

Runs the automated solver against the designated instance.

func (*Manager) CreateSchema added in v0.5.0

func (m *Manager) CreateSchema(schema *Schema) []error

Uses the schema as a definition of builds and instances that should be created/started. Prevents management of those builds and instances from other API calls unless explicitly allowed by the schema. This call is likely to be extremely time and resource intensive as it will start creating all of the requested builds immediately and not return until complete.

func (*Manager) DeleteSchema added in v0.5.0

func (m *Manager) DeleteSchema(name string) error

Tears down all instances and builds belonging to the schema.

func (*Manager) Destroy

func (m *Manager) Destroy(build BuildId) error

Destroys the assoicated "build".

func (*Manager) DetectChanges

func (m *Manager) DetectChanges(fp string) *ChallengeUpdates

Traverses the entire directory and captures all valid challenge descriptions it comes across. In general, it will continue even when it encounters errors (permission, poorly formatted JSON, etc.) in order to give the as much feedback as possible to the caller. However, it will fail fast on two challenges with the same name and namespace.

This function does not have any side-effects on the database or built/running challenge state, but changes that it detects will effect new builds. It is important to resolve any issues/errors it raises before making any other API calls for affected challenges. Failure to follow this guidance could result in inconsistencies in deployed challenges.

func (*Manager) DumpState

func (m *Manager) DumpState(challenges []ChallengeId) ([]*ChallengeMetadata, error)

func (*Manager) Freeze added in v0.10.0

func (m *Manager) Freeze(challenge ChallengeId, force bool) error

Builds the "base" stage of the challenge and push it to the Docker repository identified by the `CMGR_REGISTRY`. Any `cmgr` instances that use the same repository will then use this base image as the initial cache for building the challenge (must match both challenge hash and challenge ID). If `CMGR_REGISTRY` is unspecified, the repository has not been configured for the active Docker daemon, or an error occurs during the build step, then this function will return a descriptive error. If "force" is `false`, then `cmgr` checks the repository prior to attempting to building the "base" image and returns an error if an image already exists. If "force" is `true`, `cmgr` skips this check and unconditionally attempts to build and push a base image.

NOTE: There is no validation of whether the "base" stage is self-contained (i.e., has copies of all required libraries) so this does not guarantee necessarily future builds will work. Built-in challenge types are carefully designed to reduce the risk, but any network traffic after the "base" stage(e.g., downloading extra packages or libraries) significantly increases the likelihood that the image becomes non-functional. It is ultimately the challenge author's responsibility to take proper precautions.

func (*Manager) GetBuildMetadata

func (m *Manager) GetBuildMetadata(build BuildId) (*BuildMetadata, error)

func (*Manager) GetChallengeMetadata

func (m *Manager) GetChallengeMetadata(challenge ChallengeId) (*ChallengeMetadata, error)

func (*Manager) GetDockerfile added in v0.12.0

func (m *Manager) GetDockerfile(challengeType string) []byte

Returns a byte array with the contents of the Dockerfile associated with `challengeType` (if it exists). If the challenge type does not exist, then an empty array is returned.

func (*Manager) GetInstanceMetadata

func (m *Manager) GetInstanceMetadata(instance InstanceId) (*InstanceMetadata, error)

func (*Manager) GetSchemaState added in v0.5.0

func (m *Manager) GetSchemaState(name string) ([]*ChallengeMetadata, error)

Returns the fully-nested metadata for the schema from challenges to the associated builds which belong to the schema through to the instances currently running (to include dynamic instances).

func (*Manager) ListChallenges

func (m *Manager) ListChallenges() []*ChallengeMetadata

Obtains a list of challenges with minimal version information filled into the metadata object.

Example

Iterates over all of the discovered challenges

mgr := NewManager(WARN)

for _, c := range mgr.ListChallenges() {
	fmt.Printf("%s (%s)", c.Id, c.Name)
}
Output:

func (*Manager) ListSchemas added in v0.5.0

func (m *Manager) ListSchemas() ([]string, error)

Lists all schemas as currently defined in the database.

func (*Manager) SearchChallenges added in v0.4.1

func (m *Manager) SearchChallenges(tags []string) []*ChallengeMetadata

Obtains a list of challenges which match on all of the given tags. If no tags are passed, then it returns the same results as `ListChallenges`. Wildcards are allowed as either '*' or '%' and the search is ASCII case insensitive.

func (*Manager) Start

func (m *Manager) Start(build BuildId) (InstanceId, error)

Creates a running "instance" of the given build and returns its identifier on success otherwise an error.

func (*Manager) Stop

func (m *Manager) Stop(instance InstanceId) error

Stops the running "instance".

func (*Manager) Update

func (m *Manager) Update(fp string) *ChallengeUpdates

This will update the global system state based off the changes that are detected by a call to `DetectChanges`. Specifically, in addition to updating challenge metadata (new and existing) it will rebuild and, if successful restart, existing challenges and then remove the metadata for challenges that can no longer be found. Challenges that have not been modified should not be affected.

In the presence of errors, this function will do addition and updates as best it can in order to preserve a consistent system state. However, if a build fails, it will keep the existing instance running and rollback the challenge metadata. Additionally, in the presence of errors it will not perform any removals of challenge metadata (removing a built challenge is considered an error).

func (*Manager) UpdateSchema added in v0.5.0

func (m *Manager) UpdateSchema(schema *Schema) []error

Updates the definition of the schema internally and then converges to the new definition. Certain updates are more expensive than others. In particular, updating the flag format will cause a complete rebuild of the state.

type NetworkOptions added in v0.11.2

type NetworkOptions struct{}

type PortInfo added in v0.8.0

type PortInfo struct {
	Host string `json:"host"`
	Port int    `json:"port"`
}

type Schema added in v0.5.0

type Schema struct {
	Name       string                             `json:"name"        yaml:"name"`
	FlagFormat string                             `json:"flag_format" yaml:"flag_format"`
	Challenges map[ChallengeId]BuildSpecification `json:"challenges"  yaml:"challenges"`
}

type UnknownIdentifierError added in v0.5.1

type UnknownIdentifierError struct {
	Type string
	Name string
}

func (*UnknownIdentifierError) Error added in v0.5.1

func (e *UnknownIdentifierError) Error() string

Notes

Bugs

  • Need to actually implement more validation such as verifying that published ports are referenced and that there are no clearly invalid format strings in the details and hints.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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