mirror of
https://github.com/apricote/hcloud-upload-image.git
synced 2026-05-12 15:36:15 +02:00
Some checks failed
ci / lint (push) Has been cancelled
ci / test (push) Has been cancelled
ci / go-mod-tidy (push) Has been cancelled
ci / cli-help-pages (push) Has been cancelled
ci / nix-build (push) Has been cancelled
docs / deploy (push) Has been cancelled
release-please / release-please (push) Has been cancelled
By default `dd` writes all bytes from raw images 1:1 to the disk. Some images, like Flatcar, have a lot of zero blocks in them. They have a large partition table with 1GB for the UEFI partition, 2GB for system A and B each, another 1GB for OEM and 6GB for the user. Most of these are just zero blocks, but we currently still write them to disk. By using `dd conv=sparse`, dd automatically skips writing these blocks to the disk, which results in a quicker process, as fewer bytes need to be written. The resulting image is the same, as "zero" is also the default for the blocks after our `blkdiscard` command. I did not benchmark this properly, so you have to trust me on this one.
126 lines
3.4 KiB
Go
126 lines
3.4 KiB
Go
package hcloudimages
|
|
|
|
import (
|
|
"net/url"
|
|
"testing"
|
|
)
|
|
|
|
func mustParseURL(s string) *url.URL {
|
|
u, err := url.Parse(s)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
return u
|
|
}
|
|
|
|
func TestAssembleCommand(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
options UploadOptions
|
|
want string
|
|
wantErr bool
|
|
}{
|
|
{
|
|
name: "local raw",
|
|
options: UploadOptions{},
|
|
want: "bash -c 'set -euo pipefail && dd of=/dev/sda bs=4M conv=sparse && sync'",
|
|
},
|
|
{
|
|
name: "remote raw",
|
|
options: UploadOptions{
|
|
ImageURL: mustParseURL("https://example.com/image.xz"),
|
|
},
|
|
want: "bash -c 'set -euo pipefail && wget --no-verbose -O - \"https://example.com/image.xz\" | dd of=/dev/sda bs=4M conv=sparse && sync'",
|
|
},
|
|
{
|
|
name: "local xz",
|
|
options: UploadOptions{
|
|
ImageCompression: CompressionXZ,
|
|
},
|
|
want: "bash -c 'set -euo pipefail && xz -cd | dd of=/dev/sda bs=4M conv=sparse && sync'",
|
|
},
|
|
{
|
|
name: "remote xz",
|
|
options: UploadOptions{
|
|
ImageURL: mustParseURL("https://example.com/image.xz"),
|
|
ImageCompression: CompressionXZ,
|
|
},
|
|
want: "bash -c 'set -euo pipefail && wget --no-verbose -O - \"https://example.com/image.xz\" | xz -cd | dd of=/dev/sda bs=4M conv=sparse && sync'",
|
|
},
|
|
{
|
|
name: "local zstd",
|
|
options: UploadOptions{
|
|
ImageCompression: CompressionZSTD,
|
|
},
|
|
want: "bash -c 'set -euo pipefail && zstd -cd | dd of=/dev/sda bs=4M conv=sparse && sync'",
|
|
},
|
|
{
|
|
name: "remote zstd",
|
|
options: UploadOptions{
|
|
ImageURL: mustParseURL("https://example.com/image.zst"),
|
|
ImageCompression: CompressionZSTD,
|
|
},
|
|
want: "bash -c 'set -euo pipefail && wget --no-verbose -O - \"https://example.com/image.zst\" | zstd -cd | dd of=/dev/sda bs=4M conv=sparse && sync'",
|
|
},
|
|
{
|
|
name: "local bz2",
|
|
options: UploadOptions{
|
|
ImageCompression: CompressionBZ2,
|
|
},
|
|
want: "bash -c 'set -euo pipefail && bzip2 -cd | dd of=/dev/sda bs=4M conv=sparse && sync'",
|
|
},
|
|
{
|
|
name: "remote bz2",
|
|
options: UploadOptions{
|
|
ImageURL: mustParseURL("https://example.com/image.bz2"),
|
|
ImageCompression: CompressionBZ2,
|
|
},
|
|
want: "bash -c 'set -euo pipefail && wget --no-verbose -O - \"https://example.com/image.bz2\" | bzip2 -cd | dd of=/dev/sda bs=4M conv=sparse && sync'",
|
|
},
|
|
{
|
|
name: "local qcow2",
|
|
options: UploadOptions{
|
|
ImageFormat: FormatQCOW2,
|
|
},
|
|
want: "bash -c 'set -euo pipefail && tee image.qcow2 > /dev/null && qemu-img dd -f qcow2 -O raw if=image.qcow2 of=/dev/sda bs=4M && sync'",
|
|
},
|
|
{
|
|
name: "remote qcow2",
|
|
options: UploadOptions{
|
|
ImageURL: mustParseURL("https://example.com/image.qcow2"),
|
|
ImageFormat: FormatQCOW2,
|
|
},
|
|
want: "bash -c 'set -euo pipefail && wget --no-verbose -O - \"https://example.com/image.qcow2\" | tee image.qcow2 > /dev/null && qemu-img dd -f qcow2 -O raw if=image.qcow2 of=/dev/sda bs=4M && sync'",
|
|
},
|
|
|
|
{
|
|
name: "unknown compression",
|
|
options: UploadOptions{
|
|
ImageCompression: "noodle",
|
|
},
|
|
wantErr: true,
|
|
},
|
|
|
|
{
|
|
name: "unknown format",
|
|
options: UploadOptions{
|
|
ImageFormat: "poodle",
|
|
},
|
|
wantErr: true,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
got, err := assembleCommand(tt.options)
|
|
if (err != nil) != tt.wantErr {
|
|
t.Errorf("assembleCommand() error = %v, wantErr %v", err, tt.wantErr)
|
|
return
|
|
}
|
|
if got != tt.want {
|
|
t.Errorf("assembleCommand() got = %v, want %v", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|