You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

139 lines
4.6 KiB

package update
import (
"context"
"errors"
"io"
"time"
"tera-clone/services/tera-api/internal/storage/capacity"
)
const (
ApplyCapabilityValidationOnly = "validation-only"
ApplyCapabilityRecoveryV1 = "recovery-v1"
RecoveryCapabilityOfflineV1 = "offline-resumable-v1"
StateIdle = "idle"
StateReceiving = "receiving"
StateStaged = "staged"
StateValidating = "validating"
StateValidated = "validated"
StateApplyPending = "apply_pending"
StateRebootPending = "reboot_pending"
StateApplying = "applying"
StateVerifying = "verifying"
StateSucceeded = "succeeded"
StateFailed = "failed"
)
type Payload struct {
Name string `json:"name"`
Path string `json:"path"`
Class string `json:"class"`
Size int64 `json:"size"`
SHA256 string `json:"sha256"`
TargetPartition string `json:"target_partition,omitempty"`
Encoding string `json:"encoding,omitempty"`
ExpandedSize int64 `json:"expanded_size,omitempty"`
ExpandedSHA256 string `json:"expanded_sha256,omitempty"`
}
type Manifest struct {
FormatVersion int `json:"format_version"`
PackageID string `json:"package_id"`
Product string `json:"product"`
HardwareProfile string `json:"hardware_profile"`
Version string `json:"version"`
MinimumCurrentVersion string `json:"minimum_current_version,omitempty"`
AllowDowngrade bool `json:"allow_downgrade"`
CreatedAt time.Time `json:"created_at"`
SigningKeyID string `json:"signing_key_id"`
Payloads []Payload `json:"payloads"`
Apply struct {
Capability string `json:"capability"`
RebootRequired bool `json:"reboot_required"`
} `json:"apply"`
Recovery struct {
Capability string `json:"capability"`
Instructions string `json:"instructions"`
} `json:"recovery"`
}
type Status struct {
FormatVersion int `json:"format_version"`
OperationID string `json:"operation_id,omitempty"`
State string `json:"state"`
Message string `json:"message"`
Filename string `json:"filename,omitempty"`
DeviceVersion string `json:"device_version,omitempty"`
BytesReceived int64 `json:"bytes_received"`
BytesTotal int64 `json:"bytes_total"`
ProgressPercent int `json:"progress_percent"`
PackagePath string `json:"-"`
Manifest *Manifest `json:"manifest,omitempty"`
SignerKeyID string `json:"signer_key_id,omitempty"`
ApplyEnabled bool `json:"apply_enabled"`
ApplyDisabledReason string `json:"apply_disabled_reason,omitempty"`
RecoveryInstructions string `json:"recovery_instructions,omitempty"`
FailureCode string `json:"failure_code,omitempty"`
FailureReason string `json:"failure_reason,omitempty"`
RecoveryStep string `json:"recovery_step,omitempty"`
RecoveryAttempt int `json:"recovery_attempt,omitempty"`
Capacity capacity.Snapshot `json:"capacity"`
CreatedAt time.Time `json:"created_at,omitempty"`
UpdatedAt time.Time `json:"updated_at"`
}
type UploadRequest struct {
Filename string
ContentLength int64
Actor string
Body io.Reader
}
type ApplyRequest struct {
Actor string
OperationID string
}
type Controller interface {
Status(context.Context) (Status, error)
Upload(context.Context, UploadRequest) (Status, error)
Apply(context.Context, ApplyRequest) (Status, error)
}
type Error struct {
Code string
Message string
}
func (e *Error) Error() string { return e.Message }
func Code(err error) string {
var updateErr *Error
if errors.As(err, &updateErr) {
return updateErr.Code
}
return ""
}
type UnavailableController struct{ Reason string }
func (u UnavailableController) unavailable() error {
reason := u.Reason
if reason == "" {
reason = "tera-updated is unavailable"
}
return &Error{Code: "update_unavailable", Message: reason}
}
func (u UnavailableController) Status(context.Context) (Status, error) {
return Status{}, u.unavailable()
}
func (u UnavailableController) Upload(context.Context, UploadRequest) (Status, error) {
return Status{}, u.unavailable()
}
func (u UnavailableController) Apply(context.Context, ApplyRequest) (Status, error) {
return Status{}, u.unavailable()
}