Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package hcloud-upload-image for
openSUSE:Factory checked in at 2025-05-12 16:47:56
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/hcloud-upload-image (Old)
and /work/SRC/openSUSE:Factory/.hcloud-upload-image.new.30101 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "hcloud-upload-image"
Mon May 12 16:47:56 2025 rev:3 rq:1276488 version:1.1.0
Changes:
--------
--- /work/SRC/openSUSE:Factory/hcloud-upload-image/hcloud-upload-image.changes
2024-12-09 21:12:32.035381634 +0100
+++
/work/SRC/openSUSE:Factory/.hcloud-upload-image.new.30101/hcloud-upload-image.changes
2025-05-12 16:51:24.887060098 +0200
@@ -1,0 +2,93 @@
+Sat May 10 14:46:53 UTC 2025 - Johannes Kastl
<[email protected]>
+
+- Update to version 1.1.0:
+ * Highlights
+ - Smaller Snapshots
+ The root disk is now zeroed before the intend image is
+ uploaded. This makes sure, that no bytes from the original
+ image are stored in the compressed snapshot. Previously a
+ very small uploaded image could not be smaller than ~0.42Gi,
+ as that was the (compressed) size of image that the server
+ was started with. Starting a server from a custom image is
+ slower the larger the image is, so by having smaller images
+ the servers can start faster.
+ As one example: The test Talos Linux 1.10.1 x86 image was
+ 0.42Gi before, and now only takes up 0.2Gi.
+ This only benefits images that are smaller than 0.42Gi
+ compressed.
+ * Features
+ - smaller snapshots by zeroing disk first (#101) (fdfb284),
+ closes #96
+ * Bug Fixes
+ - upload from local image generates broken command (#98)
+ (420dcf9), closes #97
+
+-------------------------------------------------------------------
+Sat May 10 09:02:35 UTC 2025 - Johannes Kastl
<[email protected]>
+
+- Update to version 1.0.1:
+ * Bug Fixes
+ - timeout while waiting for SSH to become available (#92)
+ (e490b9a)
+ * Dependencies
+ - chore(deps): update module
+ github.com/apricote/hcloud-upload-image/hcloudimages to
+ v1.0.1 (#95)
+ - chore(deps): update golangci/golangci-lint-action action to
+ v8 (#86)
+ - chore(deps): update dependency golangci/golangci-lint to
+ v2.1.6 (#85)
+ - chore(deps): update dependency rust-lang/mdbook to v0.4.49
+ (#87)
+ - chore(deps): update dependency go to v1.24.3 (#91)
+
+-------------------------------------------------------------------
+Sat May 10 08:49:27 UTC 2025 - Johannes Kastl
<[email protected]>
+
+- Update to version 1.0.0:
+ * Highlights
+ - Upload qcow2 images
+ qcow2 images with a max size of 960 MB can now be uploaded.
+ hcloud-upload-image upload --format=qcow2
+ --architecture=x86
+
--image-url=https://download.opensuse.org/tumbleweed/appliances/openSUSE-MicroOS.x86_64-OpenStack-Cloud.qcow2
+ These will be converted to a raw disk image on the temporary
+ server with qemu-img dd.
+ - Container image
+ There is now a pre-built container image available at
+ ghcr.io/apricote/hcloud-upload-image that you can use to run
+ the command instead of installing it.
+ - Docs Website
+ You can now enjoy the same old docs in a new dress published
+ to a website: https://apricote.github.io/hcloud-upload-image/
+ * Features
+ - deps: require Go 1.23 (#70) (f3fcb62)
+ - docs website (#80) (d144b85)
+ - publish container image (#82) (91df729)
+ - upload qcow2 images (#69) (ac3e9dd)
+ * Dependencies
+ - chore(deps): update module
+ github.com/apricote/hcloud-upload-image/hcloudimages to
+ v1.0.0 (#84)
+ - chore(deps): update docker/login-action digest to 6d4b68b
+ (#83)
+ - chore(deps): update dependency rust-lang/mdbook to v0.4.48
+ (#81)
+ - chore(deps): update module golang.org/x/crypto to v0.37.0
+ (#72)
+ - chore(renovate): make sure to bump dependencies in lib too
+ (#74)
+ - chore(deps): update dependency golangci/golangci-lint to v2
+ (#66)
+ - chore(config): migrate renovate config (#73)
+ - chore(deps): update module golang.org/x/net to v0.38.0
+ [security] (#63)
+ - chore(deps): update module
+ github.com/hetznercloud/hcloud-go/v2 to v2.21.0 (#62)
+ - chore(deps): update dependency golangci/golangci-lint to
+ v1.64.8 (#64)
+ - chore(deps): update module github.com/spf13/cobra to v1.9.1
+ (#65)
+ - feat(deps): require Go 1.23 (#70)
+
+-------------------------------------------------------------------
Old:
----
hcloud-upload-image-0.3.1.obscpio
New:
----
hcloud-upload-image-1.1.0.obscpio
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ hcloud-upload-image.spec ++++++
--- /var/tmp/diff_new_pack.9Zo9Y9/_old 2025-05-12 16:51:25.507086212 +0200
+++ /var/tmp/diff_new_pack.9Zo9Y9/_new 2025-05-12 16:51:25.507086212 +0200
@@ -1,7 +1,7 @@
#
# spec file for package hcloud-upload-image
#
-# Copyright (c) 2024 SUSE LLC
+# Copyright (c) 2025 SUSE LLC
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -17,7 +17,7 @@
Name: hcloud-upload-image
-Version: 0.3.1
+Version: 1.1.0
Release: 0
Summary: Quickly upload any raw disk images into your Hetzner Cloud
projects
License: MIT
@@ -26,8 +26,8 @@
Source1: vendor.tar.gz
BuildRequires: bash-completion
BuildRequires: fish
-BuildRequires: go >= 1.22
BuildRequires: zsh
+BuildRequires: golang(API) >= 1.24
%description
Quickly upload any raw disk images into your Hetzner Cloud projects!
++++++ _service ++++++
--- /var/tmp/diff_new_pack.9Zo9Y9/_old 2025-05-12 16:51:25.555088234 +0200
+++ /var/tmp/diff_new_pack.9Zo9Y9/_new 2025-05-12 16:51:25.555088234 +0200
@@ -5,7 +5,7 @@
<param name="exclude">.git</param>
<param name="exclude">go.work</param>
<param name="exclude">go.work.sum</param>
- <param name="revision">v0.3.1</param>
+ <param name="revision">v1.1.0</param>
<param name="match-tag">v*</param>
<param name="versionformat">@PARENT_TAG@</param>
<param name="versionrewrite-pattern">v(.*)</param>
++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.9Zo9Y9/_old 2025-05-12 16:51:25.575089077 +0200
+++ /var/tmp/diff_new_pack.9Zo9Y9/_new 2025-05-12 16:51:25.579089245 +0200
@@ -1,6 +1,6 @@
<servicedata>
<service name="tar_scm">
<param
name="url">https://github.com/apricote/hcloud-upload-image/</param>
- <param
name="changesrevision">b328867f6b9b965dcd581cb6f6907dae364faa7a</param></service></servicedata>
+ <param
name="changesrevision">b9af8855d5c0c1e40ddfaa670296731b2ed0c53e</param></service></servicedata>
(No newline at EOF)
++++++ hcloud-upload-image-0.3.1.obscpio -> hcloud-upload-image-1.1.0.obscpio
++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/hcloud-upload-image-0.3.1/.github/release-please-config.json
new/hcloud-upload-image-1.1.0/.github/release-please-config.json
--- old/hcloud-upload-image-0.3.1/.github/release-please-config.json
2024-12-07 01:57:59.000000000 +0100
+++ new/hcloud-upload-image-1.1.0/.github/release-please-config.json
1970-01-01 01:00:00.000000000 +0100
@@ -1,29 +0,0 @@
-{
- "$schema":
"https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json",
- "include-component-in-tag": false,
- "include-v-in-tag": true,
- "release-type": "go",
- "group-pull-request-title-pattern": "chore(${branch}): release ${version}",
- "packages": {
- ".": {
- "component": "cli",
- "package-name": "hcloud-upload-image",
- "extra-files": ["internal/version/version.go"]
- },
- "hcloudimages": {
- "component": "hcloudimages",
- "package-name": "hcloudimages",
- "include-component-in-tag": true,
- "tag-separator": "/"
- }
- },
- "plugins": [
- {
- "type": "linked-versions",
- "groupName": "repo",
- "components": [
- "cli", "hcloudimages"
- ]
- }
- ]
-}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/hcloud-upload-image-0.3.1/.github/release-please-manifest.json
new/hcloud-upload-image-1.1.0/.github/release-please-manifest.json
--- old/hcloud-upload-image-0.3.1/.github/release-please-manifest.json
2024-12-07 01:57:59.000000000 +0100
+++ new/hcloud-upload-image-1.1.0/.github/release-please-manifest.json
1970-01-01 01:00:00.000000000 +0100
@@ -1 +0,0 @@
-{".":"0.3.1","hcloudimages":"0.3.1"}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/hcloud-upload-image-0.3.1/.github/workflows/ci.yaml
new/hcloud-upload-image-1.1.0/.github/workflows/ci.yaml
--- old/hcloud-upload-image-0.3.1/.github/workflows/ci.yaml 2024-12-07
01:57:59.000000000 +0100
+++ new/hcloud-upload-image-1.1.0/.github/workflows/ci.yaml 1970-01-01
01:00:00.000000000 +0100
@@ -1,85 +0,0 @@
-name: ci
-
-on:
- push:
- branches: [main]
- pull_request:
-
-jobs:
- lint:
- runs-on: ubuntu-latest
- steps:
- - name: Checkout
- uses: actions/checkout@v4
-
- - name: Set up Go
- uses: actions/setup-go@v5
- with:
- go-version-file: go.mod
-
- - name: Run golangci-lint (CLI)
- uses: golangci/golangci-lint-action@v6
- with:
- version: v1.62.2 # renovate: datasource=github-releases
depName=golangci/golangci-lint
- args: --timeout 5m
-
- - name: Run golangci-lint (Lib)
- uses: golangci/golangci-lint-action@v6
- with:
- version: v1.62.2 # renovate: datasource=github-releases
depName=golangci/golangci-lint
- args: --timeout 5m
- working-directory: hcloudimages
-
- test:
- runs-on: ubuntu-latest
- steps:
- - name: Checkout
- uses: actions/checkout@v4
-
- - name: Set up Go
- uses: actions/setup-go@v5
- with:
- go-version-file: go.mod
-
- - name: Run tests
- run: go test -v -race -coverpkg=./...,./hcloudimages/... ./...
./hcloudimages/...
-
- go-mod-tidy:
- runs-on: ubuntu-latest
- steps:
- - name: Checkout
- uses: actions/checkout@v4
-
- - name: Set up Go
- uses: actions/setup-go@v5
- with:
- go-version-file: go.mod
-
- - name: Run go mod tidy
- run: go mod tidy
-
- - name: Check uncommitted changes
- run: git diff --exit-code
-
- - if: failure()
- run: echo "::error::Check failed, please run 'go mod tidy' and commit
the changes."
-
- cli-help-pages:
- runs-on: ubuntu-latest
- steps:
- - name: Checkout
- uses: actions/checkout@v4
-
- - name: Set up Go
- uses: actions/setup-go@v5
- with:
- go-version-file: go.mod
-
- - name: Generate CLI help pages
- run: go run ./scripts/cli-help-pages.go
-
- - name: Check uncommitted changes
- run: git diff --exit-code
-
- - if: failure()
- run: echo "::error::Check failed, please run 'go run
./scripts/cli-help-pages.go' and commit the changes."
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/hcloud-upload-image-0.3.1/.github/workflows/release-please.yaml
new/hcloud-upload-image-1.1.0/.github/workflows/release-please.yaml
--- old/hcloud-upload-image-0.3.1/.github/workflows/release-please.yaml
2024-12-07 01:57:59.000000000 +0100
+++ new/hcloud-upload-image-1.1.0/.github/workflows/release-please.yaml
1970-01-01 01:00:00.000000000 +0100
@@ -1,18 +0,0 @@
-name: release-please
-
-on:
- push:
- branches: [main]
-
-jobs:
- release-please:
- # Do not run on forks.
- if: github.repository == 'apricote/hcloud-upload-image'
-
- runs-on: ubuntu-latest
- steps:
- - uses: googleapis/release-please-action@v4
- with:
- token: ${{ secrets.RELEASE_GH_TOKEN }}
- config-file: .github/release-please-config.json
- manifest-file: .github/release-please-manifest.json
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/hcloud-upload-image-0.3.1/.github/workflows/release.yaml
new/hcloud-upload-image-1.1.0/.github/workflows/release.yaml
--- old/hcloud-upload-image-0.3.1/.github/workflows/release.yaml
2024-12-07 01:57:59.000000000 +0100
+++ new/hcloud-upload-image-1.1.0/.github/workflows/release.yaml
1970-01-01 01:00:00.000000000 +0100
@@ -1,27 +0,0 @@
-name: release
-
-on:
- push:
- tags:
- - "v*.*.*"
-
-jobs:
- release:
- runs-on: ubuntu-latest
- steps:
- - name: Checkout
- uses: actions/checkout@v4
-
- - name: Set up Go
- uses: actions/setup-go@v5
- with:
- go-version-file: go.mod
-
- - name: Run GoReleaser
- uses: goreleaser/goreleaser-action@v6
- with:
- version: "~> v2"
- args: release --clean
- env:
- GITHUB_TOKEN: ${{ secrets.RELEASE_GH_TOKEN }}
- AUR_SSH_KEY: ${{ secrets.RELEASE_AUR_SSH_KEY }}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/hcloud-upload-image-0.3.1/.gitignore
new/hcloud-upload-image-1.1.0/.gitignore
--- old/hcloud-upload-image-0.3.1/.gitignore 2024-12-07 01:57:59.000000000
+0100
+++ new/hcloud-upload-image-1.1.0/.gitignore 1970-01-01 01:00:00.000000000
+0100
@@ -1,3 +0,0 @@
-
-dist/
-completions/
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/hcloud-upload-image-0.3.1/.goreleaser.yaml
new/hcloud-upload-image-1.1.0/.goreleaser.yaml
--- old/hcloud-upload-image-0.3.1/.goreleaser.yaml 2024-12-07
01:57:59.000000000 +0100
+++ new/hcloud-upload-image-1.1.0/.goreleaser.yaml 2025-05-10
14:27:47.000000000 +0200
@@ -7,7 +7,8 @@
- ./scripts/completions.sh
builds:
- - env:
+ - id: default
+ env:
- CGO_ENABLED=0
goos:
- linux
@@ -21,7 +22,7 @@
- -X {{ .ModulePath }}/internal/version.versionPrerelease=
archives:
- - format: tar.gz
+ - formats: [ "tar.gz" ]
# this name template makes the OS and Arch compatible with the results of
`uname`.
name_template: >-
{{ .ProjectName }}_
@@ -33,7 +34,7 @@
# use zip for windows archives
format_overrides:
- goos: windows
- format: zip
+ formats: [ "zip" ]
files:
- README.md
@@ -104,9 +105,23 @@
install -Dm644 "./completions/hcloud-upload-image.zsh"
"${pkgdir}/usr/share/zsh/site-functions/_hcloud-upload-image"
install -Dm644 "./completions/hcloud-upload-image.fish"
"${pkgdir}/usr/share/fish/vendor_completions.d/hcloud-upload-image.fish"
+kos:
+ - id: container-images
+ build: default
+ repositories:
+ - ghcr.io/apricote
+ platforms:
+ - linux/amd64
+ - linux/arm64
+ base_import_paths: true
+ labels:
+ org.opencontainers.image.source:
https://github.com/apricote/hcloud-upload-image
+ tags:
+ - latest
+ - "{{.Tag}}"
snapshot:
- name_template: "{{ .Version }}-dev+{{ .ShortCommit }}"
+ version_template: "{{ .Version }}-dev+{{ .ShortCommit }}"
changelog:
# Generated by release-please
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/hcloud-upload-image-0.3.1/CHANGELOG.md
new/hcloud-upload-image-1.1.0/CHANGELOG.md
--- old/hcloud-upload-image-0.3.1/CHANGELOG.md 2024-12-07 01:57:59.000000000
+0100
+++ new/hcloud-upload-image-1.1.0/CHANGELOG.md 2025-05-10 14:27:47.000000000
+0200
@@ -1,5 +1,34 @@
# 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)
+
+
+### Features
+
+* **deps:** require Go 1.23
([#70](https://github.com/apricote/hcloud-upload-image/issues/70))
([f3fcb62](https://github.com/apricote/hcloud-upload-image/commit/f3fcb623fc00095ab3806fa41dbcb7083c13c5df))
+* docs website
([#80](https://github.com/apricote/hcloud-upload-image/issues/80))
([d144b85](https://github.com/apricote/hcloud-upload-image/commit/d144b85e3dfd933e8fbb09a0e6f5acacb4d05bea))
+* publish container image
([#82](https://github.com/apricote/hcloud-upload-image/issues/82))
([91df729](https://github.com/apricote/hcloud-upload-image/commit/91df729f1cfd636355fc8338f47aefa4ab8b3b84))
+* upload qcow2 images
([#69](https://github.com/apricote/hcloud-upload-image/issues/69))
([ac3e9dd](https://github.com/apricote/hcloud-upload-image/commit/ac3e9dd7ecd86d1538b6401c3073c7c078c40847))
+
##
[0.3.1](https://github.com/apricote/hcloud-upload-image/compare/v0.3.0...v0.3.1)
(2024-12-07)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/hcloud-upload-image-0.3.1/README.md
new/hcloud-upload-image-1.1.0/README.md
--- old/hcloud-upload-image-0.3.1/README.md 2024-12-07 01:57:59.000000000
+0100
+++ new/hcloud-upload-image-1.1.0/README.md 2025-05-10 14:27:47.000000000
+0200
@@ -1,6 +1,15 @@
# `hcloud-upload-image`
-Quickly upload any raw disk images into your [Hetzner
Cloud](https://hetzner.com/cloud) projects!
+<p align="center">
+ Quickly upload any raw disk images into your <a
href="https://hetzner.com/cloud" target="_blank">Hetzner Cloud</a> projects!
+</p>
+
+<p align="center">
+ <a href="https://apricote.github.io/hcloud-upload-image"
target="_blank"><img
src="https://img.shields.io/badge/Documentation-brightgreen?style=flat-square"
alt="Badge: Documentation"/></a>
+ <a href="https://github.com/apricote/hcloud-upload-image/releases"
target="_blank"><img
src="https://img.shields.io/github/v/release/apricote/hcloud-upload-image?sort=semver&display_name=release&style=flat-square&color=green"
alt="Badge: Stable Release"/></a>
+ <img src="https://img.shields.io/badge/License-MIT-green?style=flat-square"
alt="Badge: License MIT"/>
+</p>
+
## About
@@ -53,6 +62,14 @@
go install github.com/apricote/hcloud-upload-image@latest
```
+#### Docker
+
+There is a docker image published at `ghcr.io/apricote/hcloud-upload-image`.
+
+```shell
+docker run --rm -e HCLOUD_TOKEN="<your token>"
ghcr.io/apricote/hcloud-upload-image:latest <command>
+```
+
#### Usage
```shell
@@ -63,7 +80,7 @@
--compression bz2
```
-To learn more, you can use the embedded help output or check out the [CLI help
pages in this repository](docs/cli/hcloud-upload-image.md).:
+To learn more, you can use the embedded help output or check out the [CLI help
pages in this repository](docs/reference/cli/hcloud-upload-image.md).:
```shell
hcloud-upload-image --help
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/hcloud-upload-image-0.3.1/cmd/root.go
new/hcloud-upload-image-1.1.0/cmd/root.go
--- old/hcloud-upload-image-0.3.1/cmd/root.go 2024-12-07 01:57:59.000000000
+0100
+++ new/hcloud-upload-image-1.1.0/cmd/root.go 2025-05-10 14:27:47.000000000
+0200
@@ -9,7 +9,6 @@
"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"
@@ -89,7 +88,7 @@
opts := []hcloud.ClientOption{
hcloud.WithToken(os.Getenv("HCLOUD_TOKEN")),
hcloud.WithApplication("hcloud-upload-image", version.Version),
- hcloud.WithPollOpts(hcloud.PollOpts{BackoffFunc:
backoff.ExponentialBackoffWithLimit(2, 1*time.Second, 30*time.Second)}),
+ hcloud.WithPollOpts(hcloud.PollOpts{BackoffFunc:
hcloud.ExponentialBackoffWithOpts(hcloud.ExponentialBackoffOpts{Multiplier: 2,
Base: 1 * time.Second, Cap: 30 * time.Second})}),
}
if os.Getenv("HCLOUD_DEBUG") != "" || verbose >= 2 {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/hcloud-upload-image-0.3.1/cmd/upload.go
new/hcloud-upload-image-1.1.0/cmd/upload.go
--- old/hcloud-upload-image-0.3.1/cmd/upload.go 2024-12-07 01:57:59.000000000
+0100
+++ new/hcloud-upload-image-1.1.0/cmd/upload.go 2025-05-10 14:27:47.000000000
+0200
@@ -1,7 +1,9 @@
package cmd
import (
+ _ "embed"
"fmt"
+ "net/http"
"net/url"
"os"
@@ -16,20 +18,24 @@
uploadFlagImageURL = "image-url"
uploadFlagImagePath = "image-path"
uploadFlagCompression = "compression"
+ uploadFlagFormat = "format"
uploadFlagArchitecture = "architecture"
uploadFlagServerType = "server-type"
uploadFlagDescription = "description"
uploadFlagLabels = "labels"
)
+//go:embed upload.md
+var longDescription string
+
// uploadCmd represents the upload command
var uploadCmd = &cobra.Command{
Use: "upload (--image-path=<local-path> | --image-url=<url>)
--architecture=<x86|arm>",
Short: "Upload the specified disk image into your Hetzner Cloud
project.",
- Long: `This command implements a fake "upload", by going through a real
server and snapshots.
-This does cost a bit of money for the server.`,
+ Long: longDescription,
Example: ` hcloud-upload-image upload --image-path
/home/you/images/custom-linux-image-x86.bz2 --architecture x86 --compression
bz2 --description "My super duper custom linux"
- hcloud-upload-image upload --image-url https://examples.com/image-arm.raw
--architecture arm --labels foo=bar,version=latest`,
+ hcloud-upload-image upload --image-url https://examples.com/image-arm.raw
--architecture arm --labels foo=bar,version=latest
+ hcloud-upload-image upload --image-url https://examples.com/image-x86.qcow2
--architecture x86 --format qcow2`,
DisableAutoGenTag: true,
GroupID: "primary",
@@ -43,6 +49,7 @@
imageURLString, _ := cmd.Flags().GetString(uploadFlagImageURL)
imagePathString, _ := cmd.Flags().GetString(uploadFlagImagePath)
imageCompression, _ :=
cmd.Flags().GetString(uploadFlagCompression)
+ imageFormat, _ := cmd.Flags().GetString(uploadFlagFormat)
architecture, _ := cmd.Flags().GetString(uploadFlagArchitecture)
serverType, _ := cmd.Flags().GetString(uploadFlagServerType)
description, _ := cmd.Flags().GetString(uploadFlagDescription)
@@ -50,6 +57,7 @@
options := hcloudimages.UploadOptions{
ImageCompression:
hcloudimages.Compression(imageCompression),
+ ImageFormat: hcloudimages.Format(imageFormat),
Description: hcloud.Ptr(description),
Labels: labels,
}
@@ -60,8 +68,26 @@
return fmt.Errorf("unable to parse url from
--%s=%q: %w", uploadFlagImageURL, imageURLString, err)
}
+ // Check for image size
+ resp, err := http.Head(imageURL.String())
+ switch {
+ case err != nil:
+ logger.DebugContext(ctx, "failed to check for
file size, error on request", "err", err)
+ case resp.ContentLength == -1:
+ logger.DebugContext(ctx, "failed to check for
file size, server did not set the Content-Length", "err", err)
+ default:
+ options.ImageSize = resp.ContentLength
+ }
+
options.ImageURL = imageURL
} else if imagePathString != "" {
+ stat, err := os.Stat(imagePathString)
+ if err != nil {
+ logger.DebugContext(ctx, "failed to check for
file size, error on stat", "err", err)
+ } else {
+ options.ImageSize = stat.Size()
+ }
+
imageFile, err := os.Open(imagePathString)
if err != nil {
return fmt.Errorf("unable to read file from
--%s=%q: %w", uploadFlagImagePath, imagePathString, err)
@@ -101,6 +127,12 @@
cobra.FixedCompletions([]string{string(hcloudimages.CompressionBZ2),
string(hcloudimages.CompressionXZ)}, cobra.ShellCompDirectiveNoFileComp),
)
+ uploadCmd.Flags().String(uploadFlagFormat, "", "Format of the image.
[choices: qcow2]")
+ _ = uploadCmd.RegisterFlagCompletionFunc(
+ uploadFlagFormat,
+
cobra.FixedCompletions([]string{string(hcloudimages.FormatQCOW2)},
cobra.ShellCompDirectiveNoFileComp),
+ )
+
uploadCmd.Flags().String(uploadFlagArchitecture, "", "CPU architecture
of the disk image [choices: x86, arm]")
_ = uploadCmd.RegisterFlagCompletionFunc(
uploadFlagArchitecture,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/hcloud-upload-image-0.3.1/cmd/upload.md
new/hcloud-upload-image-1.1.0/cmd/upload.md
--- old/hcloud-upload-image-0.3.1/cmd/upload.md 1970-01-01 01:00:00.000000000
+0100
+++ new/hcloud-upload-image-1.1.0/cmd/upload.md 2025-05-10 14:27:47.000000000
+0200
@@ -0,0 +1,12 @@
+This command implements a fake "upload", by going through a real server and
+snapshots. This does cost a bit of money for the server.
+
+#### Image Size
+
+The image size for raw disk images is only limited by the servers root disk.
+
+The image size for qcow2 images is limited to the rescue systems root disk.
+This is currently a memory-backed file system with **960 MB** of space. A qcow2
+image not be larger than this size, or the process will error. There is a
+warning being logged if hcloud-upload-image can detect that your file is larger
+than this size.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/hcloud-upload-image-0.3.1/docs/.gitignore
new/hcloud-upload-image-1.1.0/docs/.gitignore
--- old/hcloud-upload-image-0.3.1/docs/.gitignore 1970-01-01
01:00:00.000000000 +0100
+++ new/hcloud-upload-image-1.1.0/docs/.gitignore 2025-05-10
14:27:47.000000000 +0200
@@ -0,0 +1,2 @@
+book
+https:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/hcloud-upload-image-0.3.1/docs/SUMMARY.md
new/hcloud-upload-image-1.1.0/docs/SUMMARY.md
--- old/hcloud-upload-image-0.3.1/docs/SUMMARY.md 1970-01-01
01:00:00.000000000 +0100
+++ new/hcloud-upload-image-1.1.0/docs/SUMMARY.md 2025-05-10
14:27:47.000000000 +0200
@@ -0,0 +1,22 @@
+# Summary
+
+[Introduction](introduction.md)
+
+# Guides
+
+- [Uploading Images](guides/README.md)
+ - [Fedora CoreOS
↗](https://docs.fedoraproject.org/en-US/fedora-coreos/provisioning-hetzner/#_creating_a_snapshot)
+ - [Flatcar Container Linux
↗](https://www.flatcar.org/docs/latest/installing/cloud/hetzner/#building-the-snapshots-1)
+ - [Talos Linux
↗](https://www.talos.dev/v1.10/talos-guides/install/cloud-platforms/hetzner/#hcloud-upload-image)
+
+# Reference
+
+- [CLI](reference/cli/hcloud-upload-image.md)
+ - [`upload`](reference/cli/hcloud-upload-image_upload.md)
+ - [`cleanup`](reference/cli/hcloud-upload-image_cleanup.md)
+- [Go Library](reference/go-library.md)
+
+---
+
+[Changelog CLI](changelog.md)
+[Changelog Go Library](changelog-hcloudimages.md)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/hcloud-upload-image-0.3.1/docs/book.toml
new/hcloud-upload-image-1.1.0/docs/book.toml
--- old/hcloud-upload-image-0.3.1/docs/book.toml 1970-01-01
01:00:00.000000000 +0100
+++ new/hcloud-upload-image-1.1.0/docs/book.toml 2025-05-10
14:27:47.000000000 +0200
@@ -0,0 +1,8 @@
+[book]
+language = "en"
+multilingual = false
+src = "."
+title = "hcloud-upload-image"
+
+[output.html]
+git-repository-url = "https://github.com/apricote/hcloud-upload-image"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/hcloud-upload-image-0.3.1/docs/changelog-hcloudimages.md
new/hcloud-upload-image-1.1.0/docs/changelog-hcloudimages.md
--- old/hcloud-upload-image-0.3.1/docs/changelog-hcloudimages.md
1970-01-01 01:00:00.000000000 +0100
+++ new/hcloud-upload-image-1.1.0/docs/changelog-hcloudimages.md
2025-05-10 14:27:47.000000000 +0200
@@ -0,0 +1,3 @@
+# Changelog Library
+
+{{#include ../hcloudimages/CHANGELOG.md:2: }}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/hcloud-upload-image-0.3.1/docs/changelog.md
new/hcloud-upload-image-1.1.0/docs/changelog.md
--- old/hcloud-upload-image-0.3.1/docs/changelog.md 1970-01-01
01:00:00.000000000 +0100
+++ new/hcloud-upload-image-1.1.0/docs/changelog.md 2025-05-10
14:27:47.000000000 +0200
@@ -0,0 +1,3 @@
+# Changelog CLI
+
+{{#include ../CHANGELOG.md:2: }}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/hcloud-upload-image-0.3.1/docs/cli/hcloud-upload-image.md
new/hcloud-upload-image-1.1.0/docs/cli/hcloud-upload-image.md
--- old/hcloud-upload-image-0.3.1/docs/cli/hcloud-upload-image.md
2024-12-07 01:57:59.000000000 +0100
+++ new/hcloud-upload-image-1.1.0/docs/cli/hcloud-upload-image.md
1970-01-01 01:00:00.000000000 +0100
@@ -1,20 +0,0 @@
-## hcloud-upload-image
-
-Manage custom OS images on Hetzner Cloud.
-
-### Synopsis
-
-Manage custom OS images on Hetzner Cloud.
-
-### Options
-
-```
- -h, --help help for hcloud-upload-image
- -v, --verbose count verbose debug output, can be specified up to 2 times
-```
-
-### SEE ALSO
-
-* [hcloud-upload-image cleanup](hcloud-upload-image_cleanup.md) -
Remove any temporary resources that were left over
-* [hcloud-upload-image upload](hcloud-upload-image_upload.md) - Upload the
specified disk image into your Hetzner Cloud project.
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/hcloud-upload-image-0.3.1/docs/cli/hcloud-upload-image_cleanup.md
new/hcloud-upload-image-1.1.0/docs/cli/hcloud-upload-image_cleanup.md
--- old/hcloud-upload-image-0.3.1/docs/cli/hcloud-upload-image_cleanup.md
2024-12-07 01:57:59.000000000 +0100
+++ new/hcloud-upload-image-1.1.0/docs/cli/hcloud-upload-image_cleanup.md
1970-01-01 01:00:00.000000000 +0100
@@ -1,38 +0,0 @@
-## hcloud-upload-image cleanup
-
-Remove any temporary resources that were left over
-
-### Synopsis
-
-If the upload fails at any point, there might still exist a server or
-ssh key in your Hetzner Cloud project. This command cleans up any resources
-that match the label "apricote.de/created-by=hcloud-upload-image".
-
-If you want to see a preview of what would be removed, you can use the
official hcloud CLI and run:
-
- $ hcloud server list -l apricote.de/created-by=hcloud-upload-image
- $ hcloud ssh-key list -l apricote.de/created-by=hcloud-upload-image
-
-This command does not handle any parallel executions of hcloud-upload-image
-and will remove in-use resources if called at the same time.
-
-```
-hcloud-upload-image cleanup [flags]
-```
-
-### Options
-
-```
- -h, --help help for cleanup
-```
-
-### Options inherited from parent commands
-
-```
- -v, --verbose count verbose debug output, can be specified up to 2 times
-```
-
-### SEE ALSO
-
-* [hcloud-upload-image](hcloud-upload-image.md) - Manage custom OS
images on Hetzner Cloud.
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/hcloud-upload-image-0.3.1/docs/cli/hcloud-upload-image_upload.md
new/hcloud-upload-image-1.1.0/docs/cli/hcloud-upload-image_upload.md
--- old/hcloud-upload-image-0.3.1/docs/cli/hcloud-upload-image_upload.md
2024-12-07 01:57:59.000000000 +0100
+++ new/hcloud-upload-image-1.1.0/docs/cli/hcloud-upload-image_upload.md
1970-01-01 01:00:00.000000000 +0100
@@ -1,43 +0,0 @@
-## hcloud-upload-image upload
-
-Upload the specified disk image into your Hetzner Cloud project.
-
-### Synopsis
-
-This command implements a fake "upload", by going through a real server and
snapshots.
-This does cost a bit of money for the server.
-
-```
-hcloud-upload-image upload (--image-path=<local-path> | --image-url=<url>)
--architecture=<x86|arm> [flags]
-```
-
-### Examples
-
-```
- hcloud-upload-image upload --image-path
/home/you/images/custom-linux-image-x86.bz2 --architecture x86 --compression
bz2 --description "My super duper custom linux"
- hcloud-upload-image upload --image-url https://examples.com/image-arm.raw
--architecture arm --labels foo=bar,version=latest
-```
-
-### Options
-
-```
- --architecture string CPU architecture of the disk image [choices:
x86, arm]
- --compression string Type of compression that was used on the disk
image [choices: bz2, xz]
- --description string Description for the resulting image
- -h, --help help for upload
- --image-path string Local path to the disk image that should be
uploaded
- --image-url string Remote URL of the disk image that should be
uploaded
- --labels stringToString Labels for the resulting image (default [])
- --server-type string Explicitly use this server type to generate
the image. Mutually exclusive with --architecture.
-```
-
-### Options inherited from parent commands
-
-```
- -v, --verbose count verbose debug output, can be specified up to 2 times
-```
-
-### SEE ALSO
-
-* [hcloud-upload-image](hcloud-upload-image.md) - Manage custom OS
images on Hetzner Cloud.
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/hcloud-upload-image-0.3.1/docs/guides/README.md
new/hcloud-upload-image-1.1.0/docs/guides/README.md
--- old/hcloud-upload-image-0.3.1/docs/guides/README.md 1970-01-01
01:00:00.000000000 +0100
+++ new/hcloud-upload-image-1.1.0/docs/guides/README.md 2025-05-10
14:27:47.000000000 +0200
@@ -0,0 +1,7 @@
+# Uploading Images
+
+Check out these docs from other projects to learn how to use
`hcloud-upload-image`:
+
+- [Fedora CoreOS
↗](https://docs.fedoraproject.org/en-US/fedora-coreos/provisioning-hetzner/#_creating_a_snapshot)
+- [Flatcar Container Linux
↗](https://www.flatcar.org/docs/latest/installing/cloud/hetzner/#building-the-snapshots-1)
+- [Talos Linux
↗](https://www.talos.dev/v1.10/talos-guides/install/cloud-platforms/hetzner/#hcloud-upload-image)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/hcloud-upload-image-0.3.1/docs/introduction.md
new/hcloud-upload-image-1.1.0/docs/introduction.md
--- old/hcloud-upload-image-0.3.1/docs/introduction.md 1970-01-01
01:00:00.000000000 +0100
+++ new/hcloud-upload-image-1.1.0/docs/introduction.md 2025-05-10
14:27:47.000000000 +0200
@@ -0,0 +1,3 @@
+# Introduction
+
+{{#include ../README.md:2:}}
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/hcloud-upload-image-0.3.1/docs/reference/cli/hcloud-upload-image.md
new/hcloud-upload-image-1.1.0/docs/reference/cli/hcloud-upload-image.md
--- old/hcloud-upload-image-0.3.1/docs/reference/cli/hcloud-upload-image.md
1970-01-01 01:00:00.000000000 +0100
+++ new/hcloud-upload-image-1.1.0/docs/reference/cli/hcloud-upload-image.md
2025-05-10 14:27:47.000000000 +0200
@@ -0,0 +1,20 @@
+## hcloud-upload-image
+
+Manage custom OS images on Hetzner Cloud.
+
+### Synopsis
+
+Manage custom OS images on Hetzner Cloud.
+
+### Options
+
+```
+ -h, --help help for hcloud-upload-image
+ -v, --verbose count verbose debug output, can be specified up to 2 times
+```
+
+### SEE ALSO
+
+* [hcloud-upload-image cleanup](hcloud-upload-image_cleanup.md) -
Remove any temporary resources that were left over
+* [hcloud-upload-image upload](hcloud-upload-image_upload.md) - Upload the
specified disk image into your Hetzner Cloud project.
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/hcloud-upload-image-0.3.1/docs/reference/cli/hcloud-upload-image_cleanup.md
new/hcloud-upload-image-1.1.0/docs/reference/cli/hcloud-upload-image_cleanup.md
---
old/hcloud-upload-image-0.3.1/docs/reference/cli/hcloud-upload-image_cleanup.md
1970-01-01 01:00:00.000000000 +0100
+++
new/hcloud-upload-image-1.1.0/docs/reference/cli/hcloud-upload-image_cleanup.md
2025-05-10 14:27:47.000000000 +0200
@@ -0,0 +1,38 @@
+## hcloud-upload-image cleanup
+
+Remove any temporary resources that were left over
+
+### Synopsis
+
+If the upload fails at any point, there might still exist a server or
+ssh key in your Hetzner Cloud project. This command cleans up any resources
+that match the label "apricote.de/created-by=hcloud-upload-image".
+
+If you want to see a preview of what would be removed, you can use the
official hcloud CLI and run:
+
+ $ hcloud server list -l apricote.de/created-by=hcloud-upload-image
+ $ hcloud ssh-key list -l apricote.de/created-by=hcloud-upload-image
+
+This command does not handle any parallel executions of hcloud-upload-image
+and will remove in-use resources if called at the same time.
+
+```
+hcloud-upload-image cleanup [flags]
+```
+
+### Options
+
+```
+ -h, --help help for cleanup
+```
+
+### Options inherited from parent commands
+
+```
+ -v, --verbose count verbose debug output, can be specified up to 2 times
+```
+
+### SEE ALSO
+
+* [hcloud-upload-image](hcloud-upload-image.md) - Manage custom OS
images on Hetzner Cloud.
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/hcloud-upload-image-0.3.1/docs/reference/cli/hcloud-upload-image_upload.md
new/hcloud-upload-image-1.1.0/docs/reference/cli/hcloud-upload-image_upload.md
---
old/hcloud-upload-image-0.3.1/docs/reference/cli/hcloud-upload-image_upload.md
1970-01-01 01:00:00.000000000 +0100
+++
new/hcloud-upload-image-1.1.0/docs/reference/cli/hcloud-upload-image_upload.md
2025-05-10 14:27:47.000000000 +0200
@@ -0,0 +1,56 @@
+## hcloud-upload-image upload
+
+Upload the specified disk image into your Hetzner Cloud project.
+
+### Synopsis
+
+This command implements a fake "upload", by going through a real server and
+snapshots. This does cost a bit of money for the server.
+
+#### Image Size
+
+The image size for raw disk images is only limited by the servers root disk.
+
+The image size for qcow2 images is limited to the rescue systems root disk.
+This is currently a memory-backed file system with **960 MB** of space. A qcow2
+image not be larger than this size, or the process will error. There is a
+warning being logged if hcloud-upload-image can detect that your file is larger
+than this size.
+
+
+```
+hcloud-upload-image upload (--image-path=<local-path> | --image-url=<url>)
--architecture=<x86|arm> [flags]
+```
+
+### Examples
+
+```
+ hcloud-upload-image upload --image-path
/home/you/images/custom-linux-image-x86.bz2 --architecture x86 --compression
bz2 --description "My super duper custom linux"
+ hcloud-upload-image upload --image-url https://examples.com/image-arm.raw
--architecture arm --labels foo=bar,version=latest
+ hcloud-upload-image upload --image-url https://examples.com/image-x86.qcow2
--architecture x86 --format qcow2
+```
+
+### Options
+
+```
+ --architecture string CPU architecture of the disk image [choices:
x86, arm]
+ --compression string Type of compression that was used on the disk
image [choices: bz2, xz]
+ --description string Description for the resulting image
+ --format string Format of the image. [choices: qcow2]
+ -h, --help help for upload
+ --image-path string Local path to the disk image that should be
uploaded
+ --image-url string Remote URL of the disk image that should be
uploaded
+ --labels stringToString Labels for the resulting image (default [])
+ --server-type string Explicitly use this server type to generate
the image. Mutually exclusive with --architecture.
+```
+
+### Options inherited from parent commands
+
+```
+ -v, --verbose count verbose debug output, can be specified up to 2 times
+```
+
+### SEE ALSO
+
+* [hcloud-upload-image](hcloud-upload-image.md) - Manage custom OS
images on Hetzner Cloud.
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/hcloud-upload-image-0.3.1/docs/reference/go-library.md
new/hcloud-upload-image-1.1.0/docs/reference/go-library.md
--- old/hcloud-upload-image-0.3.1/docs/reference/go-library.md 1970-01-01
01:00:00.000000000 +0100
+++ new/hcloud-upload-image-1.1.0/docs/reference/go-library.md 2025-05-10
14:27:47.000000000 +0200
@@ -0,0 +1,3 @@
+# Go Library
+
+You can find the documentation at
[pkg.go.dev/github.com/apricote/hcloud-upload-image/hcloudimages
↗](https://pkg.go.dev/github.com/apricote/hcloud-upload-image/hcloudimages).
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/hcloud-upload-image-0.3.1/go.mod
new/hcloud-upload-image-1.1.0/go.mod
--- old/hcloud-upload-image-0.3.1/go.mod 2024-12-07 01:57:59.000000000
+0100
+++ new/hcloud-upload-image-1.1.0/go.mod 2025-05-10 14:27:47.000000000
+0200
@@ -1,31 +1,32 @@
module github.com/apricote/hcloud-upload-image
-go 1.22.2
+go 1.23.0
+
+toolchain go1.24.3
require (
- github.com/apricote/hcloud-upload-image/hcloudimages v0.3.0
- github.com/hetznercloud/hcloud-go/v2 v2.17.0
- github.com/spf13/cobra v1.8.1
+ github.com/apricote/hcloud-upload-image/hcloudimages v1.1.0
+ github.com/hetznercloud/hcloud-go/v2 v2.21.0
+ github.com/spf13/cobra v1.9.1
)
require (
github.com/beorn7/perks v1.0.1 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
- github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect
+ github.com/cpuguy83/go-md2man/v2 v2.0.6 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
- github.com/klauspost/compress v1.17.9 // indirect
+ github.com/klauspost/compress v1.17.11 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 //
indirect
- github.com/prometheus/client_golang v1.20.5 // indirect
+ github.com/prometheus/client_golang v1.21.1 // indirect
github.com/prometheus/client_model v0.6.1 // indirect
- github.com/prometheus/common v0.55.0 // indirect
+ github.com/prometheus/common v0.62.0 // indirect
github.com/prometheus/procfs v0.15.1 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
- github.com/spf13/pflag v1.0.5 // indirect
- github.com/stretchr/testify v1.10.0 // indirect
- golang.org/x/crypto v0.30.0 // indirect
- golang.org/x/net v0.30.0 // indirect
- golang.org/x/sys v0.28.0 // indirect
- golang.org/x/text v0.21.0 // indirect
- google.golang.org/protobuf v1.34.2 // indirect
+ github.com/spf13/pflag v1.0.6 // indirect
+ golang.org/x/crypto v0.37.0 // indirect
+ golang.org/x/net v0.38.0 // indirect
+ golang.org/x/sys v0.32.0 // indirect
+ golang.org/x/text v0.24.0 // indirect
+ google.golang.org/protobuf v1.36.1 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/hcloud-upload-image-0.3.1/go.sum
new/hcloud-upload-image-1.1.0/go.sum
--- old/hcloud-upload-image-0.3.1/go.sum 2024-12-07 01:57:59.000000000
+0100
+++ new/hcloud-upload-image-1.1.0/go.sum 2025-05-10 14:27:47.000000000
+0200
@@ -1,21 +1,21 @@
-github.com/apricote/hcloud-upload-image/hcloudimages v0.3.0
h1:POoU0nKeTq3fw7Ok/BTwJ/I3CTKhcChtn8L+Ecpba5U=
-github.com/apricote/hcloud-upload-image/hcloudimages v0.3.0/go.mod
h1:9W0XQVhzb9x69UBXXR0nxF0taC6s6fl0/nemDGUVrfI=
+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/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=
github.com/cespare/xxhash/v2 v2.3.0/go.mod
h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
-github.com/cpuguy83/go-md2man/v2 v2.0.4
h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4=
-github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod
h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
+github.com/cpuguy83/go-md2man/v2 v2.0.6
h1:XJtiaUW6dEEqVuZiMTn1ldk455QWwEIsMIJlo5vtkx0=
+github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod
h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
github.com/davecgh/go-spew v1.1.1
h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod
h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
-github.com/google/go-cmp v0.6.0/go.mod
h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
-github.com/hetznercloud/hcloud-go/v2 v2.17.0
h1:ge0w2piey9SV6XGyU/wQ6HBR24QyMbJ3wLzezplqR68=
-github.com/hetznercloud/hcloud-go/v2 v2.17.0/go.mod
h1:zfyZ4Orx+mPpYDzWAxXR7DHGL50nnlZ5Edzgs1o6f/s=
+github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
+github.com/google/go-cmp v0.7.0/go.mod
h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
+github.com/hetznercloud/hcloud-go/v2 v2.21.0
h1:wUpQT+fgAxIcdMtFvuCJ78ziqc/VARubpOQPQyj4Q84=
+github.com/hetznercloud/hcloud-go/v2 v2.21.0/go.mod
h1:WSM7w+9tT86sJTNcF8a/oHljC3HUmQfcLxYsgx6PpSc=
github.com/inconshreveable/mousetrap v1.1.0
h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod
h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
-github.com/klauspost/compress v1.17.9
h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
-github.com/klauspost/compress v1.17.9/go.mod
h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
+github.com/klauspost/compress v1.17.11
h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc=
+github.com/klauspost/compress v1.17.11/go.mod
h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod
h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
@@ -26,36 +26,36 @@
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod
h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/pmezard/go-difflib v1.0.0
h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod
h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/prometheus/client_golang v1.20.5
h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y=
-github.com/prometheus/client_golang v1.20.5/go.mod
h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
+github.com/prometheus/client_golang v1.21.1
h1:DOvXXTqVzvkIewV/CDPFdejpMCGeMcbGCQ8YOmu+Ibk=
+github.com/prometheus/client_golang v1.21.1/go.mod
h1:U9NM32ykUErtVBxdvD3zfi+EuFkkaBvMb09mIfe0Zgg=
github.com/prometheus/client_model v0.6.1
h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
github.com/prometheus/client_model v0.6.1/go.mod
h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
-github.com/prometheus/common v0.55.0
h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc=
-github.com/prometheus/common v0.55.0/go.mod
h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8=
+github.com/prometheus/common v0.62.0
h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io=
+github.com/prometheus/common v0.62.0/go.mod
h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I=
github.com/prometheus/procfs v0.15.1
h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
github.com/prometheus/procfs v0.15.1/go.mod
h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
github.com/rogpeppe/go-internal v1.11.0
h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
github.com/rogpeppe/go-internal v1.11.0/go.mod
h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
github.com/russross/blackfriday/v2 v2.1.0
h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
github.com/russross/blackfriday/v2 v2.1.0/go.mod
h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
-github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
-github.com/spf13/cobra v1.8.1/go.mod
h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
-github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
-github.com/spf13/pflag v1.0.5/go.mod
h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
+github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
+github.com/spf13/cobra v1.9.1/go.mod
h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
+github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
+github.com/spf13/pflag v1.0.6/go.mod
h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
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.30.0 h1:RwoQn3GkWiMkzlX562cLB7OxWvjH1L8xutO2WoJcRoY=
-golang.org/x/crypto v0.30.0/go.mod
h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
-golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4=
-golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU=
-golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
-golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
-golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q=
-golang.org/x/term v0.27.0/go.mod
h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM=
-golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
-golang.org/x/text v0.21.0/go.mod
h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
-google.golang.org/protobuf v1.34.2
h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
-google.golang.org/protobuf v1.34.2/go.mod
h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
+golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE=
+golang.org/x/crypto v0.37.0/go.mod
h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc=
+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.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20=
+golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
+golang.org/x/term v0.31.0 h1:erwDkOK1Msy6offm1mOgvspSkslFnIGsFnxOKoufg3o=
+golang.org/x/term v0.31.0/go.mod
h1:R4BeIy7D95HzImkxGkTW1UQTtP54tio2RyHz7PwK0aw=
+golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0=
+golang.org/x/text v0.24.0/go.mod
h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU=
+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=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c
h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod
h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/hcloud-upload-image-0.3.1/hcloudimages/CHANGELOG.md
new/hcloud-upload-image-1.1.0/hcloudimages/CHANGELOG.md
--- old/hcloud-upload-image-0.3.1/hcloudimages/CHANGELOG.md 2024-12-07
01:57:59.000000000 +0100
+++ new/hcloud-upload-image-1.1.0/hcloudimages/CHANGELOG.md 2025-05-10
14:27:47.000000000 +0200
@@ -1,5 +1,31 @@
# 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)
+
+
+### Features
+
+* upload qcow2 images
([#69](https://github.com/apricote/hcloud-upload-image/issues/69))
([ac3e9dd](https://github.com/apricote/hcloud-upload-image/commit/ac3e9dd7ecd86d1538b6401c3073c7c078c40847))
+
##
[0.3.1](https://github.com/apricote/hcloud-upload-image/compare/hcloudimages/v0.3.0...hcloudimages/v0.3.1)
(2024-12-07)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/hcloud-upload-image-0.3.1/hcloudimages/backoff/backoff.go
new/hcloud-upload-image-1.1.0/hcloudimages/backoff/backoff.go
--- old/hcloud-upload-image-0.3.1/hcloudimages/backoff/backoff.go
2024-12-07 01:57:59.000000000 +0100
+++ new/hcloud-upload-image-1.1.0/hcloudimages/backoff/backoff.go
2025-05-10 14:27:47.000000000 +0200
@@ -16,6 +16,10 @@
// 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 -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/hcloud-upload-image-0.3.1/hcloudimages/client.go
new/hcloud-upload-image-1.1.0/hcloudimages/client.go
--- old/hcloud-upload-image-0.3.1/hcloudimages/client.go 2024-12-07
01:57:59.000000000 +0100
+++ new/hcloud-upload-image-1.1.0/hcloudimages/client.go 2025-05-10
14:27:47.000000000 +0200
@@ -43,6 +43,10 @@
defaultRescueType = hcloud.ServerRescueTypeLinux64
defaultSSHDialTimeout = 1 * time.Minute
+
+ // Size observed on x86, 2025-05-03, no idea if that changes.
+ // Might be able to extends this to more of the available memory.
+ rescueSystemRootDiskSizeMB int64 = 960
)
type UploadOptions struct {
@@ -56,10 +60,14 @@
// set to anything else, the file will be decompressed before written
to the disk.
ImageCompression Compression
+ ImageFormat Format
+
+ // Can be optionally set to make the client validate that the image can
be written to the server.
+ ImageSize int64
+
// Possible future additions:
// ImageSignatureVerification
// ImageLocalPath
- // ImageType (RawDiskImage, ISO, qcow2, ...)
// Architecture should match the architecture of the Image. This
decides if the Snapshot can later be
// used with [hcloud.ArchitectureX86] or [hcloud.ArchitectureARM]
servers.
@@ -101,6 +109,19 @@
// zip,zstd
)
+type Format string
+
+const (
+ FormatRaw Format = ""
+
+ // FormatQCOW2 allows to upload images in the qcow2 format directly.
+ //
+ // The qcow2 image must fit on the disk available in the rescue system.
"qemu-img dd", which is used to convert
+ // qcow2 to raw, requires a file as an input. If
[UploadOption.ImageSize] is set and FormatQCOW2 is used, there is a
+ // warning message displayed if there is a high probability of issues.
+ FormatQCOW2 Format = "qcow2"
+)
+
// NewClient instantiates a new client. It requires a working [*hcloud.Client]
to interact with the Hetzner Cloud API.
func NewClient(c *hcloud.Client) *Client {
return &Client{
@@ -134,6 +155,19 @@
resourceName := resourcePrefix + id
labels := labelutil.Merge(DefaultLabels, options.Labels)
+ // 0. Validations
+ if options.ImageFormat == FormatQCOW2 && options.ImageSize > 0 {
+ if options.ImageSize > rescueSystemRootDiskSizeMB*1024*1024 {
+ // Just a warning, because the size might change with
time.
+ // Alternatively one could add an override flag for the
check and make this an error.
+ logger.WarnContext(ctx,
+ fmt.Sprintf("image must be smaller than %d MB
(rescue system root disk) for qcow2", rescueSystemRootDiskSizeMB),
+ "maximum-size", rescueSystemRootDiskSizeMB,
+ "actual-size", options.ImageSize/(1024*1024),
+ )
+ }
+ }
+
// 1. Create SSH Key
logger.InfoContext(ctx, "# Step 1: Generating SSH Key")
privateKey, publicKey, err := sshutil.GenerateKeyPair()
@@ -282,7 +316,7 @@
err = control.Retry(
contextlogger.New(ctx, logger.With("operation", "ssh")),
- 10,
+ 100, // ~ 3 minutes
func() error {
var err error
logger.DebugContext(ctx, "trying to connect to server",
"ip", server.PublicNet.IPv4.IP)
@@ -293,50 +327,44 @@
if err != nil {
return nil, fmt.Errorf("failed to ssh into temporary server:
%w", err)
}
- defer sshClient.Close()
+ defer func() { _ = sshClient.Close() }()
- // 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())
- }
+ // 6. Wipe existing disk, to avoid storing any bytes from it in the
snapshot
+ logger.InfoContext(ctx, "# Step 6: Cleaning existing disk")
- 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)
- }
+ 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)
}
- cmd += "dd of=/dev/sda bs=4M && sync"
+ // 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
+ }
- // 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 6: Finished writing image to disk")
+ output, err = sshsession.Run(sshClient, cmd, options.ImageReader)
+ logger.InfoContext(ctx, "# Step 7: 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)
}
- // 7. SSH On Server: Shutdown
- logger.InfoContext(ctx, "# Step 7: Shutting down server")
+ // 8. SSH On Server: Shutdown
+ logger.InfoContext(ctx, "# Step 8: 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)
}
- // 8. Create Image from Server
- logger.InfoContext(ctx, "# Step 8: Creating Image")
+ // 9. Create Image from Server
+ logger.InfoContext(ctx, "# Step 9: Creating Image")
createImageResult, _, err := s.c.Server.CreateImage(ctx, server,
&hcloud.ServerCreateImageOpts{
Type: hcloud.ImageTypeSnapshot,
Description: options.Description,
@@ -481,3 +509,39 @@
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 -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/hcloud-upload-image-0.3.1/hcloudimages/client_test.go
new/hcloud-upload-image-1.1.0/hcloudimages/client_test.go
--- old/hcloud-upload-image-0.3.1/hcloudimages/client_test.go 2024-12-07
01:57:59.000000000 +0100
+++ new/hcloud-upload-image-1.1.0/hcloudimages/client_test.go 2025-05-10
14:27:47.000000000 +0200
@@ -1,33 +1,110 @@
-package hcloudimages_test
+package hcloudimages
import (
- "context"
- "fmt"
"net/url"
-
- "github.com/hetznercloud/hcloud-go/v2/hcloud"
-
- "github.com/apricote/hcloud-upload-image/hcloudimages"
+ "testing"
)
-func ExampleClient_Upload() {
- client := hcloudimages.NewClient(
- hcloud.NewClient(hcloud.WithToken("<your token>")),
- )
-
- imageURL, err := url.Parse("https://example.com/disk-image.raw.bz2")
+func mustParseURL(s string) *url.URL {
+ u, err := url.Parse(s)
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)
- }
+ return u
+}
- fmt.Printf("Uploaded Image: %d", image.ID)
+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)
+ }
+ })
+ }
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/hcloud-upload-image-0.3.1/hcloudimages/doc_test.go
new/hcloud-upload-image-1.1.0/hcloudimages/doc_test.go
--- old/hcloud-upload-image-0.3.1/hcloudimages/doc_test.go 1970-01-01
01:00:00.000000000 +0100
+++ new/hcloud-upload-image-1.1.0/hcloudimages/doc_test.go 2025-05-10
14:27:47.000000000 +0200
@@ -0,0 +1,33 @@
+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("<your token>")),
+ )
+
+ 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 -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/hcloud-upload-image-0.3.1/hcloudimages/go.mod
new/hcloud-upload-image-1.1.0/hcloudimages/go.mod
--- old/hcloud-upload-image-0.3.1/hcloudimages/go.mod 2024-12-07
01:57:59.000000000 +0100
+++ new/hcloud-upload-image-1.1.0/hcloudimages/go.mod 2025-05-10
14:27:47.000000000 +0200
@@ -1,27 +1,29 @@
module github.com/apricote/hcloud-upload-image/hcloudimages
-go 1.22.2
+go 1.23.0
+
+toolchain go1.24.3
require (
- github.com/hetznercloud/hcloud-go/v2 v2.17.0
+ github.com/hetznercloud/hcloud-go/v2 v2.21.0
github.com/stretchr/testify v1.10.0
- golang.org/x/crypto v0.30.0
+ golang.org/x/crypto v0.37.0
)
require (
github.com/beorn7/perks v1.0.1 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
- github.com/klauspost/compress v1.17.9 // indirect
+ github.com/klauspost/compress v1.17.11 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 //
indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
- github.com/prometheus/client_golang v1.20.5 // indirect
+ github.com/prometheus/client_golang v1.21.1 // indirect
github.com/prometheus/client_model v0.6.1 // indirect
- github.com/prometheus/common v0.55.0 // indirect
+ github.com/prometheus/common v0.62.0 // indirect
github.com/prometheus/procfs v0.15.1 // indirect
- golang.org/x/net v0.30.0 // indirect
- golang.org/x/sys v0.28.0 // indirect
- golang.org/x/text v0.21.0 // indirect
- google.golang.org/protobuf v1.34.2 // indirect
+ golang.org/x/net v0.38.0 // indirect
+ golang.org/x/sys v0.32.0 // indirect
+ golang.org/x/text v0.24.0 // indirect
+ google.golang.org/protobuf v1.36.1 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/hcloud-upload-image-0.3.1/hcloudimages/go.sum
new/hcloud-upload-image-1.1.0/hcloudimages/go.sum
--- old/hcloud-upload-image-0.3.1/hcloudimages/go.sum 2024-12-07
01:57:59.000000000 +0100
+++ new/hcloud-upload-image-1.1.0/hcloudimages/go.sum 2025-05-10
14:27:47.000000000 +0200
@@ -4,12 +4,12 @@
github.com/cespare/xxhash/v2 v2.3.0/go.mod
h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/davecgh/go-spew v1.1.1
h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod
h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
-github.com/google/go-cmp v0.6.0/go.mod
h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
-github.com/hetznercloud/hcloud-go/v2 v2.17.0
h1:ge0w2piey9SV6XGyU/wQ6HBR24QyMbJ3wLzezplqR68=
-github.com/hetznercloud/hcloud-go/v2 v2.17.0/go.mod
h1:zfyZ4Orx+mPpYDzWAxXR7DHGL50nnlZ5Edzgs1o6f/s=
-github.com/klauspost/compress v1.17.9
h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
-github.com/klauspost/compress v1.17.9/go.mod
h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
+github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
+github.com/google/go-cmp v0.7.0/go.mod
h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
+github.com/hetznercloud/hcloud-go/v2 v2.21.0
h1:wUpQT+fgAxIcdMtFvuCJ78ziqc/VARubpOQPQyj4Q84=
+github.com/hetznercloud/hcloud-go/v2 v2.21.0/go.mod
h1:WSM7w+9tT86sJTNcF8a/oHljC3HUmQfcLxYsgx6PpSc=
+github.com/klauspost/compress v1.17.11
h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc=
+github.com/klauspost/compress v1.17.11/go.mod
h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod
h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
@@ -20,30 +20,30 @@
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod
h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/pmezard/go-difflib v1.0.0
h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod
h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/prometheus/client_golang v1.20.5
h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y=
-github.com/prometheus/client_golang v1.20.5/go.mod
h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
+github.com/prometheus/client_golang v1.21.1
h1:DOvXXTqVzvkIewV/CDPFdejpMCGeMcbGCQ8YOmu+Ibk=
+github.com/prometheus/client_golang v1.21.1/go.mod
h1:U9NM32ykUErtVBxdvD3zfi+EuFkkaBvMb09mIfe0Zgg=
github.com/prometheus/client_model v0.6.1
h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
github.com/prometheus/client_model v0.6.1/go.mod
h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
-github.com/prometheus/common v0.55.0
h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc=
-github.com/prometheus/common v0.55.0/go.mod
h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8=
+github.com/prometheus/common v0.62.0
h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io=
+github.com/prometheus/common v0.62.0/go.mod
h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I=
github.com/prometheus/procfs v0.15.1
h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
github.com/prometheus/procfs v0.15.1/go.mod
h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
github.com/rogpeppe/go-internal v1.11.0
h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
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.30.0 h1:RwoQn3GkWiMkzlX562cLB7OxWvjH1L8xutO2WoJcRoY=
-golang.org/x/crypto v0.30.0/go.mod
h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
-golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4=
-golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU=
-golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
-golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
-golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q=
-golang.org/x/term v0.27.0/go.mod
h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM=
-golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
-golang.org/x/text v0.21.0/go.mod
h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
-google.golang.org/protobuf v1.34.2
h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
-google.golang.org/protobuf v1.34.2/go.mod
h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
+golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE=
+golang.org/x/crypto v0.37.0/go.mod
h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc=
+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.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20=
+golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
+golang.org/x/term v0.31.0 h1:erwDkOK1Msy6offm1mOgvspSkslFnIGsFnxOKoufg3o=
+golang.org/x/term v0.31.0/go.mod
h1:R4BeIy7D95HzImkxGkTW1UQTtP54tio2RyHz7PwK0aw=
+golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0=
+golang.org/x/text v0.24.0/go.mod
h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU=
+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=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c
h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod
h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/hcloud-upload-image-0.3.1/hcloudimages/internal/control/retry.go
new/hcloud-upload-image-1.1.0/hcloudimages/internal/control/retry.go
--- old/hcloud-upload-image-0.3.1/hcloudimages/internal/control/retry.go
2024-12-07 01:57:59.000000000 +0100
+++ new/hcloud-upload-image-1.1.0/hcloudimages/internal/control/retry.go
2025-05-10 14:27:47.000000000 +0200
@@ -8,7 +8,8 @@
"context"
"time"
- "github.com/apricote/hcloud-upload-image/hcloudimages/backoff"
+ "github.com/hetznercloud/hcloud-go/v2/hcloud"
+
"github.com/apricote/hcloud-upload-image/hcloudimages/contextlogger"
)
@@ -18,7 +19,7 @@
var err error
- backoffFunc := backoff.ExponentialBackoffWithLimit(2, 1*time.Second,
30*time.Second)
+ backoffFunc :=
hcloud.ExponentialBackoffWithOpts(hcloud.ExponentialBackoffOpts{Multiplier: 2,
Base: 200 * time.Millisecond, Cap: 2 * time.Second})
for try := 0; try < maxTries; try++ {
if ctx.Err() != nil {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/hcloud-upload-image-0.3.1/hcloudimages/internal/sshsession/session.go
new/hcloud-upload-image-1.1.0/hcloudimages/internal/sshsession/session.go
--- old/hcloud-upload-image-0.3.1/hcloudimages/internal/sshsession/session.go
2024-12-07 01:57:59.000000000 +0100
+++ new/hcloud-upload-image-1.1.0/hcloudimages/internal/sshsession/session.go
2025-05-10 14:27:47.000000000 +0200
@@ -12,7 +12,7 @@
if err != nil {
return nil, err
}
- defer sess.Close()
+ defer func() { _ = sess.Close() }()
if stdin != nil {
sess.Stdin = stdin
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/hcloud-upload-image-0.3.1/internal/version/version.go
new/hcloud-upload-image-1.1.0/internal/version/version.go
--- old/hcloud-upload-image-0.3.1/internal/version/version.go 2024-12-07
01:57:59.000000000 +0100
+++ new/hcloud-upload-image-1.1.0/internal/version/version.go 2025-05-10
14:27:47.000000000 +0200
@@ -2,7 +2,7 @@
var (
// version is a semver version (https://semver.org).
- version = "0.3.1" // x-release-please-version
+ version = "1.1.0" // x-release-please-version
// versionPrerelease is a semver version pre-release identifier
(https://semver.org).
//
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/hcloud-upload-image-0.3.1/renovate.json
new/hcloud-upload-image-1.1.0/renovate.json
--- old/hcloud-upload-image-0.3.1/renovate.json 2024-12-07 01:57:59.000000000
+0100
+++ new/hcloud-upload-image-1.1.0/renovate.json 2025-05-10 14:27:47.000000000
+0200
@@ -11,12 +11,15 @@
"gomodTidy",
"gomodUpdateImportPaths"
],
+ "goGetDirs": ["./...", "./hcloudimages/..."],
"customManagers": [
{
"customType": "regex",
- "fileMatch": ["^\\.github\\/(?:workflows|actions)\\/.+\\.ya?ml$"],
+ "fileMatch": [
+ "^\\.github\\/(?:workflows|actions)\\/.+\\.ya?ml$"
+ ],
"matchStrings": [
- "(?:version|VERSION): (?<currentValue>.+) # renovate:
datasource=(?<datasource>[a-z-]+) depName=(?<depName>.+)(?:
lookupName=(?<lookupName>.+))?(?: versioning=(?<versioning>[a-z-]+))?"
+ "(?:version|VERSION): (?<currentValue>.+) # renovate:
datasource=(?<datasource>[a-z-]+) depName=(?<depName>.+)(?:
packageName=(?<packageName>.+))?(?: versioning=(?<versioning>[a-z-]+))?"
]
}
]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/hcloud-upload-image-0.3.1/scripts/cli-help-pages.go
new/hcloud-upload-image-1.1.0/scripts/cli-help-pages.go
--- old/hcloud-upload-image-0.3.1/scripts/cli-help-pages.go 2024-12-07
01:57:59.000000000 +0100
+++ new/hcloud-upload-image-1.1.0/scripts/cli-help-pages.go 2025-05-10
14:27:47.000000000 +0200
@@ -11,7 +11,7 @@
func run() error {
// Define the directory where the docs will be generated
- dir := "docs/cli"
+ dir := "docs/reference/cli"
// Ensure the directory exists
if err := os.MkdirAll(dir, 0755); err != nil {
++++++ hcloud-upload-image.obsinfo ++++++
--- /var/tmp/diff_new_pack.9Zo9Y9/_old 2025-05-12 16:51:25.711094805 +0200
+++ /var/tmp/diff_new_pack.9Zo9Y9/_new 2025-05-12 16:51:25.715094973 +0200
@@ -1,5 +1,5 @@
name: hcloud-upload-image
-version: 0.3.1
-mtime: 1733533079
-commit: b328867f6b9b965dcd581cb6f6907dae364faa7a
+version: 1.1.0
+mtime: 1746880067
+commit: b9af8855d5c0c1e40ddfaa670296731b2ed0c53e
++++++ vendor.tar.gz ++++++
++++ 19544 lines of diff (skipped)