Skip to content

Commit 6e94d1a

Browse files
committed
feat: select correct image by ARCH
1 parent c3399dc commit 6e94d1a

File tree

2 files changed

+54
-29
lines changed

2 files changed

+54
-29
lines changed

cluster-autoscaler/cloudprovider/hetzner/hetzner_manager.go

Lines changed: 2 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ type hetznerManager struct {
4646
nodeGroups map[string]*hetznerNodeGroup
4747
apiCallContext context.Context
4848
cloudInit string
49-
image *hcloud.Image
49+
image string
5050
sshKey *hcloud.SSHKey
5151
network *hcloud.Network
5252
firewall *hcloud.Firewall
@@ -103,31 +103,6 @@ func newManager() (*hetznerManager, error) {
103103
}
104104
}
105105

106-
// Search for an image ID corresponding to the supplied HCLOUD_IMAGE env
107-
// variable. This value can either be an image ID itself (an int), a name
108-
// (e.g. "ubuntu-20.04"), or a label selector associated with an image
109-
// snapshot. In the latter case it will use the most recent snapshot.
110-
image, _, err := client.Image.Get(ctx, imageName)
111-
if err != nil {
112-
return nil, fmt.Errorf("unable to find image %s: %v", imageName, err)
113-
}
114-
if image == nil {
115-
images, err := client.Image.AllWithOpts(ctx, hcloud.ImageListOpts{
116-
Type: []hcloud.ImageType{hcloud.ImageTypeSnapshot},
117-
Status: []hcloud.ImageStatus{hcloud.ImageStatusAvailable},
118-
Sort: []string{"created:desc"},
119-
ListOpts: hcloud.ListOpts{
120-
LabelSelector: imageName,
121-
},
122-
})
123-
124-
if err != nil || len(images) == 0 {
125-
return nil, fmt.Errorf("unable to find image %s: %v", imageName, err)
126-
}
127-
128-
image = images[0]
129-
}
130-
131106
var sshKey *hcloud.SSHKey
132107
sshKeyName := os.Getenv("HCLOUD_SSH_KEY")
133108
if sshKeyName != "" {
@@ -166,7 +141,7 @@ func newManager() (*hetznerManager, error) {
166141
client: client,
167142
nodeGroups: make(map[string]*hetznerNodeGroup),
168143
cloudInit: string(cloudInit),
169-
image: image,
144+
image: imageName,
170145
sshKey: sshKey,
171146
network: network,
172147
firewall: firewall,

cluster-autoscaler/cloudprovider/hetzner/hetzner_node_group.go

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,10 @@ limitations under the License.
1717
package hetzner
1818

1919
import (
20+
"context"
2021
"fmt"
2122
"math/rand"
23+
"strings"
2224
"sync"
2325
"time"
2426

@@ -380,13 +382,23 @@ func instanceTypeArch(manager *hetznerManager, instanceType string) (string, err
380382
}
381383

382384
func createServer(n *hetznerNodeGroup) error {
385+
serverType, err := n.manager.cachedServerType.getServerType(n.instanceType)
386+
if err != nil {
387+
return err
388+
}
389+
390+
image, err := findImage(n, serverType)
391+
if err != nil {
392+
return err
393+
}
394+
383395
StartAfterCreate := true
384396
opts := hcloud.ServerCreateOpts{
385397
Name: newNodeName(n),
386398
UserData: n.manager.cloudInit,
387399
Location: &hcloud.Location{Name: n.region},
388-
ServerType: &hcloud.ServerType{Name: n.instanceType},
389-
Image: n.manager.image,
400+
ServerType: serverType,
401+
Image: image,
390402
StartAfterCreate: &StartAfterCreate,
391403
Labels: map[string]string{
392404
nodeGroupLabel: n.id,
@@ -423,6 +435,44 @@ func createServer(n *hetznerNodeGroup) error {
423435
return nil
424436
}
425437

438+
// findImage searches for an image ID corresponding to the supplied
439+
// HCLOUD_IMAGE env variable. This value can either be an image ID itself (an
440+
// int), a name (e.g. "ubuntu-20.04"), or a label selector associated with an
441+
// image snapshot. In the latter case it will use the most recent snapshot.
442+
// It also verifies that the returned image has a compatible architecture with
443+
// server.
444+
func findImage(n *hetznerNodeGroup, serverType *hcloud.ServerType) (*hcloud.Image, error) {
445+
// Select correct image based on server type architecture
446+
image, _, err := n.manager.client.Image.GetForArchitecture(context.TODO(), n.manager.image, serverType.Architecture)
447+
if err != nil {
448+
// Keep looking for label if image was not found by id or name
449+
if !strings.HasPrefix(err.Error(), "image not found") {
450+
return nil, err
451+
}
452+
}
453+
454+
if image != nil {
455+
return image, nil
456+
}
457+
458+
// Look for snapshot with label
459+
images, err := n.manager.client.Image.AllWithOpts(context.TODO(), hcloud.ImageListOpts{
460+
Type: []hcloud.ImageType{hcloud.ImageTypeSnapshot},
461+
Status: []hcloud.ImageStatus{hcloud.ImageStatusAvailable},
462+
Sort: []string{"created:desc"},
463+
Architecture: []hcloud.Architecture{serverType.Architecture},
464+
ListOpts: hcloud.ListOpts{
465+
LabelSelector: n.manager.image,
466+
},
467+
})
468+
469+
if err != nil || len(images) == 0 {
470+
return nil, fmt.Errorf("unable to find image %s with architecture %s: %v", n.manager.image, serverType.Architecture, err)
471+
}
472+
473+
return images[0], nil
474+
}
475+
426476
func waitForServerAction(m *hetznerManager, serverName string, action *hcloud.Action) error {
427477
// The implementation of the Hetzner Cloud action client's WatchProgress
428478
// method may be a little puzzling. The following comment thus explains how

0 commit comments

Comments
 (0)