Fence installation transaction durability (T-613)
This commit is contained in:
@@ -35,7 +35,8 @@ var (
|
||||
|
||||
// Extractor writes only payload/ contents from a pre-verified package ZIP.
|
||||
type Extractor struct {
|
||||
limits Limits
|
||||
limits Limits
|
||||
durability durabilityFence
|
||||
}
|
||||
|
||||
type ExtractResult struct {
|
||||
@@ -56,7 +57,7 @@ func NewExtractor(limits Limits) (Extractor, error) {
|
||||
if err := limits.validate(); err != nil {
|
||||
return Extractor{}, err
|
||||
}
|
||||
return Extractor{limits: limits}, nil
|
||||
return Extractor{limits: limits, durability: defaultDurability()}, nil
|
||||
}
|
||||
|
||||
// ExtractFile requires expectedPackageSize from the verified Catalog package.
|
||||
@@ -88,6 +89,7 @@ func (extractor Extractor) extract(
|
||||
if err := extractor.limits.validate(); err != nil {
|
||||
return ExtractResult{}, err
|
||||
}
|
||||
fence := effectiveDurability(extractor.durability)
|
||||
normalizedEntrypoint, err := normalizeEntrypoint(entrypoint)
|
||||
if err != nil {
|
||||
return ExtractResult{}, err
|
||||
@@ -160,21 +162,21 @@ func (extractor Extractor) extract(
|
||||
readLimit++
|
||||
}
|
||||
copied, copyErr := io.Copy(output, io.LimitReader(source, readLimit))
|
||||
closeOutputErr := output.Close()
|
||||
closeSourceErr := source.Close()
|
||||
if copyErr != nil {
|
||||
_ = output.Close()
|
||||
return ExtractResult{}, fmt.Errorf("%w: read %s: %v", ErrArchiveCorrupt, entry.archivePath, copyErr)
|
||||
}
|
||||
if closeOutputErr != nil {
|
||||
return ExtractResult{}, fmt.Errorf("close staging file: %w", closeOutputErr)
|
||||
}
|
||||
if closeSourceErr != nil {
|
||||
_ = output.Close()
|
||||
return ExtractResult{}, fmt.Errorf("%w: close %s: %v", ErrArchiveCorrupt, entry.archivePath, closeSourceErr)
|
||||
}
|
||||
if copied > remaining {
|
||||
_ = output.Close()
|
||||
return ExtractResult{}, ErrExpandedTooLarge
|
||||
}
|
||||
if uint64(copied) != entry.file.UncompressedSize64 {
|
||||
_ = output.Close()
|
||||
return ExtractResult{}, fmt.Errorf(
|
||||
"%w: %s expanded to %d bytes, header declares %d",
|
||||
ErrArchiveCorrupt,
|
||||
@@ -183,9 +185,19 @@ func (extractor Extractor) extract(
|
||||
entry.file.UncompressedSize64,
|
||||
)
|
||||
}
|
||||
if err := syncFileWithFence(fence, output, "staging payload"); err != nil {
|
||||
_ = output.Close()
|
||||
return ExtractResult{}, err
|
||||
}
|
||||
if err := output.Close(); err != nil {
|
||||
return ExtractResult{}, fmt.Errorf("close staging file: %w", err)
|
||||
}
|
||||
written += copied
|
||||
result.Files++
|
||||
}
|
||||
if err := syncStagingTree(fence, destinationRoot); err != nil {
|
||||
return ExtractResult{}, err
|
||||
}
|
||||
|
||||
result.Bytes = written
|
||||
result.EntrypointPath = entrypointPath
|
||||
|
||||
Reference in New Issue
Block a user