provision

package
v0.2.1-rc2 Latest Latest
Warning

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

Go to latest
Published: Feb 19, 2020 License: Apache-2.0 Imports: 34 Imported by: 3

Documentation

Overview

Package provision is a daemon that pulls on reservation source, and then tries to apply these reservations locally. Note that, provision module doesn't expose any interface on zbus. since it should not be driven by users, instead all reservation should be pushed by the reservation source.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrPollEOS can be returned by a reservation poll to
	// notify the caller that it has reached end of stream
	// and next calls will not return any more data.
	ErrPollEOS = fmt.Errorf("end of stream")
)

Functions

func GetZBus

func GetZBus(ctx context.Context) zbus.Client

GetZBus gets a zbus client from context

func Verify

func Verify(r *Reservation) error

Verify verifies the signature of the reservation

func WithOwnerCache

func WithOwnerCache(ctx context.Context, cache OwnerCache) context.Context

WithOwnerCache adds the owner cache to context

func WithZBus

func WithZBus(ctx context.Context, client zbus.Client) context.Context

WithZBus adds a zbus client middleware to context

func WithZDBMapping

func WithZDBMapping(ctx context.Context, mapping ZDBMapping) context.Context

WithZDBMapping set ZDBMapping into the context

Types

type Container

type Container struct {
	// URL of the flist
	FList string `json:"flist"`
	// URL of the storage backend for the flist
	FlistStorage string `json:"flist_storage"`
	// Env env variables to container in format
	Env map[string]string `json:"env"`
	// Env env variables to container that the value is encrypted
	// with the node public key. the env will be exposed to plain
	// text to the entrypoint.
	SecretEnv map[string]string `json:"secret_env"`
	// Entrypoint the process to start inside the container
	Entrypoint string `json:"entrypoint"`
	// Interactivity enable Core X as PID 1 on the container
	Interactive bool `json:"interactive"`
	// Mounts extra mounts in the container
	Mounts []Mount `json:"mounts"`
	// Network network info for container
	Network Network `json:"network"`
	// ContainerCapacity is the amount of resource to allocate to the container
	Capacity ContainerCapacity `json:"capacity"`
}

Container creation info

type ContainerCapacity

type ContainerCapacity struct {
	// Number of CPU
	CPU uint `json:"cpu"`
	// Memory in MiB
	Memory uint64 `json:"memory"`
}

ContainerCapacity is the amount of resource to allocate to the container

type ContainerResult

type ContainerResult struct {
	ID   string `json:"id"`
	IPv6 string `json:"ipv6"`
	IPv4 string `json:"ipv4"`
}

ContainerResult is the information return to the BCDB after deploying a container

type Counter

type Counter interface {
	// Increment counter atomically by one
	Increment() int64
	// Decrement counter atomically by one
	Decrement() int64
	// Current returns the current value
	Current() int64
}

Counter interface

type Debug

type Debug struct {
	Host    string `json:"host"`
	Port    int    `json:"port"`
	Channel string `json:"channel"`
}

Debug provision schema

type DiskType

type DiskType string

DiskType defines disk type

const (
	// HDDDiskType for hdd disks
	HDDDiskType DiskType = "HDD"
	// SSDDiskType for ssd disks
	SSDDiskType DiskType = "SSD"
)

type Engine

type Engine interface {
	// Start the engine
	Run(ctx context.Context) error
	// Counters stream for number of provisioned resources
	Counters(ctx context.Context) <-chan pkg.ProvisionCounters
}

Engine interface

func New

New creates a new engine. Once started, the engine will continue processing all reservations from the reservation source and try to apply them. the default implementation is a single threaded worker. so it process one reservation at a time. On error, the engine will log the error. and continue to next reservation.

type FSStore

type FSStore struct {
	sync.RWMutex
	// contains filtered or unexported fields
}

FSStore is a in reservation store using the filesystem as backend

func NewFSStore

func NewFSStore(root string) (*FSStore, error)

NewFSStore creates a in memory reservation store

func (*FSStore) Add

func (s *FSStore) Add(r *Reservation) error

Add a reservation to the store

func (*FSStore) Close

func (s *FSStore) Close() error

Close makes sure the backend of the store is closed properly

func (*FSStore) Counters

func (s *FSStore) Counters() pkg.ProvisionCounters

Counters returns stats about the cashed reservations

func (*FSStore) Exists

func (s *FSStore) Exists(id string) (bool, error)

Exists checks if the reservation ID is in the store

func (*FSStore) Get

func (s *FSStore) Get(id string) (*Reservation, error)

Get retrieves a specific reservation using its ID if returns a non nil error if the reservation is not present in the store

func (*FSStore) GetExpired

func (s *FSStore) GetExpired() ([]*Reservation, error)

GetExpired returns all id the the reservations that are expired at the time of the function call

func (*FSStore) Remove

func (s *FSStore) Remove(id string) error

Remove a reservation from the store

type Feedbacker

type Feedbacker interface {
	Feedback(id string, r *Result) error
	Deleted(id string) error
}

Feedbacker defines the method that needs to be implemented to send the provision result to BCDB

type HTTPStore

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

HTTPStore is a reservation store over HTTP

func NewHTTPStore

func NewHTTPStore(url string) *HTTPStore

NewHTTPStore creates an a client to a TNoDB reachable over HTTP

func (*HTTPStore) Delete

func (s *HTTPStore) Delete(id string) error

Delete marks a reservation as to be deleted

func (*HTTPStore) Deleted

func (s *HTTPStore) Deleted(id string) error

Deleted marks a reservation as deleted

func (*HTTPStore) Feedback

func (s *HTTPStore) Feedback(id string, r *Result) error

Feedback sends back the result of a provisioning to BCDB

func (*HTTPStore) Get

func (s *HTTPStore) Get(id string) (*Reservation, error)

Get retrieves a single reservation using its ID

func (*HTTPStore) Poll

func (s *HTTPStore) Poll(nodeID pkg.Identifier, from uint64) ([]*Reservation, error)

Poll retrieves reservations from BCDB. from acts like a cursor, first call should use 0 to retrieve everything. Next calls should use the last+1 ID of the previous poll. Note that from is a reservation ID not a workload ID. so user the Reservation.SplitID() method to get the reservation part.

func (*HTTPStore) Reserve

func (s *HTTPStore) Reserve(r *Reservation) (string, error)

Reserve adds a reservation to the BCDB

type Kubernetes

type Kubernetes struct {
	// Size of the vm, this defines the amount of vCpu, memory, and the disk size
	// Docs: docs/kubernetes/sizes.md
	Size uint8 `json:"size"`

	// NetworkID of the network namepsace in which to run the VM. The network
	// must be provisioned previously.
	NetworkID pkg.NetID `json:"network_id"`
	// IP of the VM. The IP must be part of the subnet available in the network
	// resource defined by the networkID on this node
	IP net.IP `json:"ip"`

	// ClusterSecret is the hex encoded encrypted cluster secret.
	ClusterSecret string `json:"cluster_secret"`
	// MasterIPs define the URL's for the kubernetes master nodes. If this
	// list is empty, this node is considered to be a master node.
	MasterIPs []net.IP `json:"master_ips"`
	// SSHKeys is a list of ssh keys to add to the VM. Keys can be either
	// a full ssh key, or in the form of `github:${username}`. In case of
	// the later, the VM will retrieve the github keys for this username
	// when it boots.
	SSHKeys []string `json:"ssh_keys"`

	PlainClusterSecret string `json:"-"`
}

Kubernetes reservation data

type KubernetesResult

type KubernetesResult struct {
	ID string `json:"id"`
	IP string `json:"ip"`
}

KubernetesResult result returned by k3s reservation

type Mount

type Mount struct {
	VolumeID   string `json:"volume_id"`
	Mountpoint string `json:"mountpoint"`
}

Mount defines a container volume mounted inside the container

type Network

type Network struct {
	NetworkID pkg.NetID `json:"network_id"`
	// IP to give to the container
	IPs       []net.IP `json:"ips"`
	PublicIP6 bool     `json:"public_ip6"`
}

Network struct

type OwnerCache

type OwnerCache interface {
	OwnerOf(reservationID string) (string, error)
}

OwnerCache interface

func GetOwnerCache

func GetOwnerCache(ctx context.Context) OwnerCache

GetOwnerCache gets the owner cache from context

func NewCache

func NewCache(local, remote ReservationGetter) OwnerCache

NewCache returns a new initialized reservation cache

type Reservation

type Reservation struct {
	// ID of the reservation
	ID string `json:"id"`
	// NodeID of the node where to deploy this reservation
	NodeID string `json:"node_id"`
	// Identification of the user requesting the reservation
	User string `json:"user_id"`
	// Type of the reservation (container, zdb, vm, etc...)
	Type ReservationType `json:"type"`
	// Data is the reservation type arguments.
	Data json.RawMessage `json:"data,omitempty"`
	// Date of creation
	Created time.Time `json:"created"`
	// Duration of the reservation
	Duration time.Duration `json:"duration"`
	// Signature is the signature to the reservation
	// it contains all the field of this struct except the signature itself and the Result field
	Signature []byte `json:"signature,omitempty"`

	// This flag is set to true when a reservation needs to be deleted
	// before its expiration time
	ToDelete bool `json:"to_delete"`

	// Tag object is mainly used for debugging.
	Tag Tag `json:"-"`
}

Reservation struct

func (*Reservation) Expired

func (r *Reservation) Expired() bool

Expired returns a boolean depending if the reservation has expire or not at the time of the function call

func (*Reservation) Sign

func (r *Reservation) Sign(privateKey ed25519.PrivateKey) error

Sign creates a signature from all the field of the reservation object and fill the Signature field

func (*Reservation) SplitID

func (r *Reservation) SplitID() (reservation uint64, workload uint64, err error)

SplitID gets the reservation part and the workload part from a full reservation ID

type ReservationCache

type ReservationCache interface {
	Add(r *Reservation) error
	Get(id string) (*Reservation, error)
	Remove(id string) error
	Exists(id string) (bool, error)
	Counters() pkg.ProvisionCounters
}

ReservationCache define the interface to store some reservations

type ReservationExpirer

type ReservationExpirer interface {
	// GetExpired returns all id the the reservations that are expired
	// at the time of the function call
	GetExpired() ([]*Reservation, error)
}

ReservationExpirer define the interface to implement to get all the reservation that have expired

type ReservationGetter added in v0.4.9

type ReservationGetter interface {
	Get(id string) (*Reservation, error)
}

ReservationGetter define the interface how to get a reservation from its ID

type ReservationPoller

type ReservationPoller interface {
	// Poll ask the store to send us reservation for a specific node ID
	// from is the used as a filter to which reservation to use as
	// reservation.ID >= from. So a client to the Poll method should make
	// sure to call it with the last (MAX) reservation ID he receieved.
	Poll(nodeID pkg.Identifier, from uint64) ([]*Reservation, error)
}

ReservationPoller define the interface to implement to poll the BCDB for new reservation

type ReservationSource

type ReservationSource interface {
	Reservations(ctx context.Context) <-chan *Reservation
}

ReservationSource interface. The source defines how the node will get reservation requests then reservations are applied to the node to deploy a resource of the given Reservation.Type

func CombinedSource

func CombinedSource(sources ...ReservationSource) ReservationSource

CombinedSource merge different ReservationSources into one ReservationSource

func NewDecommissionSource

func NewDecommissionSource(store ReservationExpirer) ReservationSource

NewDecommissionSource creates a ReservationSource that sends reservation that have expired into it's output channel

func PollSource

func PollSource(store ReservationPoller, nodeID pkg.Identifier) ReservationSource

PollSource does a long poll on address to get new and to be deleted reservations. the server should only return unique reservations stall the connection as long as possible if no new reservations are available.

type ReservationType

type ReservationType string

ReservationType type

const (
	// ContainerReservation type
	ContainerReservation ReservationType = "container"
	// VolumeReservation type
	VolumeReservation ReservationType = "volume"
	// NetworkReservation type
	NetworkReservation ReservationType = "network"
	// ZDBReservation type
	ZDBReservation ReservationType = "zdb"
	// DebugReservation type
	DebugReservation ReservationType = "debug"
	// KubernetesReservation type
	KubernetesReservation ReservationType = "kubernetes"
)

type Result

type Result struct {
	Type ReservationType `json:"type"`
	//Reservation ID
	ID string `json:"id"`
	// Time when the result is sent
	Created time.Time `json:"created"`
	// State of the deployment (ok,error)
	State string `json:"state"`
	// if State is "error", then this field contains the error
	// otherwise it's nil
	Error string `json:"error"`
	// Data is the information generated by the provisioning of the workload
	// its type depend on the reservation type
	Data json.RawMessage `json:"data"`
	// Signature is the signature to the result
	// it contains all the field of this struct except the signature itself
	Signature []byte `json:"signature"`
}

Result is the struct filled by the node after a reservation object has been processed

func (*Result) Bytes

func (r *Result) Bytes() ([]byte, error)

Bytes returns a slice of bytes container all the information used to sign the Result object

type Tag

type Tag map[string]string

Tag is custom tag to mark certain reservations

func AppendTag

func AppendTag(t, n Tag) Tag

AppendTag appends tags

func (Tag) String

func (t Tag) String() string

type Volume

type Volume struct {
	// Size of the volume in GiB
	Size uint64 `json:"size"`
	// Type of disk underneath the volume
	Type DiskType `json:"type"`
}

Volume defines a mount point

type VolumeResult

type VolumeResult struct {
	ID string `json:"volume_id"`
}

VolumeResult is the information return to the BCDB after deploying a volume

type ZDB

type ZDB struct {
	Size     uint64         `json:"size"`
	Mode     pkg.ZDBMode    `json:"mode"`
	Password string         `json:"password"`
	DiskType pkg.DeviceType `json:"disk_type"`
	Public   bool           `json:"public"`

	PlainPassword string `json:"-"`
}

ZDB namespace creation info

type ZDBMapping

type ZDBMapping interface {

	// Get returns the container ID where namespace lives
	// if the namespace is not found an empty string and false is returned
	Get(namespace string) (string, bool)

	// Set saves the mapping between the namespace and a container ID
	Set(namespace, container string)
}

ZDBMapping interface

func GetZDBMapping

func GetZDBMapping(ctx context.Context) ZDBMapping

GetZDBMapping gets the zdb mapping from the context

type ZDBResult

type ZDBResult struct {
	Namespace string
	IP        string
	Port      uint
}

ZDBResult is the information return to the BCDB after deploying a 0-db namespace

Jump to

Keyboard shortcuts

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