Documentation
¶
Index ¶
- func AtomicReplaceFileWithS(ctx context.Context, runner *cmdrunner.CommandsRunner, ...) error
- func CopyWithContext(ctx context.Context, dst io.Writer, src io.Reader) (int64, error)
- func GetDownloadedVersions(baseDir, binaryName string, logger *logrus.Entry) ([]string, error)
- func MoveFile(logger *logrus.Entry, src, dst string) error
- func TempSiblingPath(dst string) string
- func VerifyChecksum(logger *logrus.Entry, filePath, expectedSHA256 string) error
- type ArchiveBinary
- type ArchiveRelease
- type PermissionManager
- type ValidationOutcome
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func AtomicReplaceFileWithS ¶ added in v1.6.1
func AtomicReplaceFileWithS( ctx context.Context, runner *cmdrunner.CommandsRunner, dst, content, mode string, validate func(ctx context.Context, tmpPath string) error, ) error
AtomicReplaceFileWithS writes content to a sibling temp file (via sudo, because the target directories are root-owned and the client runs as the elchi user), sets its mode, runs validate against the staged temp, then atomically renames it onto dst with `mv -f` (atomic on the same filesystem). The live dst is never touched until validation passes, so an interrupted write or a rejected config can never leave a broken file in place. The temp is removed on any failure.
validate may be nil. It receives the staged temp path and should return a non-nil error only for a genuine config rejection; a validator that cannot run should be treated as best-effort by the caller (see ClassifyValidatorResult) and return nil.
func CopyWithContext ¶
CopyWithContext copies data from src to dst with context cancellation support
func GetDownloadedVersions ¶
GetDownloadedVersions returns list of locally downloaded versions by scanning the base directory for version directories containing the specified binary
func MoveFile ¶
MoveFile moves a file from src to dst, handling cross-device links. The cross-device fallback is crash-safe: the destination is only ever made visible via an atomic rename, never written in place. The previous code io.Copy'd straight into dst, so a crash mid-copy left a truncated dst that a later non-force SetVersion would accept as a valid (but corrupt) binary.
func TempSiblingPath ¶ added in v1.6.1
TempSiblingPath returns a hidden temp path in the SAME directory as dst, so a later rename onto dst is an atomic same-filesystem move. It is pure (no I/O) so the naming can be unit-tested.
Types ¶
type ArchiveBinary ¶
type ArchiveBinary struct {
Arch string `json:"arch"`
DownloadURL string `json:"download_url"`
SHA256 string `json:"sha256"`
}
ArchiveBinary represents a binary download info
type ArchiveRelease ¶
type ArchiveRelease struct {
Version string `json:"version"`
Date time.Time `json:"date"`
Binaries []ArchiveBinary `json:"binaries"`
}
ArchiveRelease represents a single release from the archive API
type PermissionManager ¶
type PermissionManager struct {
BaseDir string
DirPerm os.FileMode
FilePerm os.FileMode
Logger *logrus.Entry
}
PermissionManager manages directory and file permissions for binary packages
func NewPermissionManager ¶
func NewPermissionManager(baseDir string, dirPerm, filePerm os.FileMode, logger *logrus.Entry) *PermissionManager
NewPermissionManager creates a new PermissionManager with the given configuration
func (*PermissionManager) CreateVersionDirectory ¶
func (pm *PermissionManager) CreateVersionDirectory(version string) (string, error)
CreateVersionDirectory creates directory structure for a version
func (*PermissionManager) EnsureBaseDirectory ¶
func (pm *PermissionManager) EnsureBaseDirectory() error
EnsureBaseDirectory creates the base directory if it doesn't exist
func (*PermissionManager) SetBinaryPermissions ¶
func (pm *PermissionManager) SetBinaryPermissions(binaryPath string) error
SetBinaryPermissions sets proper permissions for a binary file
type ValidationOutcome ¶ added in v1.6.1
type ValidationOutcome int
ValidationOutcome is the interpreted result of running a config validator.
const ( // ConfigValid means the validator ran and accepted the config. ConfigValid ValidationOutcome = iota // ConfigInvalid means the validator ran and rejected the config — the caller // must NOT commit the staged file. ConfigInvalid // binary, no permission, missing keystore, …). Callers treat this as // best-effort and proceed, exactly as the shield sync does, since refusing // every push because the validator is broken would be worse than today's // no-validation behaviour. ConfigValidatorUnavailable )
func ClassifyValidatorResult ¶ added in v1.6.1
func ClassifyValidatorResult(exitErr error, output string) ValidationOutcome
ClassifyValidatorResult interprets a config-validator invocation. exitErr is the error from running the validator (nil ⇒ exit 0); output is its combined output. A clean exit is ConfigValid; a non-zero exit whose output looks like the validator could not run is ConfigValidatorUnavailable; any other non-zero exit is a genuine ConfigInvalid. It is pure so it can be unit-tested without a validator binary.