pkg

package module
v1.1.9 Latest Latest
Warning

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

Go to latest
Published: Oct 14, 2026 License: ISC Imports: 29 Imported by: 1

README

pkg

Go Reference

pkg is the Plakar package manager, extracted to its own repo for easier reuse across projects.

Concepts

There are two layers of APIs:

  • manager: the object that implements the package manager logic, constructed with New.
  • backend: the logic for how to list, add and remove package locally. One implementation, the FlatBackend is provided.

Example usage

var plugindir, cachedir string  // fill these
var token string                // for authentication

var kctx *kcontext.KContext

backend, err := pkg.NewFlatBackend(kctx, plugdir, cachedir, &pkg.FlatBackendOptions{
	PreLoadHook: pkgpreloadhook,
	LoadHook:    pkgloadhook,
	UnloadHook:  pkgunloadhook,
})
if err != nil {
	return fmt.Errorf("failed to init the package manager: %w", err)
}

manager, err := pkg.New(backend, &pkg.Options{
	DistURL:         "https://plakar.io/dist/plugins/kloset/",
	Edition:         "community",
	ApiURL:          "https://api.plakar.io/",
	BinaryNeedsAuth: true,
	UserAgent:       "myclient/v1.2.3",
	RequestHook:     pkg.WithBearer(func() (string, error) { return token, nil }),
})
if err != nil {
	return fmt.Errorf("failed to init the package manager: %w", err)
}

if err := backend.LoadAll(); err != nil {
	return fmt.Errorf("failed to load packages: %w", err)
}

Documentation

Index

Constants

View Source
const (
	ResourceClassUndefined     ResourceClass = ""
	ResourceClassUnknown       ResourceClass = "unknown"
	ResourceClassAnalytics     ResourceClass = "analytics"
	ResourceClassBlockStorage  ResourceClass = "block-storage"
	ResourceClassCompute       ResourceClass = "compute"
	ResourceClassDatabase      ResourceClass = "database"
	ResourceClassFileStorage   ResourceClass = "file-storage"
	ResourceClassHypervisor    ResourceClass = "hypervisor"
	ResourceClassIdentity      ResourceClass = "identity"
	ResourceClassMessaging     ResourceClass = "messaging"
	ResourceClassNetwork       ResourceClass = "network"
	ResourceClassObjectStorage ResourceClass = "object-storage"
	ResourceClassObservability ResourceClass = "observability"
	ResourceClassRegistry      ResourceClass = "registry"
	ResourceClassSecurity      ResourceClass = "security"
	ResourceClassService       ResourceClass = "service"

	ResourceSubClassUndefined     ResourceSubClass = ""
	ResourceSubClassUnknown       ResourceSubClass = "unknown"
	ResourceSubClassAzBlob        ResourceSubClass = "azblob"
	ResourceSubClassFTP           ResourceSubClass = "ftp"
	ResourceSubClassGCS           ResourceSubClass = "gcs"
	ResourceSubClassIMAP          ResourceSubClass = "imap"
	ResourceSubClassMongoDB       ResourceSubClass = "mongodb"
	ResourceSubClassMySQL         ResourceSubClass = "mysql"
	ResourceSubClassPVC           ResourceSubClass = "pvc"
	ResourceSubClassPostgreSQL    ResourceSubClass = "postgresql"
	ResourceSubClassProxmox       ResourceSubClass = "proxmox"
	ResourceSubClassRedis         ResourceSubClass = "redis"
	ResourceSubClassS3            ResourceSubClass = "s3"
	ResourceSubClassSecretManager ResourceSubClass = "secret-manager"
	ResourceSubClassSFTP          ResourceSubClass = "sftp"
	ResourceSubClassVMware        ResourceSubClass = "vmware"

	ConnectorTypeImporter       ConnectorType = "importer"
	ConnectorTypeExporter       ConnectorType = "exporter"
	ConnectorTypeStorage        ConnectorType = "storage"
	ConnectorTypeSecretProvider ConnectorType = "secret_provider"
	ConnectorTypeInventory      ConnectorType = "inventory"
)
View Source
const LocalOrigin = "local"

LocalOrigin is the Origin of a package installed from a filesystem path. Not a URL, so that no URL-scoped trust can match it.

View Source
const OSContainer = "oci"

OSContainer is the OperatingSystem of container-flavored packages: they carry an image pin instead of executables and run on any linux host.

View Source
const PLUGIN_API_VERSION = "v1.1.0"
View Source
const PLUGIN_BUNDLE_VERSION = "v1.0.0"

Variables

View Source
var (
	ErrInvalidOptions        = errors.New("invalid options")
	ErrAlreadyInstalled      = errors.New("already installed")
	ErrBadOSArch             = errors.New("OS or architecture don't match the current one")
	ErrAuthorizationRequired = errors.New("authorization required")
	ErrNoDistURL             = errors.New("no DistURL provided")
	ErrNoApiURL              = errors.New("no ApiURL provided")
	ErrBadEdition            = errors.New("bad edition")
	ErrRecipeMismatch        = errors.New("recipe does not match the requested package")
)
View Source
var (
	ErrBadPackageName = errors.New("invalid package name")
)
View Source
var (
	ErrManifestMismatch = errors.New("manifest does not match the package")
)
View Source
var ErrUnverified = errors.New("package signature verification failed")

Functions

func Build

func Build(*BuildOptions) error

func GetClassTree

func GetClassTree() map[ResourceClass][]ResourceSubClass

func WithBearer

func WithBearer(fn func() (string, error)) func(*http.Request) error

WithBearer adds an Authorization header with the Bearer token returned by the given callback. It's meant to be passed as Options.RequestHook. If it yields an empty token, the header will not be added.

Types

type AddOptions

type AddOptions struct {
	// The edition to consider, if given.  Falls back to
	// [Options.Edition].
	Edition string

	// The version to install, if given.  Otherwise, the latest
	// version available will be used.
	Version string

	// If exists a older version of the plugin, remove it prior
	// to install this version.
	Upgrade bool

	// If exists a newer version of the plugin, remove it prior
	// to install this version.
	Downgrade bool

	// Remove other version of the plugin, even if it's the same,
	// and install this version.
	Replace bool

	// Don't fail if other versions of the same plugin exist.
	AllowMultipleVersions bool

	// If target does not point at a .ptar file, attempt to fetch
	// the pre-packaged plugin from the repository.
	ImplicitFetch bool

	// Install the package even if the OS and Architecture don't
	// match.
	AllowOSArchMismatch bool

	// Install the container flavor when fetching from the repository: the
	// package whose OS atom is OSContainer, carrying an image pin instead
	// of executables. Local .ptar files carry it in the filename instead.
	Container bool
}

type Artifact added in v1.1.3

type Artifact struct {
	Filename  string
	Package   *Package // nil for files that are not packages, such as a recipe
	Origin    string   // registry base URL, or LocalOrigin
	Signature []byte   // the .sum.sig, or nil if it shipped without one
}

type Backend

type Backend interface {
	// List returns an iterator of plugin names,
	// e.g. s3_v1.0.0_openbsd_amd64.ptar, optionally filtered by
	// the given name, or an error.
	List(name string) iter.Seq2[*Package, error]

	// Load a plugin' ptar from the given reader. sig is the artifact's
	// signature, retained alongside it, or nil if it has none.
	Load(pkg *Package, rd io.Reader, sig []byte) error

	// Signature returns the retained signature of an installed package,
	// or nil if it was installed without one.
	Signature(*Package) ([]byte, error)

	// Unload a plugin
	Unload(*Package) error
}

type BuildOptions

type BuildOptions struct{}

type Connector

type Connector struct {
	Type      string     `json:"type"` // importer, exporter, storage
	Protocols []Protocol `json:"protocols"`
	Class     string     `json:"class"`
	SubClass  string     `json:"subclass"`
	Validator any        `json:"validator"` // json schema
}

type ConnectorType

type ConnectorType string

func (ConnectorType) IsValid

func (c ConnectorType) IsValid() bool

type CreateOptions

type CreateOptions struct{}

type DelOptions

type DelOptions struct {
	// If target is the empty string, delete all the packages
	// installed.
	All bool

	// If version is not the empty string, delete only the given
	// version.  It's incompatible with All.
	Version string
}

type FetchOptions added in v1.1.5

type FetchOptions struct {
	// The edition to consider, if given.  Falls back to
	// [Options.Edition].
	Edition string
}

type FlatBackend

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

A backend that stores integrations in a single, flat, directory.

func NewFlatBackend

func NewFlatBackend(kctx *kcontext.KContext, pkgdir, cachedir string, opts *FlatBackendOptions) (*FlatBackend, error)

func (*FlatBackend) List

func (f *FlatBackend) List(name string) iter.Seq2[*Package, error]

func (*FlatBackend) Load

func (f *FlatBackend) Load(pkg *Package, rd io.Reader, sig []byte) error

func (*FlatBackend) LoadAll

func (f *FlatBackend) LoadAll() error

func (*FlatBackend) Signature added in v1.1.3

func (f *FlatBackend) Signature(pkg *Package) ([]byte, error)

func (*FlatBackend) Unload

func (f *FlatBackend) Unload(pkg *Package) error

type FlatBackendOptions

type FlatBackendOptions struct {
	PreLoadHook func(*Manifest) error

	// InstallHook runs once per package at install time, after the manifest
	// passed validation and before the package is enabled, giving the
	// consumer a chance to fulfill external prerequisites (e.g. pull the
	// the image for a container package). An error aborts the install.
	InstallHook func(*Manifest) error

	LoadHook   func(*Manifest, *Package, string)
	UnloadHook func(*Manifest, *Package)
}

type Integration

type Integration struct {
	Edition string `json:"edition"`
	API     string `json:"api"`

	Tier          string      `json:"tier"`
	Contact       string      `json:"contact"`
	Name          string      `json:"name"`
	DisplayName   string      `json:"display_name"`
	Description   string      `json:"description"`
	Homepage      string      `json:"homepage"`
	Repository    string      `json:"repository"`
	License       string      `json:"license"`
	Tags          []string    `json:"tags"`
	Version       string      `json:"version"` // integration version
	Connectors    []Connector `json:"connectors"`
	Documentation string      `json:"documentation"` // README.md
	Icon          string      `json:"icon"`          // assets/icon.{png,svg}
	Featured      string      `json:"featured"`      // assets/featured.{png,svg}

	Id            string                  `json:"id"`
	Types         IntegrationTypes        `json:"types"`
	Stage         string                  `json:"stage"`
	Installation  IntegrationInstallation `json:"installation"`
	LatestVersion string                  `json:"latest_version"`
}

func (*Integration) HasConnectorType

func (int *Integration) HasConnectorType(ct string) bool

type IntegrationIndex

type IntegrationIndex struct {
	Version      string        `json:"version"`
	Timestamp    time.Time     `json:"timestamp"`
	Integrations []Integration `json:"integrations"`
}

type IntegrationInstallation

type IntegrationInstallation struct {
	Status    string `json:"status"`
	Version   string `json:"version,omitempty"`
	Available bool   `json:"available"`
}

type IntegrationTypes

type IntegrationTypes struct {
	Storage     bool `json:"storage"`
	Source      bool `json:"source"`
	Destination bool `json:"destination"`
	Provider    bool `json:"provider"`
}

type Manager

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

func New

func New(store Backend, opts *Options) (*Manager, error)

New creates a new package manager.

func (*Manager) Add

func (p *Manager) Add(target string, opts *AddOptions) error

Add installs a package. By default, it will fail if another version of the same plugin is already present.

func (*Manager) Create

func (p *Manager) Create(manifest *Manifest, opts *CreateOptions) error

func (*Manager) Del

func (p *Manager) Del(target string, opts *DelOptions) error

Del uninstalls all matching packages.

func (*Manager) FetchRecipe

func (p *Manager) FetchRecipe(name string, opts *FetchOptions) (*Recipe, error)

func (*Manager) List

func (p *Manager) List() iter.Seq2[*Package, error]

List lists all the installed packages.

func (*Manager) Query

func (p *Manager) Query(opts *QueryOptions) (ret []*Integration, err error)

func (*Manager) Signature added in v1.1.3

func (p *Manager) Signature(pkg *Package) ([]byte, error)

Signature returns the retained signature of an installed package, or nil if it was installed without one.

type Manifest

type Manifest struct {
	Name        string   `yaml:"name"`
	DisplayName string   `yaml:"display_name"`
	Description string   `yaml:"description"`
	Tier        string   `yaml:"tier"`
	Contact     string   `yaml:"contact"`
	Homepage    string   `yaml:"homepage"`
	License     string   `yaml:"license"`
	Tags        []string `yaml:"tags"`
	APIVersion  string   `yaml:"api_version"`

	Connectors []ManifestConnector `yaml:"connectors"`
}

func NewManifestFromFile

func NewManifestFromFile(path string) (*Manifest, error)

func (*Manifest) Parse

func (m *Manifest) Parse(rd io.Reader) error

func (*Manifest) ParseFile

func (m *Manifest) ParseFile(path string) error

func (*Manifest) Validate added in v1.1.9

func (m *Manifest) Validate() error

Validate checks the manifest's own fields; connectors are checked separately.

type ManifestConnector

type ManifestConnector struct {
	Type          ConnectorType    `yaml:"type"`
	Class         ResourceClass    `yaml:"class,omitempty"`
	SubClass      ResourceSubClass `yaml:"subclass,omitempty"`
	Validator     string           `yaml:"validator,omitempty"`
	Protocols     []string         `yaml:"protocols"`
	LocationFlags []string         `yaml:"location_flags,omitempty"`
	Executable    string           `yaml:"executable,omitempty"`
	Args          []string         `yaml:"args,omitempty"`
	ExtraFiles    []string         `yaml:"extra_files,omitempty"`

	// Containerized connectors carry an image pin instead of an executable.
	// ImageID is the sha256 of the image, filled at package creation time
	// following a docker build.
	// Image is registry reference to pull from when install pre-built packages.
	ImageID string `yaml:"image_id,omitempty"`
	Image   string `yaml:"image,omitempty"`
}

func (*ManifestConnector) Flags

func (conn *ManifestConnector) Flags() (flags location.Flags, err error)

func (*ManifestConnector) Validate added in v1.1.5

func (conn *ManifestConnector) Validate() error

type Options

type Options struct {
	DistURL string
	Edition string // community, devel, enterprise, ...
	ApiURL  string

	// IndexURL is where [Manager.Query] fetches the integrations
	// index from, overriding the default location on the API
	// server.  A mirror of the distribution tree serves it at its
	// root, next to the edition directories.
	IndexURL        string
	BinaryNeedsAuth bool
	RequestHook     RequestHook

	// User agent name for network requests on the repository at
	// DistURL.  "(os/architecture)" will be appended implicitly.
	UserAgent string

	// Verifier decides whether an artifact may be installed. When nil,
	// nothing is verified and no signature is fetched.
	Verifier Verifier
}

type Package

type Package struct {
	Name            string
	Version         string
	Architecture    string
	OperatingSystem string
}

func (*Package) Filename

func (p *Package) Filename() string

func (*Package) Validate

func (pkg *Package) Validate() error

type Protocol

type Protocol struct {
	Scheme    string `json:"scheme"`    // sftp, s3, http, ...
	Validator any    `json:"validator"` // json schema, override connector schema if defined
}

type QueryOptions

type QueryOptions struct {
	Type    string
	Tag     string
	Status  string
	Edition string

	OnlyLocal bool
}

type Recipe

type Recipe struct {
	Name       string `yaml:"name"`
	Version    string `yaml:"version"`
	Repository string `yaml:"repository"`
}

func NewRecipeFromFile

func NewRecipeFromFile(path string) (*Recipe, error)

func (*Recipe) Parse

func (recipe *Recipe) Parse(rd io.Reader) error

func (*Recipe) ParseFile

func (recipe *Recipe) ParseFile(path string) error

func (*Recipe) PkgName

func (recipe *Recipe) PkgName() string

xxx unused

func (*Recipe) Semver

func (recipe *Recipe) Semver() string

func (*Recipe) Subdir

func (recipe *Recipe) Subdir() string

func (*Recipe) Tag

func (recipe *Recipe) Tag() string

type RequestHook

type RequestHook func(*http.Request) error

type ResourceClass

type ResourceClass string

func (ResourceClass) IsValid

func (c ResourceClass) IsValid() bool

type ResourceSubClass

type ResourceSubClass string

func (ResourceSubClass) IsSubClassOf

func (c ResourceSubClass) IsSubClassOf(parent ResourceClass) bool

func (ResourceSubClass) IsValid

func (c ResourceSubClass) IsValid() bool

type Verifier added in v1.1.3

type Verifier interface {
	Verify(artifact *Artifact, rd io.Reader) error
}

A Verifier decides whether an artifact may be installed. rd is not seekable, and a non-nil error aborts the installation. This package holds no keys and no policy: the embedding application supplies them.

type VerifierFunc added in v1.1.3

type VerifierFunc func(artifact *Artifact, rd io.Reader) error

func (VerifierFunc) Verify added in v1.1.3

func (f VerifierFunc) Verify(artifact *Artifact, rd io.Reader) error

Directories

Path Synopsis
cmd
validator command

Jump to

Keyboard shortcuts

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