feat: select correct image by ARCH

This commit is contained in:
Julian Tölle 2023-03-23 15:45:52 +01:00
parent c3399dcbc1
commit 6e94d1a84a
No known key found for this signature in database
GPG Key ID: 23645912EA28C2DB
2 changed files with 54 additions and 29 deletions

View File

@ -46,7 +46,7 @@ type hetznerManager struct {
nodeGroups map[string]*hetznerNodeGroup
apiCallContext context.Context
cloudInit string
image *hcloud.Image
image string
sshKey *hcloud.SSHKey
network *hcloud.Network
firewall *hcloud.Firewall
@ -103,31 +103,6 @@ func newManager() (*hetznerManager, error) {
}
}
// Search for an image ID corresponding to the supplied HCLOUD_IMAGE env
// variable. This value can either be an image ID itself (an int), a name
// (e.g. "ubuntu-20.04"), or a label selector associated with an image
// snapshot. In the latter case it will use the most recent snapshot.
image, _, err := client.Image.Get(ctx, imageName)
if err != nil {
return nil, fmt.Errorf("unable to find image %s: %v", imageName, err)
}
if image == nil {
images, err := client.Image.AllWithOpts(ctx, hcloud.ImageListOpts{
Type: []hcloud.ImageType{hcloud.ImageTypeSnapshot},
Status: []hcloud.ImageStatus{hcloud.ImageStatusAvailable},
Sort: []string{"created:desc"},
ListOpts: hcloud.ListOpts{
LabelSelector: imageName,
},
})
if err != nil || len(images) == 0 {
return nil, fmt.Errorf("unable to find image %s: %v", imageName, err)
}
image = images[0]
}
var sshKey *hcloud.SSHKey
sshKeyName := os.Getenv("HCLOUD_SSH_KEY")
if sshKeyName != "" {
@ -166,7 +141,7 @@ func newManager() (*hetznerManager, error) {
client: client,
nodeGroups: make(map[string]*hetznerNodeGroup),
cloudInit: string(cloudInit),
image: image,
image: imageName,
sshKey: sshKey,
network: network,
firewall: firewall,

View File

@ -17,8 +17,10 @@ limitations under the License.
package hetzner
import (
"context"
"fmt"
"math/rand"
"strings"
"sync"
"time"
@ -380,13 +382,23 @@ func instanceTypeArch(manager *hetznerManager, instanceType string) (string, err
}
func createServer(n *hetznerNodeGroup) error {
serverType, err := n.manager.cachedServerType.getServerType(n.instanceType)
if err != nil {
return err
}
image, err := findImage(n, serverType)
if err != nil {
return err
}
StartAfterCreate := true
opts := hcloud.ServerCreateOpts{
Name: newNodeName(n),
UserData: n.manager.cloudInit,
Location: &hcloud.Location{Name: n.region},
ServerType: &hcloud.ServerType{Name: n.instanceType},
Image: n.manager.image,
ServerType: serverType,
Image: image,
StartAfterCreate: &StartAfterCreate,
Labels: map[string]string{
nodeGroupLabel: n.id,
@ -423,6 +435,44 @@ func createServer(n *hetznerNodeGroup) error {
return nil
}
// findImage searches for an image ID corresponding to the supplied
// HCLOUD_IMAGE env variable. This value can either be an image ID itself (an
// int), a name (e.g. "ubuntu-20.04"), or a label selector associated with an
// image snapshot. In the latter case it will use the most recent snapshot.
// It also verifies that the returned image has a compatible architecture with
// server.
func findImage(n *hetznerNodeGroup, serverType *hcloud.ServerType) (*hcloud.Image, error) {
// Select correct image based on server type architecture
image, _, err := n.manager.client.Image.GetForArchitecture(context.TODO(), n.manager.image, serverType.Architecture)
if err != nil {
// Keep looking for label if image was not found by id or name
if !strings.HasPrefix(err.Error(), "image not found") {
return nil, err
}
}
if image != nil {
return image, nil
}
// Look for snapshot with label
images, err := n.manager.client.Image.AllWithOpts(context.TODO(), hcloud.ImageListOpts{
Type: []hcloud.ImageType{hcloud.ImageTypeSnapshot},
Status: []hcloud.ImageStatus{hcloud.ImageStatusAvailable},
Sort: []string{"created:desc"},
Architecture: []hcloud.Architecture{serverType.Architecture},
ListOpts: hcloud.ListOpts{
LabelSelector: n.manager.image,
},
})
if err != nil || len(images) == 0 {
return nil, fmt.Errorf("unable to find image %s with architecture %s: %v", n.manager.image, serverType.Architecture, err)
}
return images[0], nil
}
func waitForServerAction(m *hetznerManager, serverName string, action *hcloud.Action) error {
// The implementation of the Hetzner Cloud action client's WatchProgress
// method may be a little puzzling. The following comment thus explains how