update

package
v0.0.0-...-890248b Latest Latest
Warning

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

Go to latest
Published: May 21, 2026 License: AGPL-3.0 Imports: 21 Imported by: 0

Documentation

Index

Constants

View Source
const (
	RegistryDockerHub = "docker.io"
	RegistryGHCR      = "ghcr.io"
	RegistryGCR       = "gcr.io"
	RegistryQuay      = "quay.io"
	RegistryECR       = "amazonaws.com"
	RegistryACR       = "azurecr.io"
)

Common registries

Variables

This section is empty.

Functions

func CompareSemver

func CompareSemver(a, b string) int

CompareSemver compares two semver strings Returns: -1 if a < b, 0 if a == b, 1 if a > b

func ExtractDigestFromRepoDigests

func ExtractDigestFromRepoDigests(repoDigests []string, image string) string

ExtractDigestFromRepoDigests extracts digest from Docker's RepoDigests

func ExtractSourceRepo

func ExtractSourceRepo(labels map[string]string) string

ExtractSourceRepo attempts to extract the source repository URL from image labels

func FilterUpdates

func FilterUpdates(updates []models.AvailableUpdate, includePrerelease bool) []models.AvailableUpdate

FilterUpdates filters available updates based on criteria

func FormatChangelogEntry

func FormatChangelogEntry(entry *ChangelogEntry) string

FormatChangelogEntry formats a changelog entry as markdown

func GroupUpdatesByHost

func GroupUpdatesByHost(updates []models.AvailableUpdate, getHostID func(containerID string) uuid.UUID) map[uuid.UUID][]models.AvailableUpdate

GroupUpdatesByHost groups updates by host ID

func IsPrerelease

func IsPrerelease(tag string) bool

IsPrerelease checks if a tag appears to be a prerelease version

func IsSemver

func IsSemver(tag string) bool

IsSemver checks if a tag follows semantic versioning

func ParseImageRef

func ParseImageRef(image string) (*models.ImageRef, error)

ParseImageRef parses a Docker image reference into its components

func ShouldSkipImage

func ShouldSkipImage(image string, skipPatterns []string) bool

ShouldSkipImage determines if an image should be skipped during update checks

Types

type AvailableUpdate

type AvailableUpdate struct {
	ContainerID    string     `json:"container_id"`
	ContainerName  string     `json:"container_name"`
	Image          string     `json:"image"`
	CurrentVersion string     `json:"current_version"`
	CurrentDigest  string     `json:"current_digest,omitempty"`
	LatestVersion  string     `json:"latest_version"`
	LatestDigest   string     `json:"latest_digest,omitempty"`
	IsPrerelease   bool       `json:"is_prerelease"`
	HasChangelog   bool       `json:"has_changelog"`
	Changelog      *Changelog `json:"changelog,omitempty"`
	CheckedAt      time.Time  `json:"checked_at"`
}

AvailableUpdate represents an available update for a container

func (*AvailableUpdate) NeedsUpdate

func (a *AvailableUpdate) NeedsUpdate() bool

NeedsUpdate returns true if an update is available

type BackupCreateOptions

type BackupCreateOptions struct {
	HostID      uuid.UUID
	ContainerID string
	Trigger     string
	CreatedBy   *uuid.UUID
}

BackupCreateOptions for creating backups

type BackupRestoreOptions

type BackupRestoreOptions struct {
	BackupID    uuid.UUID
	ContainerID string
}

BackupRestoreOptions for restoring backups

type BackupRestoreResult

type BackupRestoreResult struct {
	Success bool
}

BackupRestoreResult from restoring a backup

type BackupResult

type BackupResult struct {
	BackupID uuid.UUID
	Path     string
	Size     int64
}

BackupResult from creating a backup

type BackupService

type BackupService interface {
	Create(ctx context.Context, opts BackupCreateOptions) (*BackupResult, error)
	Restore(ctx context.Context, opts BackupRestoreOptions) (*BackupRestoreResult, error)
}

BackupService interface for backup operations (from Dept H)

type BatchUpdateInput

type BatchUpdateInput struct {
	ContainerIDs    []string      `json:"container_ids" validate:"required,min=1"`
	BackupVolumes   bool          `json:"backup_volumes"`
	SecurityScan    bool          `json:"security_scan"`
	HealthCheckWait time.Duration `json:"health_check_wait,omitempty"`
	StopOnFailure   bool          `json:"stop_on_failure"`
}

BatchUpdateInput represents input for batch updating multiple containers

type BatchUpdateResult

type BatchUpdateResult struct {
	Total     int            `json:"total"`
	Succeeded int            `json:"succeeded"`
	Failed    int            `json:"failed"`
	Skipped   int            `json:"skipped"`
	Results   []UpdateResult `json:"results"`
	Duration  time.Duration  `json:"duration"`
}

BatchUpdateResult represents the result of a batch update

type Changelog

type Changelog struct {
	Version      string     `json:"version"`
	Title        string     `json:"title,omitempty"`
	Body         string     `json:"body"`
	URL          string     `json:"url,omitempty"`
	PublishedAt  *time.Time `json:"published_at,omitempty"`
	IsPrerelease bool       `json:"is_prerelease"`
	IsDraft      bool       `json:"is_draft"`
	Author       string     `json:"author,omitempty"`
}

Changelog represents release changelog information

type ChangelogCacheRepository

type ChangelogCacheRepository interface {
	Get(ctx context.Context, image, version string) (*models.Changelog, error)
	Set(ctx context.Context, image, version string, changelog *models.Changelog, expiresAt time.Time) error
}

ChangelogCacheRepository interface for caching changelogs

type ChangelogEntry

type ChangelogEntry struct {
	Version string
	Date    string
	Changes map[string][]string // Type -> Changes
}

ChangelogEntry represents a parsed changelog entry

func FindChangelogEntry

func FindChangelogEntry(entries []ChangelogEntry, version string) *ChangelogEntry

FindChangelogEntry finds a specific version in parsed changelog

func ParseChangelogMD

func ParseChangelogMD(content string) []ChangelogEntry

ParseChangelogMD parses a CHANGELOG.md file

type ChangelogFetcher

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

ChangelogFetcher fetches changelogs from various sources

func NewChangelogFetcher

func NewChangelogFetcher(config *ChangelogFetcherConfig, cacheRepo ChangelogCacheRepository, log *logger.Logger) *ChangelogFetcher

NewChangelogFetcher creates a new changelog fetcher

func (*ChangelogFetcher) FetchChangelog

func (f *ChangelogFetcher) FetchChangelog(ctx context.Context, image, version string, labels map[string]string) (*models.Changelog, error)

FetchChangelog fetches a changelog for the given image and version

func (*ChangelogFetcher) FetchLatestChangelog

func (f *ChangelogFetcher) FetchLatestChangelog(ctx context.Context, image string, labels map[string]string) (*models.Changelog, error)

FetchLatestChangelog fetches the latest changelog for an image

type ChangelogFetcherConfig

type ChangelogFetcherConfig struct {
	Timeout     time.Duration
	GitHubToken string
	GitLabToken string
}

ChangelogFetcherConfig holds configuration for the changelog fetcher

type Checker

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

Checker checks for available updates

func NewChecker

func NewChecker(config *CheckerConfig, cache VersionCache, log *logger.Logger) *Checker

NewChecker creates a new version checker

func (*Checker) CheckContainer

func (c *Checker) CheckContainer(ctx context.Context, containerID, containerName, image, currentDigest string) (*models.AvailableUpdate, error)

CheckContainer checks if a container has an update available. currentDigest is the running container's image digest (from Docker ImageID), used for accurate comparison with "latest" tagged images.

func (*Checker) CheckContainers

func (c *Checker) CheckContainers(ctx context.Context, containers []ContainerInfo) (*models.UpdateCheckResult, error)

CheckContainers checks multiple containers for updates

func (*Checker) RegisterClient

func (c *Checker) RegisterClient(client RegistryClient)

RegisterClient registers a registry client

type CheckerConfig

type CheckerConfig struct {
	// CacheTTL is how long to cache version information
	CacheTTL time.Duration

	// CheckTimeout is the timeout for checking a single image
	CheckTimeout time.Duration

	// MaxConcurrent is the maximum number of concurrent checks
	MaxConcurrent int

	// IncludePrerelease includes prerelease versions in checks
	IncludePrerelease bool

	// SkipLocalImages skips images that appear to be locally built
	SkipLocalImages bool
}

CheckerConfig holds configuration for the version checker

func DefaultCheckerConfig

func DefaultCheckerConfig() *CheckerConfig

DefaultCheckerConfig returns the default checker configuration

type ContainerInfo

type ContainerInfo struct {
	ID     string
	Name   string
	Image  string
	Digest string // Current digest if known
}

ContainerInfo holds basic container information for checking

type ContainerUpdateCount

type ContainerUpdateCount struct {
	ContainerID   string `json:"container_id"`
	ContainerName string `json:"container_name"`
	Count         int    `json:"count"`
}

ContainerUpdateCount represents update count for a container

type ContainerVersionUpdater

type ContainerVersionUpdater interface {
	UpdateVersionInfo(ctx context.Context, id string, currentVersion, latestVersion string, updateAvailable bool) error
}

ContainerVersionUpdater persists version info back to the containers table.

type CreateUpdatePolicyInput

type CreateUpdatePolicyInput struct {
	TargetType        UpdateType `json:"target_type" validate:"required,oneof=container stack service"`
	TargetID          string     `json:"target_id" validate:"required"`
	AutoUpdate        bool       `json:"auto_update"`
	AutoBackup        bool       `json:"auto_backup"`
	IncludePrerelease bool       `json:"include_prerelease"`
	Schedule          *string    `json:"schedule,omitempty" validate:"omitempty,cron"`
	NotifyOnUpdate    bool       `json:"notify_on_update"`
	NotifyOnFailure   bool       `json:"notify_on_failure"`
	MaxRetries        int        `json:"max_retries,omitempty" validate:"omitempty,min=0,max=10"`
	HealthCheckWait   int        `json:"health_check_wait,omitempty" validate:"omitempty,min=5,max=600"`
}

CreateUpdatePolicyInput represents input for creating an update policy

type DBVersionCache

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

DBVersionCache uses the database for caching version information

func NewDBVersionCache

func NewDBVersionCache(repo VersionCacheRepository, log *logger.Logger) *DBVersionCache

NewDBVersionCache creates a database-backed version cache

func (*DBVersionCache) Cleanup

func (c *DBVersionCache) Cleanup(ctx context.Context) (int64, error)

Cleanup removes expired entries

func (*DBVersionCache) Delete

func (c *DBVersionCache) Delete(ctx context.Context, image, tag string)

Delete removes a version from the database cache

func (*DBVersionCache) Get

func (c *DBVersionCache) Get(ctx context.Context, image, tag string) (*models.ImageVersion, bool)

Get retrieves a cached version from the database

func (*DBVersionCache) Set

func (c *DBVersionCache) Set(ctx context.Context, image, tag string, version *models.ImageVersion, ttl time.Duration)

Set stores a version in the database cache

type DockerClient

type DockerClient interface {
	// Container operations
	ContainerInspect(ctx context.Context, containerID string) (*dockertypes.ContainerJSON, error)
	ContainerStop(ctx context.Context, containerID string, timeout *int) error
	ContainerStart(ctx context.Context, containerID string) error
	ContainerRemove(ctx context.Context, containerID string, force bool) error
	ContainerCreate(ctx context.Context, config *container.Config, hostConfig *container.HostConfig, name string) (string, error)
	ContainerRename(ctx context.Context, containerID, newName string) error
	ContainerList(ctx context.Context) ([]ContainerInfo, error)

	// Image operations
	ImagePull(ctx context.Context, ref string, onProgress func(status string)) error
	ImageInspect(ctx context.Context, imageID string) (*ImageInfo, error)
}

DockerClient interface for Docker operations

type DockerClientAdapter

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

DockerClientAdapter adapts a host-based Docker client pool to the DockerClient interface required by the update service. It resolves the client lazily on each call.

func NewDockerClientAdapter

func NewDockerClientAdapter(provider HostClientProvider, hostID uuid.UUID) *DockerClientAdapter

NewDockerClientAdapter wraps a host client provider to implement DockerClient.

func (*DockerClientAdapter) ContainerCreate

func (a *DockerClientAdapter) ContainerCreate(ctx context.Context, config *container.Config, hostConfig *container.HostConfig, name string) (string, error)

func (*DockerClientAdapter) ContainerInspect

func (a *DockerClientAdapter) ContainerInspect(ctx context.Context, containerID string) (*dockertypes.ContainerJSON, error)

func (*DockerClientAdapter) ContainerList

func (a *DockerClientAdapter) ContainerList(ctx context.Context) ([]ContainerInfo, error)

func (*DockerClientAdapter) ContainerRemove

func (a *DockerClientAdapter) ContainerRemove(ctx context.Context, containerID string, force bool) error

func (*DockerClientAdapter) ContainerRename

func (a *DockerClientAdapter) ContainerRename(ctx context.Context, containerID, newName string) error

func (*DockerClientAdapter) ContainerStart

func (a *DockerClientAdapter) ContainerStart(ctx context.Context, containerID string) error

func (*DockerClientAdapter) ContainerStop

func (a *DockerClientAdapter) ContainerStop(ctx context.Context, containerID string, timeout *int) error

func (*DockerClientAdapter) ImageInspect

func (a *DockerClientAdapter) ImageInspect(ctx context.Context, imageID string) (*ImageInfo, error)

func (*DockerClientAdapter) ImagePull

func (a *DockerClientAdapter) ImagePull(ctx context.Context, ref string, onProgress func(status string)) error

type DockerHubClient

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

DockerHubClient implements RegistryClient for Docker Hub

func NewDockerHubClient

func NewDockerHubClient(config *DockerHubConfig, log *logger.Logger) *DockerHubClient

NewDockerHubClient creates a new Docker Hub client

func (*DockerHubClient) GetDigest

func (c *DockerHubClient) GetDigest(ctx context.Context, ref *models.ImageRef) (string, error)

GetDigest gets the digest for a specific tag

func (*DockerHubClient) GetLatestSemverTag

func (c *DockerHubClient) GetLatestSemverTag(ctx context.Context, ref *models.ImageRef) (string, error)

GetLatestSemverTag finds the latest semantic version tag

func (*DockerHubClient) GetLatestVersion

func (c *DockerHubClient) GetLatestVersion(ctx context.Context, ref *models.ImageRef) (*models.ImageVersion, error)

GetLatestVersion gets the latest version info for an image from Docker Hub using variant-aware filtering (e.g. redis:7-alpine only compares against 7.x-alpine tags)

func (*DockerHubClient) GetTagsFromHubAPI

func (c *DockerHubClient) GetTagsFromHubAPI(ctx context.Context, namespace, repository string, page, pageSize int) (*DockerHubTagsResponse, error)

GetTagsFromHubAPI gets tags using the Docker Hub API (not registry API) This provides more information like last_updated

func (*DockerHubClient) ListTags

func (c *DockerHubClient) ListTags(ctx context.Context, ref *models.ImageRef, limit int) ([]string, error)

ListTags lists available tags for an image

func (*DockerHubClient) SupportsRegistry

func (c *DockerHubClient) SupportsRegistry(registry string) bool

SupportsRegistry returns true for Docker Hub registries

type DockerHubConfig

type DockerHubConfig struct {
	// Timeout for HTTP requests
	Timeout time.Duration

	// Username for Docker Hub (optional, for private repos)
	Username string

	// Password/Token for Docker Hub
	Password string
}

DockerHubConfig holds configuration for Docker Hub client

type DockerHubImage

type DockerHubImage struct {
	Architecture string    `json:"architecture"`
	Digest       string    `json:"digest"`
	OS           string    `json:"os"`
	Size         int64     `json:"size"`
	LastPushed   time.Time `json:"last_pushed"`
}

DockerHubImage represents image details within a tag

type DockerHubTag

type DockerHubTag struct {
	Name        string           `json:"name"`
	FullSize    int64            `json:"full_size"`
	LastUpdated time.Time        `json:"last_updated"`
	Images      []DockerHubImage `json:"images"`
}

DockerHubTag represents a single tag from Docker Hub

type DockerHubTagsResponse

type DockerHubTagsResponse struct {
	Count    int            `json:"count"`
	Next     string         `json:"next"`
	Previous string         `json:"previous"`
	Results  []DockerHubTag `json:"results"`
}

DockerHubTagsResponse represents the Docker Hub tags API response

type GHCRClient

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

GHCRClient implements RegistryClient for GitHub Container Registry

func NewGHCRClient

func NewGHCRClient(config *GHCRConfig, log *logger.Logger) *GHCRClient

NewGHCRClient creates a new GHCR client

func (*GHCRClient) GetDigest

func (c *GHCRClient) GetDigest(ctx context.Context, ref *models.ImageRef) (string, error)

GetDigest gets the digest for a specific tag

func (*GHCRClient) GetLatestVersion

func (c *GHCRClient) GetLatestVersion(ctx context.Context, ref *models.ImageRef) (*models.ImageVersion, error)

GetLatestVersion gets the latest version info for an image from GHCR

func (*GHCRClient) ListTags

func (c *GHCRClient) ListTags(ctx context.Context, ref *models.ImageRef, limit int) ([]string, error)

ListTags lists available tags for an image

func (*GHCRClient) SupportsRegistry

func (c *GHCRClient) SupportsRegistry(registry string) bool

SupportsRegistry returns true for GHCR

type GHCRConfig

type GHCRConfig struct {
	// Timeout for HTTP requests
	Timeout time.Duration

	// Token is the GitHub token (PAT or GITHUB_TOKEN)
	// Required for private packages, optional for public
	Token string
}

GHCRConfig holds configuration for GHCR client

type GenericRegistryClient

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

GenericRegistryClient implements RegistryClient for generic OCI registries

func NewGenericRegistryClient

func NewGenericRegistryClient(config *GenericRegistryConfig, log *logger.Logger) *GenericRegistryClient

NewGenericRegistryClient creates a new generic registry client

func (*GenericRegistryClient) GetDigest

func (c *GenericRegistryClient) GetDigest(ctx context.Context, ref *models.ImageRef) (string, error)

GetDigest gets the digest for a specific tag

func (*GenericRegistryClient) GetLatestVersion

func (c *GenericRegistryClient) GetLatestVersion(ctx context.Context, ref *models.ImageRef) (*models.ImageVersion, error)

GetLatestVersion gets the latest version info

func (*GenericRegistryClient) ListTags

func (c *GenericRegistryClient) ListTags(ctx context.Context, ref *models.ImageRef, limit int) ([]string, error)

ListTags lists available tags

func (*GenericRegistryClient) SupportsRegistry

func (c *GenericRegistryClient) SupportsRegistry(registry string) bool

SupportsRegistry returns true if registry is in the configured list

type GenericRegistryConfig

type GenericRegistryConfig struct {
	Timeout    time.Duration
	Registries []string // List of supported registries
	Username   string
	Password   string
}

GenericRegistryConfig holds configuration for generic registry client

type GitHubRelease

type GitHubRelease struct {
	ID          int64     `json:"id"`
	TagName     string    `json:"tag_name"`
	Name        string    `json:"name"`
	Body        string    `json:"body"`
	Draft       bool      `json:"draft"`
	Prerelease  bool      `json:"prerelease"`
	PublishedAt time.Time `json:"published_at"`
	HTMLURL     string    `json:"html_url"`
	Author      struct {
		Login string `json:"login"`
	} `json:"author"`
}

GitHubRelease represents a GitHub release

func (*GitHubRelease) ToChangelog

func (r *GitHubRelease) ToChangelog() *models.Changelog

ToChangelog converts a GitHub release to a Changelog model

type GitHubReleasesClient

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

GitHubReleasesClient fetches release information from GitHub

func NewGitHubReleasesClient

func NewGitHubReleasesClient(token string, log *logger.Logger) *GitHubReleasesClient

NewGitHubReleasesClient creates a new GitHub releases client

func (*GitHubReleasesClient) GetLatestRelease

func (c *GitHubReleasesClient) GetLatestRelease(ctx context.Context, owner, repo string) (*GitHubRelease, error)

GetLatestRelease gets the latest release for a repository

func (*GitHubReleasesClient) GetReleaseByTag

func (c *GitHubReleasesClient) GetReleaseByTag(ctx context.Context, owner, repo, tag string) (*GitHubRelease, error)

GetReleaseByTag gets a specific release by tag

func (*GitHubReleasesClient) ListReleases

func (c *GitHubReleasesClient) ListReleases(ctx context.Context, owner, repo string, perPage int) ([]*GitHubRelease, error)

ListReleases lists releases for a repository

type HostClientProvider

type HostClientProvider interface {
	GetClient(ctx context.Context, hostID uuid.UUID) (dockerpkg.ClientAPI, error)
}

HostClientProvider provides Docker clients for a given host.

type ImageInfo

type ImageInfo struct {
	ID          string
	RepoTags    []string
	RepoDigests []string
	Created     time.Time
	Size        int64
	Labels      map[string]string
}

ImageInfo holds basic image information

type ImageRef

type ImageRef struct {
	Registry   string `json:"registry"`   // docker.io, ghcr.io, etc.
	Namespace  string `json:"namespace"`  // library, portainer, etc.
	Repository string `json:"repository"` // nginx, portainer-ce
	Tag        string `json:"tag"`        // latest, v2.0.0, alpine
	Digest     string `json:"digest,omitempty"`
}

ImageRef represents a parsed Docker image reference

func (*ImageRef) FullName

func (r *ImageRef) FullName() string

FullName returns the full image name

func (*ImageRef) FullNameWithTag

func (r *ImageRef) FullNameWithTag() string

FullNameWithTag returns the full image name with tag

func (*ImageRef) IsDockerHub

func (r *ImageRef) IsDockerHub() bool

IsDockerHub returns true if the image is from Docker Hub

func (*ImageRef) IsGHCR

func (r *ImageRef) IsGHCR() bool

IsGHCR returns true if the image is from GitHub Container Registry

type ImageVersion

type ImageVersion struct {
	Tag       string    `json:"tag"`
	Digest    string    `json:"digest"`
	CreatedAt time.Time `json:"created_at"`
	Size      int64     `json:"size,omitempty"`
	OS        string    `json:"os,omitempty"`
	Arch      string    `json:"arch,omitempty"`
}

ImageVersion represents version information for a Docker image

type MemoryChangelogCache

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

MemoryChangelogCache implements ChangelogCacheRepository with in-memory storage.

func NewMemoryChangelogCache

func NewMemoryChangelogCache() *MemoryChangelogCache

NewMemoryChangelogCache creates a new in-memory changelog cache.

func (*MemoryChangelogCache) Get

func (c *MemoryChangelogCache) Get(ctx context.Context, image, version string) (*models.Changelog, error)

func (*MemoryChangelogCache) Set

func (c *MemoryChangelogCache) Set(ctx context.Context, image, version string, changelog *models.Changelog, expiresAt time.Time) error

type MemoryVersionCache

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

MemoryVersionCache is an in-memory cache for version information with LRU eviction.

func NewMemoryVersionCache

func NewMemoryVersionCache() *MemoryVersionCache

NewMemoryVersionCache creates a new in-memory version cache with LRU eviction.

func (*MemoryVersionCache) Delete

func (c *MemoryVersionCache) Delete(ctx context.Context, image, tag string)

Delete removes a version from the cache

func (*MemoryVersionCache) Get

func (c *MemoryVersionCache) Get(ctx context.Context, image, tag string) (*models.ImageVersion, bool)

Get retrieves a cached version

func (*MemoryVersionCache) Set

func (c *MemoryVersionCache) Set(ctx context.Context, image, tag string, version *models.ImageVersion, ttl time.Duration)

Set stores a version in the cache, evicting the oldest entry if at capacity.

type RegistryClient

type RegistryClient interface {
	// GetLatestVersion gets the latest version info for an image
	GetLatestVersion(ctx context.Context, ref *models.ImageRef) (*models.ImageVersion, error)

	// GetDigest gets the digest for a specific tag
	GetDigest(ctx context.Context, ref *models.ImageRef) (string, error)

	// ListTags lists available tags for an image
	ListTags(ctx context.Context, ref *models.ImageRef, limit int) ([]string, error)

	// SupportsRegistry returns true if this client supports the given registry
	SupportsRegistry(registry string) bool
}

RegistryClient interface for interacting with container registries

type RollbackOptions

type RollbackOptions struct {
	UpdateID      uuid.UUID `json:"update_id" validate:"required"`
	RestoreBackup bool      `json:"restore_backup"`
	Reason        string    `json:"reason,omitempty"`
}

RollbackOptions represents options for rolling back an update

type RollbackResult

type RollbackResult struct {
	Success          bool          `json:"success"`
	UpdateID         uuid.UUID     `json:"update_id"`
	RestoredVersion  string        `json:"restored_version"`
	RestoredBackupID *uuid.UUID    `json:"restored_backup_id,omitempty"`
	Duration         time.Duration `json:"duration"`
	ErrorMessage     string        `json:"error_message,omitempty"`
}

RollbackResult represents the result of a rollback operation

type SecurityScanResult

type SecurityScanResult struct {
	Score int
	Grade string
}

SecurityScanResult from security scanning

type SecurityService

type SecurityService interface {
	ScanContainer(ctx context.Context, hostID uuid.UUID, containerID string) (*SecurityScanResult, error)
	GetLatestScan(ctx context.Context, containerID string) (*SecurityScanResult, error)
}

SecurityService interface for security scanning (from Dept F)

type Service

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

Service handles container update operations

func NewService

func NewService(
	repo UpdateRepository,
	checker *Checker,
	changelogFetcher *ChangelogFetcher,
	dockerClient DockerClient,
	backupService BackupService,
	securityService SecurityService,
	versionUpdater ContainerVersionUpdater,
	config *ServiceConfig,
	log *logger.Logger,
) *Service

NewService creates a new update service

func (*Service) CheckContainerForUpdate

func (s *Service) CheckContainerForUpdate(ctx context.Context, hostID uuid.UUID, containerID string) (*models.AvailableUpdate, error)

CheckContainerForUpdate checks a specific container for updates

func (*Service) CheckForUpdates

func (s *Service) CheckForUpdates(ctx context.Context, hostID uuid.UUID) (*models.UpdateCheckResult, error)

CheckForUpdates checks all containers on a host for available updates

func (*Service) CreateWebhook

func (s *Service) CreateWebhook(ctx context.Context, hostID uuid.UUID, targetType models.UpdateType, targetID string) (*models.UpdateWebhook, error)

CreateWebhook creates a new update webhook

func (*Service) DeletePolicy

func (s *Service) DeletePolicy(ctx context.Context, id uuid.UUID) error

DeletePolicy deletes an update policy

func (*Service) DeleteWebhook

func (s *Service) DeleteWebhook(ctx context.Context, id uuid.UUID) error

DeleteWebhook deletes a webhook

func (*Service) GetHistory

func (s *Service) GetHistory(ctx context.Context, hostID uuid.UUID, targetID string, limit int) ([]*models.Update, error)

GetHistory returns update history for a target

func (*Service) GetPolicy

func (s *Service) GetPolicy(ctx context.Context, hostID uuid.UUID, targetType models.UpdateType, targetID string) (*models.UpdatePolicy, error)

GetPolicy gets an update policy for a target

func (*Service) GetPolicyByID

func (s *Service) GetPolicyByID(ctx context.Context, id uuid.UUID) (*models.UpdatePolicy, error)

GetPolicyByID gets an update policy by ID

func (*Service) GetStats

func (s *Service) GetStats(ctx context.Context, hostID *uuid.UUID) (*models.UpdateStats, error)

GetStats returns update statistics

func (*Service) ListPolicies

func (s *Service) ListPolicies(ctx context.Context, hostID *uuid.UUID) ([]*models.UpdatePolicy, error)

ListPolicies lists all update policies

func (*Service) ListUpdates

func (s *Service) ListUpdates(ctx context.Context, opts models.UpdateListOptions) ([]*models.Update, int64, error)

ListUpdates lists updates with filtering

func (*Service) ListWebhooks

func (s *Service) ListWebhooks(ctx context.Context, hostID uuid.UUID) ([]*models.UpdateWebhook, error)

ListWebhooks lists all webhooks for a host

func (*Service) RollbackUpdate

func (s *Service) RollbackUpdate(ctx context.Context, opts *models.RollbackOptions) (*models.RollbackResult, error)

RollbackUpdate rolls back a completed update

func (*Service) SetPolicy

func (s *Service) SetPolicy(ctx context.Context, policy *models.UpdatePolicy) error

SetPolicy creates or updates an update policy

func (*Service) TriggerWebhook

func (s *Service) TriggerWebhook(ctx context.Context, token string) (*models.UpdateResult, error)

TriggerWebhook triggers an update via webhook

func (*Service) UpdateContainer

func (s *Service) UpdateContainer(ctx context.Context, hostID uuid.UUID, opts *models.UpdateOptions) (*models.UpdateResult, error)

UpdateContainer performs an update on a container

type ServiceConfig

type ServiceConfig struct {
	// DefaultHealthCheckWait is the default wait time for health checks
	DefaultHealthCheckWait time.Duration

	// DefaultMaxRetries is the default max retries for health checks
	DefaultMaxRetries int

	// DefaultBackupVolumes whether to backup volumes by default
	DefaultBackupVolumes bool

	// DefaultSecurityScan whether to perform security scan by default
	DefaultSecurityScan bool

	// MaxConcurrentUpdates is the max number of concurrent updates
	MaxConcurrentUpdates int
}

ServiceConfig holds configuration for the update service

func DefaultServiceConfig

func DefaultServiceConfig() *ServiceConfig

DefaultServiceConfig returns default service configuration

type SourceInfo

type SourceInfo struct {
	Type       string // "github" or "gitlab"
	URL        string
	Owner      string
	Repository string
}

SourceInfo contains information about the source repository

func DetectSource

func DetectSource(labels map[string]string) *SourceInfo

DetectSource detects the source repository from container labels

type Update

type Update struct {
	ID                  uuid.UUID     `json:"id" db:"id"`
	HostID              uuid.UUID     `json:"host_id" db:"host_id"`
	Type                UpdateType    `json:"type" db:"type"`
	TargetID            string        `json:"target_id" db:"target_id"` // Container ID or Stack ID
	TargetName          string        `json:"target_name" db:"target_name"`
	Image               string        `json:"image" db:"image"`
	FromVersion         string        `json:"from_version" db:"from_version"`
	ToVersion           string        `json:"to_version" db:"to_version"`
	FromDigest          *string       `json:"from_digest,omitempty" db:"from_digest"`
	ToDigest            *string       `json:"to_digest,omitempty" db:"to_digest"`
	Status              UpdateStatus  `json:"status" db:"status"`
	Trigger             UpdateTrigger `json:"trigger" db:"trigger"`
	BackupID            *uuid.UUID    `json:"backup_id,omitempty" db:"backup_id"`
	ChangelogURL        *string       `json:"changelog_url,omitempty" db:"changelog_url"`
	ChangelogBody       *string       `json:"changelog_body,omitempty" db:"changelog_body"`
	SecurityScoreBefore *int          `json:"security_score_before,omitempty" db:"security_score_before"`
	SecurityScoreAfter  *int          `json:"security_score_after,omitempty" db:"security_score_after"`
	HealthCheckPassed   *bool         `json:"health_check_passed,omitempty" db:"health_check_passed"`
	RollbackReason      *string       `json:"rollback_reason,omitempty" db:"rollback_reason"`
	ErrorMessage        *string       `json:"error_message,omitempty" db:"error_message"`
	DurationMs          *int64        `json:"duration_ms,omitempty" db:"duration_ms"`
	CreatedBy           *uuid.UUID    `json:"created_by,omitempty" db:"created_by"`
	StartedAt           *time.Time    `json:"started_at,omitempty" db:"started_at"`
	CompletedAt         *time.Time    `json:"completed_at,omitempty" db:"completed_at"`
	CreatedAt           time.Time     `json:"created_at" db:"created_at"`
}

Update represents an update operation record

func (*Update) CanRollback

func (u *Update) CanRollback() bool

CanRollback returns true if the update can be rolled back

func (*Update) Duration

func (u *Update) Duration() time.Duration

Duration returns the update duration

func (*Update) SecurityScoreDelta

func (u *Update) SecurityScoreDelta() int

SecurityScoreDelta returns the security score change

type UpdateCheckResult

type UpdateCheckResult struct {
	HostID           uuid.UUID         `json:"host_id"`
	CheckedAt        time.Time         `json:"checked_at"`
	TotalContainers  int               `json:"total_containers"`
	CheckedCount     int               `json:"checked_count"`
	UpdatesAvailable int               `json:"updates_available"`
	Errors           int               `json:"errors"`
	Updates          []AvailableUpdate `json:"updates,omitempty"`
	SkippedImages    []string          `json:"skipped_images,omitempty"`
}

UpdateCheckResult represents the result of checking for updates

type UpdateListOptions

type UpdateListOptions struct {
	HostID   *uuid.UUID     `json:"host_id,omitempty"`
	TargetID *string        `json:"target_id,omitempty"`
	Status   *UpdateStatus  `json:"status,omitempty"`
	Trigger  *UpdateTrigger `json:"trigger,omitempty"`
	Before   *time.Time     `json:"before,omitempty"`
	After    *time.Time     `json:"after,omitempty"`
	Limit    int            `json:"limit,omitempty"`
	Offset   int            `json:"offset,omitempty"`
}

UpdateListOptions represents options for listing updates

type UpdateOptions

type UpdateOptions struct {
	ContainerID     string        `json:"container_id" validate:"required"`
	TargetVersion   string        `json:"target_version,omitempty"` // Empty = latest
	ForcePull       bool          `json:"force_pull,omitempty"`
	BackupVolumes   bool          `json:"backup_volumes"`
	SecurityScan    bool          `json:"security_scan"`
	HealthCheckWait time.Duration `json:"health_check_wait,omitempty"`
	MaxRetries      int           `json:"max_retries,omitempty"`
	DryRun          bool          `json:"dry_run,omitempty"`
}

UpdateOptions represents options for performing an update

func DefaultUpdateOptions

func DefaultUpdateOptions() UpdateOptions

DefaultUpdateOptions returns default update options

type UpdatePolicy

type UpdatePolicy struct {
	ID                uuid.UUID  `json:"id" db:"id"`
	HostID            uuid.UUID  `json:"host_id" db:"host_id"`
	TargetType        UpdateType `json:"target_type" db:"target_type"`
	TargetID          string     `json:"target_id" db:"target_id"`
	TargetName        string     `json:"target_name" db:"target_name"`
	IsEnabled         bool       `json:"is_enabled" db:"is_enabled"`
	AutoUpdate        bool       `json:"auto_update" db:"auto_update"`
	AutoBackup        bool       `json:"auto_backup" db:"auto_backup"`
	IncludePrerelease bool       `json:"include_prerelease" db:"include_prerelease"`
	Schedule          *string    `json:"schedule,omitempty" db:"schedule"` // Cron expression
	NotifyOnUpdate    bool       `json:"notify_on_update" db:"notify_on_update"`
	NotifyOnFailure   bool       `json:"notify_on_failure" db:"notify_on_failure"`
	MaxRetries        int        `json:"max_retries" db:"max_retries"`
	HealthCheckWait   int        `json:"health_check_wait" db:"health_check_wait"` // Seconds
	CreatedAt         time.Time  `json:"created_at" db:"created_at"`
	UpdatedAt         time.Time  `json:"updated_at" db:"updated_at"`
}

UpdatePolicy represents update policy settings for a container/stack

func DefaultUpdatePolicy

func DefaultUpdatePolicy() UpdatePolicy

DefaultUpdatePolicy returns a default update policy

type UpdatePolicyInput

type UpdatePolicyInput struct {
	IsEnabled         *bool   `json:"is_enabled,omitempty"`
	AutoUpdate        *bool   `json:"auto_update,omitempty"`
	AutoBackup        *bool   `json:"auto_backup,omitempty"`
	IncludePrerelease *bool   `json:"include_prerelease,omitempty"`
	Schedule          *string `json:"schedule,omitempty" validate:"omitempty,cron"`
	NotifyOnUpdate    *bool   `json:"notify_on_update,omitempty"`
	NotifyOnFailure   *bool   `json:"notify_on_failure,omitempty"`
	MaxRetries        *int    `json:"max_retries,omitempty" validate:"omitempty,min=0,max=10"`
	HealthCheckWait   *int    `json:"health_check_wait,omitempty" validate:"omitempty,min=5,max=600"`
}

UpdatePolicyInput represents input for updating an update policy

type UpdateRepository

type UpdateRepository interface {
	Create(ctx context.Context, update *models.Update) error
	Get(ctx context.Context, id uuid.UUID) (*models.Update, error)
	Update(ctx context.Context, update *models.Update) error
	UpdateStatus(ctx context.Context, id uuid.UUID, status models.UpdateStatus, errorMsg *string) error
	Delete(ctx context.Context, id uuid.UUID) error
	List(ctx context.Context, opts models.UpdateListOptions) ([]*models.Update, int64, error)
	GetByTarget(ctx context.Context, hostID uuid.UUID, targetID string, limit int) ([]*models.Update, error)
	GetLatestByTarget(ctx context.Context, hostID uuid.UUID, targetID string) (*models.Update, error)
	GetRollbackCandidate(ctx context.Context, hostID uuid.UUID, targetID string) (*models.Update, error)
	GetStats(ctx context.Context, hostID *uuid.UUID) (*models.UpdateStats, error)

	// Policy operations
	CreatePolicy(ctx context.Context, policy *models.UpdatePolicy) error
	GetPolicy(ctx context.Context, id uuid.UUID) (*models.UpdatePolicy, error)
	GetPolicyByTarget(ctx context.Context, hostID uuid.UUID, targetType models.UpdateType, targetID string) (*models.UpdatePolicy, error)
	UpdatePolicy(ctx context.Context, policy *models.UpdatePolicy) error
	DeletePolicy(ctx context.Context, id uuid.UUID) error
	ListPolicies(ctx context.Context, hostID *uuid.UUID) ([]*models.UpdatePolicy, error)
	GetAutoUpdatePolicies(ctx context.Context) ([]*models.UpdatePolicy, error)

	// Webhook operations
	CreateWebhook(ctx context.Context, webhook *models.UpdateWebhook) error
	GetWebhookByToken(ctx context.Context, token string) (*models.UpdateWebhook, error)
	UpdateWebhookLastUsed(ctx context.Context, id uuid.UUID) error
	DeleteWebhook(ctx context.Context, id uuid.UUID) error
	ListWebhooks(ctx context.Context, hostID uuid.UUID) ([]*models.UpdateWebhook, error)
}

UpdateRepository interface for update persistence

type UpdateResult

type UpdateResult struct {
	Update         *Update       `json:"update"`
	Success        bool          `json:"success"`
	FromVersion    string        `json:"from_version"`
	ToVersion      string        `json:"to_version"`
	BackupID       *uuid.UUID    `json:"backup_id,omitempty"`
	NewContainerID string        `json:"new_container_id,omitempty"`
	Duration       time.Duration `json:"duration"`
	HealthPassed   bool          `json:"health_passed"`
	SecurityDelta  int           `json:"security_delta"`
	WasRolledBack  bool          `json:"was_rolled_back"`
	RollbackReason string        `json:"rollback_reason,omitempty"`
	ErrorMessage   string        `json:"error_message,omitempty"`
}

UpdateResult represents the result of an update operation

type UpdateStats

type UpdateStats struct {
	TotalUpdates    int                    `json:"total_updates"`
	SuccessfulCount int                    `json:"successful_count"`
	FailedCount     int                    `json:"failed_count"`
	RolledBackCount int                    `json:"rolled_back_count"`
	AvgDurationMs   int64                  `json:"avg_duration_ms"`
	ByStatus        map[string]int         `json:"by_status"`
	ByTrigger       map[string]int         `json:"by_trigger"`
	LastUpdateAt    *time.Time             `json:"last_update_at,omitempty"`
	MostUpdated     []ContainerUpdateCount `json:"most_updated,omitempty"`
}

UpdateStats represents update statistics

type UpdateStatus

type UpdateStatus string

UpdateStatus represents the status of an update operation

const (
	UpdateStatusPending     UpdateStatus = "pending"
	UpdateStatusChecking    UpdateStatus = "checking"
	UpdateStatusAvailable   UpdateStatus = "available"
	UpdateStatusPulling     UpdateStatus = "pulling"
	UpdateStatusBackingUp   UpdateStatus = "backing_up"
	UpdateStatusUpdating    UpdateStatus = "updating"
	UpdateStatusHealthCheck UpdateStatus = "health_check"
	UpdateStatusCompleted   UpdateStatus = "completed"
	UpdateStatusFailed      UpdateStatus = "failed"
	UpdateStatusRolledBack  UpdateStatus = "rolled_back"
	UpdateStatusSkipped     UpdateStatus = "skipped"
)

func (UpdateStatus) IsSuccess

func (s UpdateStatus) IsSuccess() bool

IsSuccess returns true if the update completed successfully

func (UpdateStatus) IsTerminal

func (s UpdateStatus) IsTerminal() bool

IsTerminal returns true if the status is a terminal state

type UpdateTrigger

type UpdateTrigger string

UpdateTrigger represents what triggered the update

const (
	UpdateTriggerManual     UpdateTrigger = "manual"
	UpdateTriggerScheduled  UpdateTrigger = "scheduled"
	UpdateTriggerWebhook    UpdateTrigger = "webhook"
	UpdateTriggerWatchtower UpdateTrigger = "watchtower"
	UpdateTriggerAutomatic  UpdateTrigger = "automatic"
)

type UpdateType

type UpdateType string

UpdateType represents the type of update target

const (
	UpdateTypeContainer UpdateType = "container"
	UpdateTypeStack     UpdateType = "stack"
	UpdateTypeService   UpdateType = "service" // Swarm service
)

type UpdateWebhook

type UpdateWebhook struct {
	ID         uuid.UUID  `json:"id" db:"id"`
	HostID     uuid.UUID  `json:"host_id" db:"host_id"`
	TargetType UpdateType `json:"target_type" db:"target_type"`
	TargetID   string     `json:"target_id" db:"target_id"`
	Token      string     `json:"token" db:"token"` // Webhook token
	IsEnabled  bool       `json:"is_enabled" db:"is_enabled"`
	LastUsedAt *time.Time `json:"last_used_at,omitempty" db:"last_used_at"`
	CreatedAt  time.Time  `json:"created_at" db:"created_at"`
}

UpdateWebhook represents a webhook configuration for updates

func (*UpdateWebhook) WebhookURL

func (w *UpdateWebhook) WebhookURL(baseURL string) string

WebhookURL returns the webhook URL

type VersionCache

type VersionCache interface {
	Get(ctx context.Context, image, tag string) (*models.ImageVersion, bool)
	Set(ctx context.Context, image, tag string, version *models.ImageVersion, ttl time.Duration)
	Delete(ctx context.Context, image, tag string)
}

VersionCache interface for caching version information

type VersionCacheRepository

type VersionCacheRepository interface {
	GetVersion(ctx context.Context, image, tag string) (*models.ImageVersion, error)
	SetVersion(ctx context.Context, image, tag string, version *models.ImageVersion, expiresAt time.Time) error
	DeleteVersion(ctx context.Context, image, tag string) error
	DeleteExpired(ctx context.Context) (int64, error)
}

VersionCacheRepository interface for database operations

Jump to

Keyboard shortcuts

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