-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathimage.go
86 lines (76 loc) · 2.75 KB
/
image.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
// Copyright 2013 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.
package openstack
import (
"gopkg.in/goose.v2/nova"
"github.com/juju/juju/environs/imagemetadata"
"github.com/juju/juju/environs/instances"
)
// FlavorFilter is an interface that can control which server flavors
// are acceptable.
type FlavorFilter interface {
// AcceptFlavor returns true iff the given flavor is acceptable.
AcceptFlavor(nova.FlavorDetail) bool
}
// FlavorFilterFunc is a function type that implements FlavorFilter.
type FlavorFilterFunc func(nova.FlavorDetail) bool
// AcceptFlavor is part of the FlavorFilter interface.
func (f FlavorFilterFunc) AcceptFlavor(d nova.FlavorDetail) bool {
return f(d)
}
// AcceptAllFlavors is a function that returns true for any input,
// and can be assigned to a value of type FlavorFilterFunc.
func AcceptAllFlavors(nova.FlavorDetail) bool {
return true
}
// findInstanceSpec returns an image and instance type satisfying the constraint.
// The instance type comes from querying the flavors supported by the deployment.
func findInstanceSpec(
e *Environ,
ic *instances.InstanceConstraint,
imageMetadata []*imagemetadata.ImageMetadata,
) (*instances.InstanceSpec, error) {
// First construct all available instance types from the supported flavors.
nova := e.nova()
flavors, err := nova.ListFlavorsDetail()
if err != nil {
return nil, err
}
// Not all needed information is available in flavors,
// for e.g. architectures or virtualisation types.
// For these properties, we assume that all instance types support
// all values.
allInstanceTypes := []instances.InstanceType{}
for _, flavor := range flavors {
if !e.flavorFilter.AcceptFlavor(flavor) {
continue
}
instanceType := instances.InstanceType{
Id: flavor.Id,
Name: flavor.Name,
Arches: ic.Arches,
Mem: uint64(flavor.RAM),
CpuCores: uint64(flavor.VCPUs),
RootDisk: uint64(flavor.Disk * 1024),
// tags not currently supported on openstack
}
if ic.Constraints.HasVirtType() {
// Instance Type virtual type depends on the virtual type of the selected image, i.e.
// picking an image with a virt type gives a machine with this virt type.
instanceType.VirtType = ic.Constraints.VirtType
}
allInstanceTypes = append(allInstanceTypes, instanceType)
}
images := instances.ImageMetadataToImages(imageMetadata)
spec, err := instances.FindInstanceSpec(images, ic, allInstanceTypes)
if err != nil {
return nil, err
}
// If instance constraints did not have a virtualisation type,
// but image metadata did, we will have an instance type
// with virtualisation type of an image.
if !ic.Constraints.HasVirtType() && spec.Image.VirtType != "" {
spec.InstanceType.VirtType = &spec.Image.VirtType
}
return spec, nil
}