diff --git a/.github/release-please-manifest.json b/.github/release-please-manifest.json index 2b6f241..db709a3 100644 --- a/.github/release-please-manifest.json +++ b/.github/release-please-manifest.json @@ -1 +1 @@ -{".":"1.1.0","hcloudimages":"1.1.0"} +{".":"1.0.0","hcloudimages":"1.0.0"} diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 78b427c..124abc4 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -18,15 +18,15 @@ jobs: go-version-file: go.mod - name: Run golangci-lint (CLI) - uses: golangci/golangci-lint-action@v8 + uses: golangci/golangci-lint-action@v7 with: - version: v2.1.6 # renovate: datasource=github-releases depName=golangci/golangci-lint + version: v2.1.5 # renovate: datasource=github-releases depName=golangci/golangci-lint args: --timeout 5m - name: Run golangci-lint (Lib) - uses: golangci/golangci-lint-action@v8 + uses: golangci/golangci-lint-action@v7 with: - version: v2.1.6 # renovate: datasource=github-releases depName=golangci/golangci-lint + version: v2.1.5 # renovate: datasource=github-releases depName=golangci/golangci-lint args: --timeout 5m working-directory: hcloudimages diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index f8d6e93..5d7bc55 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -19,7 +19,7 @@ jobs: - uses: ./.github/actions/setup-mdbook with: - version: v0.4.49 # renovate: datasource=github-releases depName=rust-lang/mdbook + version: v0.4.48 # renovate: datasource=github-releases depName=rust-lang/mdbook - name: Build Book working-directory: docs diff --git a/CHANGELOG.md b/CHANGELOG.md index e0ca817..c9c3fe4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,24 +1,5 @@ # Changelog -## [1.1.0](https://github.com/apricote/hcloud-upload-image/compare/v1.0.1...v1.1.0) (2025-05-10) - - -### Features - -* smaller snapshots by zeroing disk first ([#101](https://github.com/apricote/hcloud-upload-image/issues/101)) ([fdfb284](https://github.com/apricote/hcloud-upload-image/commit/fdfb284533d3154806b0936c08015fd5cc64b0fb)), closes [#96](https://github.com/apricote/hcloud-upload-image/issues/96) - - -### Bug Fixes - -* upload from local image generates broken command ([#98](https://github.com/apricote/hcloud-upload-image/issues/98)) ([420dcf9](https://github.com/apricote/hcloud-upload-image/commit/420dcf94c965ee470602db6c9c23c777fda91222)), closes [#97](https://github.com/apricote/hcloud-upload-image/issues/97) - -## [1.0.1](https://github.com/apricote/hcloud-upload-image/compare/v1.0.0...v1.0.1) (2025-05-09) - - -### Bug Fixes - -* timeout while waiting for SSH to become available ([#92](https://github.com/apricote/hcloud-upload-image/issues/92)) ([e490b9a](https://github.com/apricote/hcloud-upload-image/commit/e490b9a7f394e268fa1946ca51aa998c78c3d46a)) - ## [1.0.0](https://github.com/apricote/hcloud-upload-image/compare/v0.3.1...v1.0.0) (2025-05-04) diff --git a/cmd/root.go b/cmd/root.go index 98a25d3..86cfe89 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -9,6 +9,7 @@ import ( "github.com/spf13/cobra" "github.com/apricote/hcloud-upload-image/hcloudimages" + "github.com/apricote/hcloud-upload-image/hcloudimages/backoff" "github.com/apricote/hcloud-upload-image/hcloudimages/contextlogger" "github.com/apricote/hcloud-upload-image/internal/ui" "github.com/apricote/hcloud-upload-image/internal/version" @@ -88,7 +89,7 @@ func initClient(cmd *cobra.Command, _ []string) { opts := []hcloud.ClientOption{ hcloud.WithToken(os.Getenv("HCLOUD_TOKEN")), hcloud.WithApplication("hcloud-upload-image", version.Version), - hcloud.WithPollOpts(hcloud.PollOpts{BackoffFunc: hcloud.ExponentialBackoffWithOpts(hcloud.ExponentialBackoffOpts{Multiplier: 2, Base: 1 * time.Second, Cap: 30 * time.Second})}), + hcloud.WithPollOpts(hcloud.PollOpts{BackoffFunc: backoff.ExponentialBackoffWithLimit(2, 1*time.Second, 30*time.Second)}), } if os.Getenv("HCLOUD_DEBUG") != "" || verbose >= 2 { diff --git a/go.mod b/go.mod index 75c60bc..69de163 100644 --- a/go.mod +++ b/go.mod @@ -2,10 +2,10 @@ module github.com/apricote/hcloud-upload-image go 1.23.0 -toolchain go1.24.3 +toolchain go1.24.2 require ( - github.com/apricote/hcloud-upload-image/hcloudimages v1.1.0 + github.com/apricote/hcloud-upload-image/hcloudimages v1.0.0 github.com/hetznercloud/hcloud-go/v2 v2.21.0 github.com/spf13/cobra v1.9.1 ) diff --git a/go.sum b/go.sum index 6ca002d..3d020ac 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,5 @@ -github.com/apricote/hcloud-upload-image/hcloudimages v1.1.0 h1:1guW0IO2/070qbaP6zzNJJ8XsGLKPpxyE1W6fyf7MPc= -github.com/apricote/hcloud-upload-image/hcloudimages v1.1.0/go.mod h1:iJ95BaLfISZBY9X8K2Y2A5a49dI0RLjAuq+4BqlOSgA= +github.com/apricote/hcloud-upload-image/hcloudimages v1.0.0 h1:Gq0SSuPCiZFApGQ3SIEEQqD8btD6tRwfOxr+cky7oTo= +github.com/apricote/hcloud-upload-image/hcloudimages v1.0.0/go.mod h1:MwBmhSPlwS3S3ynOsFXPbco40Iv3udqhXKz2EXKSpVU= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= diff --git a/go.work.sum b/go.work.sum index a13bce8..1f0124a 100644 --- a/go.work.sum +++ b/go.work.sum @@ -3,7 +3,7 @@ github.com/alecthomas/kingpin/v2 v2.4.0 h1:f48lwail6p8zpO1bC4TxtqACaGqHYA22qkHjH github.com/alecthomas/kingpin/v2 v2.4.0/go.mod h1:0gyi0zQnjuFk8xrkNKamJoyUo382HRL7ATRpFZCw6tE= github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 h1:s6gZFSlWYmbqAuRjVTiNNhvNRfY2Wxp9nhfyel4rklc= github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= -github.com/apricote/hcloud-upload-image/hcloudimages v1.1.0/go.mod h1:iJ95BaLfISZBY9X8K2Y2A5a49dI0RLjAuq+4BqlOSgA= +github.com/apricote/hcloud-upload-image/hcloudimages v1.0.0/go.mod h1:MwBmhSPlwS3S3ynOsFXPbco40Iv3udqhXKz2EXKSpVU= github.com/cpuguy83/go-md2man/v2 v2.0.3 h1:qMCsGGgs+MAzDFyp9LpAe1Lqy/fY/qCovCm0qnXZOBM= github.com/creack/pty v1.1.9 h1:uDmaGzcdjhF4i/plgjmEsriH11Y0o7RKapEf/LDaM3w= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= diff --git a/hcloudimages/CHANGELOG.md b/hcloudimages/CHANGELOG.md index 3d7b6a0..076256f 100644 --- a/hcloudimages/CHANGELOG.md +++ b/hcloudimages/CHANGELOG.md @@ -1,24 +1,5 @@ # Changelog -## [1.1.0](https://github.com/apricote/hcloud-upload-image/compare/hcloudimages/v1.0.1...hcloudimages/v1.1.0) (2025-05-10) - - -### Features - -* smaller snapshots by zeroing disk first ([#101](https://github.com/apricote/hcloud-upload-image/issues/101)) ([fdfb284](https://github.com/apricote/hcloud-upload-image/commit/fdfb284533d3154806b0936c08015fd5cc64b0fb)), closes [#96](https://github.com/apricote/hcloud-upload-image/issues/96) - - -### Bug Fixes - -* upload from local image generates broken command ([#98](https://github.com/apricote/hcloud-upload-image/issues/98)) ([420dcf9](https://github.com/apricote/hcloud-upload-image/commit/420dcf94c965ee470602db6c9c23c777fda91222)), closes [#97](https://github.com/apricote/hcloud-upload-image/issues/97) - -## [1.0.1](https://github.com/apricote/hcloud-upload-image/compare/hcloudimages/v1.0.0...hcloudimages/v1.0.1) (2025-05-09) - - -### Bug Fixes - -* timeout while waiting for SSH to become available ([#92](https://github.com/apricote/hcloud-upload-image/issues/92)) ([e490b9a](https://github.com/apricote/hcloud-upload-image/commit/e490b9a7f394e268fa1946ca51aa998c78c3d46a)) - ## [1.0.0](https://github.com/apricote/hcloud-upload-image/compare/hcloudimages/v0.3.1...hcloudimages/v1.0.0) (2025-05-04) diff --git a/hcloudimages/backoff/backoff.go b/hcloudimages/backoff/backoff.go index 346fb8f..310312a 100644 --- a/hcloudimages/backoff/backoff.go +++ b/hcloudimages/backoff/backoff.go @@ -16,10 +16,6 @@ import ( // It uses the formula: // // min(b^retries * d, limit) -// -// This function has a known overflow issue and should not be used anymore. -// -// Deprecated: Use BackoffFuncWithOpts from github.com/hetznercloud/hcloud-go/v2/hcloud instead. func ExponentialBackoffWithLimit(b float64, d time.Duration, limit time.Duration) hcloud.BackoffFunc { return func(retries int) time.Duration { current := time.Duration(math.Pow(b, float64(retries))) * d diff --git a/hcloudimages/client.go b/hcloudimages/client.go index 9652854..62e218a 100644 --- a/hcloudimages/client.go +++ b/hcloudimages/client.go @@ -316,7 +316,7 @@ func (s *Client) Upload(ctx context.Context, options UploadOptions) (*hcloud.Ima err = control.Retry( contextlogger.New(ctx, logger.With("operation", "ssh")), - 100, // ~ 3 minutes + 10, func() error { var err error logger.DebugContext(ctx, "trying to connect to server", "ip", server.PublicNet.IPv4.IP) @@ -329,42 +329,55 @@ func (s *Client) Upload(ctx context.Context, options UploadOptions) (*hcloud.Ima } defer func() { _ = sshClient.Close() }() - // 6. Wipe existing disk, to avoid storing any bytes from it in the snapshot - logger.InfoContext(ctx, "# Step 6: Cleaning existing disk") - - output, err := sshsession.Run(sshClient, "blkdiscard /dev/sda", nil) - logger.DebugContext(ctx, string(output)) - if err != nil { - return nil, fmt.Errorf("failed to clean existing disk: %w", err) + // 6. SSH On Server: Download Image, Decompress, Write to Root Disk + logger.InfoContext(ctx, "# Step 6: Downloading image and writing to disk") + cmd := "" + if options.ImageURL != nil { + cmd += fmt.Sprintf("wget --no-verbose -O - %q", options.ImageURL.String()) } - // 7. SSH On Server: Download Image, Decompress, Write to Root Disk - logger.InfoContext(ctx, "# Step 7: Downloading image and writing to disk") - - cmd, err := assembleCommand(options) - if err != nil { - return nil, err + if options.ImageCompression != CompressionNone { + switch options.ImageCompression { + case CompressionBZ2: + cmd += " | bzip2 -cd" + case CompressionXZ: + cmd += " | xz -cd" + default: + return nil, fmt.Errorf("unknown compression: %q", options.ImageCompression) + } } + switch options.ImageFormat { + case FormatRaw: + cmd += " | dd of=/dev/sda bs=4M" + case FormatQCOW2: + cmd += " > image.qcow2 && qemu-img dd -f qcow2 -O raw if=image.qcow2 of=/dev/sda bs=4M" + } + + cmd += " && sync" + + // Make sure that we fail early, ie. if the image url does not work. + // the pipefail does not work correctly without wrapping in bash. + cmd = fmt.Sprintf("bash -c 'set -euo pipefail && %s'", cmd) logger.DebugContext(ctx, "running download, decompress and write to disk command", "cmd", cmd) - output, err = sshsession.Run(sshClient, cmd, options.ImageReader) - logger.InfoContext(ctx, "# Step 7: Finished writing image to disk") + output, err := sshsession.Run(sshClient, cmd, options.ImageReader) + logger.InfoContext(ctx, "# Step 6: Finished writing image to disk") logger.DebugContext(ctx, string(output)) if err != nil { return nil, fmt.Errorf("failed to download and write the image: %w", err) } - // 8. SSH On Server: Shutdown - logger.InfoContext(ctx, "# Step 8: Shutting down server") + // 7. SSH On Server: Shutdown + logger.InfoContext(ctx, "# Step 7: Shutting down server") _, err = sshsession.Run(sshClient, "shutdown now", nil) if err != nil { // TODO Verify if shutdown error, otherwise return logger.WarnContext(ctx, "shutdown returned error", "err", err) } - // 9. Create Image from Server - logger.InfoContext(ctx, "# Step 9: Creating Image") + // 8. Create Image from Server + logger.InfoContext(ctx, "# Step 8: Creating Image") createImageResult, _, err := s.c.Server.CreateImage(ctx, server, &hcloud.ServerCreateImageOpts{ Type: hcloud.ImageTypeSnapshot, Description: options.Description, @@ -509,39 +522,3 @@ func (s *Client) cleanupTempSSHKeys(ctx context.Context, logger *slog.Logger, se return nil } - -func assembleCommand(options UploadOptions) (string, error) { - // Make sure that we fail early, ie. if the image url does not work - cmd := "set -euo pipefail && " - - if options.ImageURL != nil { - cmd += fmt.Sprintf("wget --no-verbose -O - %q | ", options.ImageURL.String()) - } - - if options.ImageCompression != CompressionNone { - switch options.ImageCompression { - case CompressionBZ2: - cmd += "bzip2 -cd | " - case CompressionXZ: - cmd += "xz -cd | " - default: - return "", fmt.Errorf("unknown compression: %q", options.ImageCompression) - } - } - - switch options.ImageFormat { - case FormatRaw: - cmd += "dd of=/dev/sda bs=4M" - case FormatQCOW2: - cmd += "tee image.qcow2 > /dev/null && qemu-img dd -f qcow2 -O raw if=image.qcow2 of=/dev/sda bs=4M" - default: - return "", fmt.Errorf("unknown format: %q", options.ImageFormat) - } - - cmd += " && sync" - - // the pipefail does not work correctly without wrapping in bash. - cmd = fmt.Sprintf("bash -c '%s'", cmd) - - return cmd, nil -} diff --git a/hcloudimages/client_test.go b/hcloudimages/client_test.go index 86f8961..4905bdf 100644 --- a/hcloudimages/client_test.go +++ b/hcloudimages/client_test.go @@ -1,110 +1,33 @@ -package hcloudimages +package hcloudimages_test import ( + "context" + "fmt" "net/url" - "testing" + + "github.com/hetznercloud/hcloud-go/v2/hcloud" + + "github.com/apricote/hcloud-upload-image/hcloudimages" ) -func mustParseURL(s string) *url.URL { - u, err := url.Parse(s) +func ExampleClient_Upload() { + client := hcloudimages.NewClient( + hcloud.NewClient(hcloud.WithToken("")), + ) + + imageURL, err := url.Parse("https://example.com/disk-image.raw.bz2") 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 && 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 && sync'", - }, - { - name: "local xz", - options: UploadOptions{ - ImageCompression: CompressionXZ, - }, - want: "bash -c 'set -euo pipefail && xz -cd | dd of=/dev/sda bs=4M && 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 && sync'", - }, - { - name: "local bz2", - options: UploadOptions{ - ImageCompression: CompressionBZ2, - }, - want: "bash -c 'set -euo pipefail && bzip2 -cd | dd of=/dev/sda bs=4M && sync'", - }, - { - name: "remote bz2", - options: UploadOptions{ - ImageURL: mustParseURL("https://example.com/image.bz2"), - ImageCompression: CompressionXZ, - }, - want: "bash -c 'set -euo pipefail && wget --no-verbose -O - \"https://example.com/image.bz2\" | xz -cd | dd of=/dev/sda bs=4M && 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) - } - }) + image, err := client.Upload(context.TODO(), hcloudimages.UploadOptions{ + ImageURL: imageURL, + ImageCompression: hcloudimages.CompressionBZ2, + Architecture: hcloud.ArchitectureX86, + }) + if err != nil { + panic(err) } + + fmt.Printf("Uploaded Image: %d", image.ID) } diff --git a/hcloudimages/doc_test.go b/hcloudimages/doc_test.go deleted file mode 100644 index 4905bdf..0000000 --- a/hcloudimages/doc_test.go +++ /dev/null @@ -1,33 +0,0 @@ -package hcloudimages_test - -import ( - "context" - "fmt" - "net/url" - - "github.com/hetznercloud/hcloud-go/v2/hcloud" - - "github.com/apricote/hcloud-upload-image/hcloudimages" -) - -func ExampleClient_Upload() { - client := hcloudimages.NewClient( - hcloud.NewClient(hcloud.WithToken("")), - ) - - imageURL, err := url.Parse("https://example.com/disk-image.raw.bz2") - if err != nil { - panic(err) - } - - image, err := client.Upload(context.TODO(), hcloudimages.UploadOptions{ - ImageURL: imageURL, - ImageCompression: hcloudimages.CompressionBZ2, - Architecture: hcloud.ArchitectureX86, - }) - if err != nil { - panic(err) - } - - fmt.Printf("Uploaded Image: %d", image.ID) -} diff --git a/hcloudimages/go.mod b/hcloudimages/go.mod index a1f6792..fbcfa83 100644 --- a/hcloudimages/go.mod +++ b/hcloudimages/go.mod @@ -2,12 +2,12 @@ module github.com/apricote/hcloud-upload-image/hcloudimages go 1.23.0 -toolchain go1.24.3 +toolchain go1.24.2 require ( github.com/hetznercloud/hcloud-go/v2 v2.21.0 github.com/stretchr/testify v1.10.0 - golang.org/x/crypto v0.39.0 + golang.org/x/crypto v0.38.0 ) require ( @@ -23,7 +23,7 @@ require ( github.com/prometheus/procfs v0.15.1 // indirect golang.org/x/net v0.38.0 // indirect golang.org/x/sys v0.33.0 // indirect - golang.org/x/text v0.26.0 // indirect + golang.org/x/text v0.25.0 // indirect google.golang.org/protobuf v1.36.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/hcloudimages/go.sum b/hcloudimages/go.sum index 8540767..6507380 100644 --- a/hcloudimages/go.sum +++ b/hcloudimages/go.sum @@ -32,16 +32,16 @@ github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDN github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -golang.org/x/crypto v0.39.0 h1:SHs+kF4LP+f+p14esP5jAoDpHU8Gu/v9lFRK6IT5imM= -golang.org/x/crypto v0.39.0/go.mod h1:L+Xg3Wf6HoL4Bn4238Z6ft6KfEpN0tJGo53AAPC632U= +golang.org/x/crypto v0.38.0 h1:jt+WWG8IZlBnVbomuhg2Mdq0+BBQaHbtqHEFEigjUV8= +golang.org/x/crypto v0.38.0/go.mod h1:MvrbAqul58NNYPKnOra203SB9vpuZW0e+RRZV+Ggqjw= golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8= golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw= golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/term v0.32.0 h1:DR4lr0TjUs3epypdhTOkMmuF5CDFJ/8pOnbzMZPQ7bg= golang.org/x/term v0.32.0/go.mod h1:uZG1FhGx848Sqfsq4/DlJr3xGGsYMu/L5GW4abiaEPQ= -golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M= -golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA= +golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4= +golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA= google.golang.org/protobuf v1.36.1 h1:yBPeRvTftaleIgM3PZ/WBIZ7XM/eEYAaEyCwvyjq/gk= google.golang.org/protobuf v1.36.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/hcloudimages/internal/control/retry.go b/hcloudimages/internal/control/retry.go index 44cfe55..eb56721 100644 --- a/hcloudimages/internal/control/retry.go +++ b/hcloudimages/internal/control/retry.go @@ -8,8 +8,7 @@ import ( "context" "time" - "github.com/hetznercloud/hcloud-go/v2/hcloud" - + "github.com/apricote/hcloud-upload-image/hcloudimages/backoff" "github.com/apricote/hcloud-upload-image/hcloudimages/contextlogger" ) @@ -19,7 +18,7 @@ func Retry(ctx context.Context, maxTries int, f func() error) error { var err error - backoffFunc := hcloud.ExponentialBackoffWithOpts(hcloud.ExponentialBackoffOpts{Multiplier: 2, Base: 200 * time.Millisecond, Cap: 2 * time.Second}) + backoffFunc := backoff.ExponentialBackoffWithLimit(2, 200*time.Millisecond, 2*time.Second) for try := 0; try < maxTries; try++ { if ctx.Err() != nil { diff --git a/internal/version/version.go b/internal/version/version.go index f8df129..5d6e08f 100644 --- a/internal/version/version.go +++ b/internal/version/version.go @@ -2,7 +2,7 @@ package version var ( // version is a semver version (https://semver.org). - version = "1.1.0" // x-release-please-version + version = "1.0.0" // x-release-please-version // versionPrerelease is a semver version pre-release identifier (https://semver.org). //