2024-05-02 20:19:25 +02:00
package cmd
import (
"fmt"
"net/url"
2024-05-09 18:16:37 +02:00
"os"
2024-05-02 20:19:25 +02:00
"github.com/hetznercloud/hcloud-go/v2/hcloud"
"github.com/spf13/cobra"
2024-05-04 22:13:33 +02:00
"github.com/apricote/hcloud-upload-image/hcloudimages"
2024-05-02 21:42:36 +02:00
"github.com/apricote/hcloud-upload-image/hcloudimages/contextlogger"
2024-05-02 20:19:25 +02:00
)
const (
uploadFlagImageURL = "image-url"
2024-05-09 18:16:37 +02:00
uploadFlagImagePath = "image-path"
2024-05-02 20:19:25 +02:00
uploadFlagCompression = "compression"
uploadFlagArchitecture = "architecture"
uploadFlagDescription = "description"
uploadFlagLabels = "labels"
)
// uploadCmd represents the upload command
var uploadCmd = & cobra . Command {
2024-05-09 18:16:37 +02:00
Use : "upload (--image-path=<local-path> | --image-url=<url>) --architecture=<x86|arm>" ,
2024-05-02 20:19:25 +02:00
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 . ` ,
2024-05-09 18:16:37 +02:00
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
` ,
2024-05-05 00:05:09 +02:00
GroupID : "primary" ,
2024-05-02 20:19:25 +02:00
2024-05-10 18:06:38 +02:00
PreRun : initClient ,
2024-05-02 20:19:25 +02:00
RunE : func ( cmd * cobra . Command , args [ ] string ) error {
ctx := cmd . Context ( )
logger := contextlogger . From ( ctx )
imageURLString , _ := cmd . Flags ( ) . GetString ( uploadFlagImageURL )
2024-05-09 18:16:37 +02:00
imagePathString , _ := cmd . Flags ( ) . GetString ( uploadFlagImagePath )
2024-05-02 20:19:25 +02:00
imageCompression , _ := cmd . Flags ( ) . GetString ( uploadFlagCompression )
architecture , _ := cmd . Flags ( ) . GetString ( uploadFlagArchitecture )
description , _ := cmd . Flags ( ) . GetString ( uploadFlagDescription )
labels , _ := cmd . Flags ( ) . GetStringToString ( uploadFlagLabels )
2024-05-09 18:16:37 +02:00
options := hcloudimages . UploadOptions {
2024-05-04 22:13:33 +02:00
ImageCompression : hcloudimages . Compression ( imageCompression ) ,
2024-05-02 20:19:25 +02:00
Architecture : hcloud . Architecture ( architecture ) ,
Description : hcloud . Ptr ( description ) ,
Labels : labels ,
2024-05-09 18:16:37 +02:00
}
if imageURLString != "" {
imageURL , err := url . Parse ( imageURLString )
if err != nil {
return fmt . Errorf ( "unable to parse url from --%s=%q: %w" , uploadFlagImageURL , imageURLString , err )
}
options . ImageURL = imageURL
} else if imagePathString != "" {
imageFile , err := os . Open ( imagePathString )
if err != nil {
return fmt . Errorf ( "unable to read file from --%s=%q: %w" , uploadFlagImagePath , imagePathString , err )
}
options . ImageReader = imageFile
}
image , err := client . Upload ( ctx , options )
2024-05-02 20:19:25 +02:00
if err != nil {
return fmt . Errorf ( "failed to upload the image: %w" , err )
}
logger . InfoContext ( ctx , "Successfully uploaded the image!" , "image" , image . ID )
return nil
} ,
}
func init ( ) {
rootCmd . AddCommand ( uploadCmd )
2024-05-09 18:16:37 +02:00
uploadCmd . Flags ( ) . String ( uploadFlagImageURL , "" , "Remote URL of the disk image that should be uploaded" )
uploadCmd . Flags ( ) . String ( uploadFlagImagePath , "" , "Local path to the disk image that should be uploaded" )
uploadCmd . MarkFlagsMutuallyExclusive ( uploadFlagImageURL , uploadFlagImagePath )
uploadCmd . MarkFlagsOneRequired ( uploadFlagImageURL , uploadFlagImagePath )
2024-05-02 20:19:25 +02:00
2024-05-09 19:15:54 +02:00
uploadCmd . Flags ( ) . String ( uploadFlagCompression , "" , "Type of compression that was used on the disk image [choices: bz2, xz]" )
2024-05-02 20:19:25 +02:00
_ = uploadCmd . RegisterFlagCompletionFunc (
uploadFlagCompression ,
2024-05-09 19:15:54 +02:00
cobra . FixedCompletions ( [ ] string { string ( hcloudimages . CompressionBZ2 ) , string ( hcloudimages . CompressionXZ ) } , cobra . ShellCompDirectiveNoFileComp ) ,
2024-05-02 20:19:25 +02:00
)
2024-05-09 18:16:37 +02:00
uploadCmd . Flags ( ) . String ( uploadFlagArchitecture , "" , "CPU architecture of the disk image [choices: x86, arm]" )
2024-05-02 20:19:25 +02:00
_ = uploadCmd . RegisterFlagCompletionFunc (
uploadFlagArchitecture ,
cobra . FixedCompletions ( [ ] string { string ( hcloud . ArchitectureX86 ) , string ( hcloud . ArchitectureARM ) } , cobra . ShellCompDirectiveNoFileComp ) ,
)
_ = uploadCmd . MarkFlagRequired ( uploadFlagArchitecture )
2024-05-09 18:16:37 +02:00
uploadCmd . Flags ( ) . String ( uploadFlagDescription , "" , "Description for the resulting image" )
2024-05-02 20:19:25 +02:00
2024-05-09 18:16:37 +02:00
uploadCmd . Flags ( ) . StringToString ( uploadFlagLabels , map [ string ] string { } , "Labels for the resulting image" )
2024-05-02 20:19:25 +02:00
}