@@ -16,8 +16,9 @@ type InstanceConstraint struct {
16
16
Series string
17
17
Arches []string
18
18
Constraints constraints.Value
19
- DefaultInstanceType string // the default instance type to use if none matches the constraints
20
- DefaultImageId string // the default image to use if none matches the constraints
19
+ DefaultInstanceType string // the instance type to use if multiple matching ones are found
20
+ DefaultImageId string // the image to use if multiple matching ones are found
21
+ OverrideImageId string // ignore any known, published images, use this image
21
22
// Optional filtering criteria not supported by all providers. These attributes are not specified
22
23
// by the user as a constraint but rather passed in by the provider implementation to restrict the
23
24
// choice of available images.
@@ -31,72 +32,44 @@ type InstanceSpec struct {
31
32
Image Image
32
33
}
33
34
34
- // minMemoryHeuristic is the assumed minimum amount of memory (in MB) we prefer in order to run a server (1GB)
35
- const minMemoryHeuristic = 1024
36
-
37
35
// FindInstanceSpec returns an InstanceSpec satisfying the supplied InstanceConstraint.
38
- // r has been set up to read from a file containing Ubuntu cloud guest images availability data. A query
39
- // interface for EC2 images is exposed at http://cloud-images.ubuntu.com/query. Other cloud providers may
40
- // provide similar files for their own images. e.g. the Openstack provider has been configured to look for
41
- // cloud image availability files in the cloud's control and public storage containers.
42
- // For more information on the image availability file format, see https://help.ubuntu.com/community/UEC/Images.
36
+ // possibleImages contains a list of images matching the InstanceConstraint.
43
37
// allInstanceTypes provides information on every known available instance type (name, memory, cpu cores etc) on
44
- // which instances can be run.
38
+ // which instances can be run. The InstanceConstraint is used to filter allInstanceTypes and then a suitable image
39
+ // compatible with the matching instance types is returned.
45
40
func FindInstanceSpec (possibleImages []Image , ic * InstanceConstraint , allInstanceTypes []InstanceType ) (* InstanceSpec , error ) {
46
41
matchingTypes , err := getMatchingInstanceTypes (ic , allInstanceTypes )
47
42
if err != nil {
48
- // There are no instance types matching the supplied constraints. If the user has specifically
49
- // asked for a nominated default instance type to be used as a fallback and that is invalid, we
50
- // report the error. Otherwise we continue to look for an instance type that we can use as a last resort.
51
- if len (allInstanceTypes ) == 0 || ic .DefaultInstanceType != "" {
52
- return nil , err
53
- }
54
- // No matching instance types were found, so the fallback is to:
55
- // 1. Sort by memory and find the smallest matching both the required architecture
56
- // and our own heuristic: minimum amount of memory required to run a realistic server, or
57
- // 2. Sort by memory in reverse order and return the largest one, which will hopefully work,
58
- // albeit not the best match
59
-
60
- archCons := & InstanceConstraint {Arches : ic .Arches }
61
- fallbackTypes , fberr := getMatchingInstanceTypes (archCons , allInstanceTypes )
62
- // If there's an error getting the fallback instance, return the original error.
63
- if fberr != nil {
64
- return nil , err
65
- }
66
- sort .Sort (byMemory (fallbackTypes ))
67
- // 1. check for smallest instance type that can realistically run a server
68
- for _ , itype := range fallbackTypes {
69
- if itype .Mem >= minMemoryHeuristic {
70
- matchingTypes = []InstanceType {itype }
71
- break
72
- }
73
- }
74
- if len (matchingTypes ) == 0 {
75
- // 2. just get the one with the largest memory
76
- matchingTypes = []InstanceType {fallbackTypes [len (fallbackTypes )- 1 ]}
77
- }
43
+ return nil , err
78
44
}
79
45
80
46
sort .Sort (byArch (possibleImages ))
81
47
for _ , itype := range matchingTypes {
48
+ typeMatch := false
82
49
for _ , image := range possibleImages {
83
50
if image .match (itype ) {
84
- return & InstanceSpec {itype .Id , itype .Name , image }, nil
51
+ typeMatch = true
52
+ if ic .DefaultImageId == "" || ic .DefaultImageId == image .Id {
53
+ return & InstanceSpec {itype .Id , itype .Name , image }, nil
54
+ }
85
55
}
86
56
}
57
+ if typeMatch && ic .DefaultImageId != "" {
58
+ return nil , fmt .Errorf ("invalid default image id %q" , ic .DefaultImageId )
59
+ }
87
60
}
88
- // if no matching image is found for whatever reason, use the default if one is specified.
89
- if ic .DefaultImageId != "" && len (matchingTypes ) > 0 {
61
+ // if no matching image is found for whatever reason, use the override if one is specified.
62
+ if ic .OverrideImageId != "" && len (matchingTypes ) > 0 {
90
63
spec := & InstanceSpec {
91
64
InstanceTypeId : matchingTypes [0 ].Id ,
92
65
InstanceTypeName : matchingTypes [0 ].Name ,
93
- Image : Image {Id : ic .DefaultImageId , Arch : ic .Arches [0 ]},
66
+ Image : Image {Id : ic .OverrideImageId , Arch : ic .Arches [0 ]},
94
67
}
95
68
return spec , nil
96
69
}
97
70
98
71
if len (possibleImages ) == 0 || len (matchingTypes ) == 0 {
99
- return nil , fmt .Errorf ("no %q images in %s with arches %s, and no default specified" ,
72
+ return nil , fmt .Errorf ("no %q images in %s with arches %s, and no override specified" ,
100
73
ic .Series , ic .Region , ic .Arches )
101
74
}
102
75
@@ -107,15 +80,6 @@ func FindInstanceSpec(possibleImages []Image, ic *InstanceConstraint, allInstanc
107
80
return nil , fmt .Errorf ("no %q images in %s matching instance types %v" , ic .Series , ic .Region , names )
108
81
}
109
82
110
- //byMemory is used to sort a slice of instance types by the amount of RAM they have.
111
- type byMemory []InstanceType
112
-
113
- func (s byMemory ) Len () int { return len (s ) }
114
- func (s byMemory ) Swap (i , j int ) { s [i ], s [j ] = s [j ], s [i ] }
115
- func (s byMemory ) Less (i , j int ) bool {
116
- return s [i ].Mem < s [j ].Mem
117
- }
118
-
119
83
// Image holds the attributes that vary amongst relevant images for
120
84
// a given series in a given region.
121
85
type Image struct {
0 commit comments