Skip to content

Commit 57fccac

Browse files
authored
Merge pull request #9 from AkihiroSuda/dev
go-qcow2reader-example: add zstd
2 parents 628b8f1 + a805272 commit 57fccac

File tree

6 files changed

+67
-4
lines changed

6 files changed

+67
-4
lines changed

.github/dependabot.yml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
version: 2
2+
updates:
3+
- package-ecosystem: gomod
4+
directory: "/"
5+
schedule:
6+
interval: daily
7+
open-pull-requests-limit: 10
8+
reviewers:
9+
- AkihiroSuda
10+
- package-ecosystem: github-actions
11+
directory: "/"
12+
schedule:
13+
interval: daily
14+
open-pull-requests-limit: 10
15+
reviewers:
16+
- AkihiroSuda

.github/workflows/test.yml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
name: test
22
on:
33
push:
4+
branches:
5+
- master
46
pull_request:
57
jobs:
68
integration:
@@ -21,7 +23,7 @@ jobs:
2123
- name: Unit tests
2224
run: go test -v ./...
2325
- name: Install go-qcow2reader-example
24-
run: go install ./cmd/go-qcow2reader-example
26+
run: cd ./cmd/go-qcow2reader-example && go install
2527
- name: Install qemu-img as a test dependency
2628
run: |
2729
sudo apt-get update
@@ -43,9 +45,13 @@ jobs:
4345
# Create a child image, with a custom size
4446
qemu-img create -f qcow2 -b debian-11-genericcloud-amd64-20230501-1367.qcow2 -F qcow2 debian-11-genericcloud-amd64-20230501-1367.child_4G.qcow2 4G
4547
# TODO: write something to the child image (with qemu-nbd?)
48+
# Convert to zstd
49+
qemu-img convert -f qcow2 -O qcow2 -o compression_type=zstd debian-11-genericcloud-amd64-20230501-1367.qcow2 debian-11-genericcloud-amd64-20230501-1367.zstd.qcow2
4650
- name: Prepare test-images
4751
run: cp -a test-images-ro test-images
4852
- name: "Test debian-11-genericcloud-amd64-20230501-1367.qcow2"
4953
run: hack/compare-with-qemu-img.sh test-images/debian-11-genericcloud-amd64-20230501-1367.qcow2
5054
- name: "Test debian-11-genericcloud-amd64-20230501-1367.child_4G.qcow2 (child image, with a custom size)"
5155
run: hack/compare-with-qemu-img.sh test-images/debian-11-genericcloud-amd64-20230501-1367.child_4G.qcow2
56+
- name: "Test debian-11-genericcloud-amd64-20230501-1367.zstd.qcow2"
57+
run: hack/compare-with-qemu-img.sh test-images/debian-11-genericcloud-amd64-20230501-1367.zstd.qcow2

cmd/go-qcow2reader-example/go.mod

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
module github.com/lima-vm/go-qcow2reader/cmd/go-qcow2reader-example
2+
3+
go 1.20
4+
5+
require (
6+
github.com/klauspost/compress v1.16.5
7+
github.com/lima-vm/go-qcow2reader v0.0.0-00010101000000-000000000000
8+
)
9+
10+
replace github.com/lima-vm/go-qcow2reader => ../../

cmd/go-qcow2reader-example/go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
github.com/klauspost/compress v1.16.5 h1:IFV2oUNUzZaz+XyusxpLzpzS8Pt5rh0Z16For/djlyI=
2+
github.com/klauspost/compress v1.16.5/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=

cmd/go-qcow2reader-example/main.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,10 @@ import (
88
"io"
99
"os"
1010

11+
"github.com/klauspost/compress/zstd"
1112
"github.com/lima-vm/go-qcow2reader"
1213
"github.com/lima-vm/go-qcow2reader/image"
14+
"github.com/lima-vm/go-qcow2reader/image/qcow2"
1315
"github.com/lima-vm/go-qcow2reader/log"
1416
)
1517

@@ -21,8 +23,29 @@ func debugPrint(s string) {
2123
fmt.Fprintln(os.Stderr, "DEBUG: "+s)
2224
}
2325

26+
type zstdDecompressor struct {
27+
*zstd.Decoder
28+
}
29+
30+
func (x *zstdDecompressor) Close() error {
31+
x.Decoder.Close()
32+
return nil
33+
}
34+
35+
func newZstdDecompressor(r io.Reader) (io.ReadCloser, error) {
36+
dec, err := zstd.NewReader(r)
37+
if err != nil {
38+
return nil, err
39+
}
40+
return &zstdDecompressor{dec}, nil
41+
}
42+
2443
func main() {
2544
log.SetWarnFunc(warn)
45+
46+
// zlib (deflate) decompressor is registered by default, but zstd is not.
47+
qcow2.SetDecompressor(qcow2.CompressionTypeZstd, newZstdDecompressor)
48+
2649
if err := xmain(); err != nil {
2750
fmt.Fprintln(os.Stderr, "ERROR: "+err.Error())
2851
os.Exit(1)

image/qcow2/qcow2.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -184,10 +184,13 @@ func (x CompressionType) MarshalText() ([]byte, error) {
184184
return []byte(x.String()), nil
185185
}
186186

187-
type Decompressor func(r io.Reader) io.ReadCloser
187+
type Decompressor func(r io.Reader) (io.ReadCloser, error)
188188

189189
var decompressors = map[CompressionType]Decompressor{
190-
CompressionTypeZlib: flate.NewReader, // no zlib header
190+
// no zlib header
191+
CompressionTypeZlib: func(r io.Reader) (io.ReadCloser, error) {
192+
return flate.NewReader(r), nil
193+
},
191194
}
192195

193196
// SetDecompressor sets a custom decompressor.
@@ -749,7 +752,10 @@ func (img *Qcow2) readAtAlignedCompressed(p []byte, off int64, desc compressedCl
749752
additionalSectors := desc.additionalSectors(int(img.Header.ClusterBits))
750753
compressedSize := img.clusterSize + 512*additionalSectors
751754
compressedSR := io.NewSectionReader(img.ra, int64(hostClusterOffset), int64(compressedSize))
752-
zr := img.decompressor(compressedSR)
755+
zr, err := img.decompressor(compressedSR)
756+
if err != nil {
757+
return 0, fmt.Errorf("could not open the decompressor: %w", err)
758+
}
753759
defer zr.Close()
754760
if discard := off % int64(img.clusterSize); discard != 0 {
755761
if _, err := io.CopyN(io.Discard, zr, discard); err != nil {

0 commit comments

Comments
 (0)