Merge lp:~axwalk/gwacl/rolesizes-update into lp:gwacl
- rolesizes-update
- Merge into trunk
Proposed by
Andrew Wilkins
Status: | Merged |
---|---|
Approved by: | Andrew Wilkins |
Approved revision: | 236 |
Merge reported by: | Andrew Wilkins |
Merged at revision: | not available |
Proposed branch: | lp:~axwalk/gwacl/rolesizes-update |
Merge into: | lp:gwacl |
Diff against target: |
512 lines (+370/-100) 2 files modified
rolesizes.go (+332/-98) rolesizes_test.go (+38/-2) |
To merge this branch: | bzr merge lp:~axwalk/gwacl/rolesizes-update |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Ian Booth | Approve | ||
Review via email: mp+224103@code.launchpad.net |
Commit message
Description of the change
Update role sizes
- Add basic tier role sizes.
- Fix OS disk sizes.
- Separate cost from role sizes,
record region-specific costs.
To post a comment you must log in.
- 236. By Andrew Wilkins
-
Add type name for cost unit
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'rolesizes.go' |
2 | --- rolesizes.go 2014-01-31 08:32:00 +0000 |
3 | +++ rolesizes.go 2014-06-24 03:26:22 +0000 |
4 | @@ -5,32 +5,38 @@ |
5 | |
6 | package gwacl |
7 | |
8 | +import ( |
9 | + "fmt" |
10 | +) |
11 | + |
12 | // RoleSize is a representation of the machine specs available in the Azure |
13 | // documentation here: |
14 | -// http://msdn.microsoft.com/en-us/library/windowsazure/dn197896.aspx and |
15 | +// http://msdn.microsoft.com/en-us/library/windowsazure/dn197896.aspx |
16 | // |
17 | // Pricing from here: |
18 | -// http://www.windowsazure.com/en-us/pricing/details/cloud-services/ |
19 | +// http://azure.microsoft.com/en-us/pricing/details/virtual-machines |
20 | // |
21 | // Detailed specifications here: |
22 | -// http://msdn.microsoft.com/en-us/library/windowsazure/dn197896.aspx |
23 | +// http://msdn.microsoft.com/en-us/library/windowsazure/dn197896.aspx |
24 | // |
25 | // Our specifications may be inaccurate or out of date. When in doubt, check! |
26 | // |
27 | // The Disk Space values are only the maxumim permitted; actual space is |
28 | // determined by the OS image being used. |
29 | // |
30 | -// Sizes and costs last updated 2014-01-31. |
31 | +// Sizes and costs last updated 2014-06-23. |
32 | type RoleSize struct { |
33 | - Name string |
34 | - CpuCores uint64 |
35 | - Mem uint64 // In MB |
36 | - OSDiskSpaceCloud uint64 // In MB |
37 | - OSDiskSpaceVirt uint64 // In MB |
38 | - MaxDataDisks uint64 // 1TB each |
39 | - Cost uint64 // USD cents per hour |
40 | + Name string |
41 | + CpuCores uint64 |
42 | + Mem uint64 // In MB |
43 | + OSDiskSpace uint64 // In MB |
44 | + TempDiskSpace uint64 // In MB |
45 | + MaxDataDisks uint64 // 1TB each |
46 | } |
47 | |
48 | +// decicentsPerHour is the unit of cost we store for RoleSizeCost. |
49 | +type decicentsPerHour uint64 |
50 | + |
51 | const ( |
52 | // MB is the unit in which we specify sizes, so it's 1. |
53 | // But please include it anyway, so that units are always explicit. |
54 | @@ -39,94 +45,322 @@ |
55 | TB = 1024 * GB |
56 | ) |
57 | |
58 | -var RoleSizes = []RoleSize{ |
59 | - { |
60 | - Name: "ExtraSmall", |
61 | - CpuCores: 1, // shared |
62 | - Mem: 768 * MB, |
63 | - OSDiskSpaceCloud: 19 * GB, |
64 | - OSDiskSpaceVirt: 20 * GB, |
65 | - MaxDataDisks: 1, |
66 | - Cost: 2, |
67 | - }, { |
68 | - Name: "Small", |
69 | - CpuCores: 1, |
70 | - Mem: 1.75 * GB, |
71 | - OSDiskSpaceCloud: 224 * GB, |
72 | - OSDiskSpaceVirt: 70 * GB, |
73 | - MaxDataDisks: 2, |
74 | - Cost: 8, |
75 | - }, { |
76 | - Name: "Medium", |
77 | - CpuCores: 2, |
78 | - Mem: 3.5 * GB, |
79 | - OSDiskSpaceCloud: 489 * GB, |
80 | - OSDiskSpaceVirt: 135 * GB, |
81 | - MaxDataDisks: 4, |
82 | - Cost: 16, |
83 | - }, { |
84 | - Name: "Large", |
85 | - CpuCores: 4, |
86 | - Mem: 7 * GB, |
87 | - OSDiskSpaceCloud: 999 * GB, |
88 | - OSDiskSpaceVirt: 285 * GB, |
89 | - MaxDataDisks: 8, |
90 | - Cost: 32, |
91 | - }, { |
92 | - Name: "ExtraLarge", |
93 | - CpuCores: 8, |
94 | - Mem: 14 * GB, |
95 | - OSDiskSpaceCloud: 2039 * GB, |
96 | - OSDiskSpaceVirt: 605 * GB, |
97 | - MaxDataDisks: 16, |
98 | - Cost: 64, |
99 | - }, { |
100 | - Name: "A5", |
101 | - CpuCores: 2, |
102 | - Mem: 14 * GB, |
103 | - OSDiskSpaceCloud: 489 * GB, |
104 | - OSDiskSpaceVirt: 135 * GB, |
105 | - MaxDataDisks: 4, |
106 | - Cost: 35, |
107 | - }, { |
108 | - Name: "A6", |
109 | - CpuCores: 4, |
110 | - Mem: 28 * GB, |
111 | - OSDiskSpaceCloud: 999 * GB, |
112 | - OSDiskSpaceVirt: 285 * GB, |
113 | - MaxDataDisks: 8, |
114 | - Cost: 71, |
115 | - }, { |
116 | - Name: "A7", |
117 | - CpuCores: 8, |
118 | - Mem: 56 * GB, |
119 | - OSDiskSpaceCloud: 2039 * GB, |
120 | - OSDiskSpaceVirt: 605 * GB, |
121 | - MaxDataDisks: 16, |
122 | - Cost: 141, |
123 | - }, { |
124 | - Name: "A8", |
125 | - CpuCores: 8, |
126 | - Mem: 56 * GB, |
127 | - OSDiskSpaceCloud: 2039 * GB, // Estimate; not yet announced. |
128 | - OSDiskSpaceVirt: 605 * GB, // Estimate; not yet announced. |
129 | - MaxDataDisks: 16, // Estimate; not yet announced. |
130 | - Cost: 245, |
131 | - }, { |
132 | - Name: "A9", |
133 | - CpuCores: 16, |
134 | - Mem: 112 * GB, |
135 | - OSDiskSpaceCloud: 2039 * GB, // Estimate; not yet announced. |
136 | - OSDiskSpaceVirt: 605 * GB, // Estimate; not yet announced. |
137 | - MaxDataDisks: 16, // Estimate; not yet announced. |
138 | - Cost: 490, |
139 | +// Basic tier roles. |
140 | +var basicRoleSizes = []RoleSize{{ // A0..A4: general purpose |
141 | + Name: "Basic_A0", |
142 | + CpuCores: 1, // shared |
143 | + Mem: 768 * MB, |
144 | + OSDiskSpace: 127 * GB, |
145 | + TempDiskSpace: 20 * GB, |
146 | + MaxDataDisks: 1, |
147 | +}, { |
148 | + Name: "Basic_A1", |
149 | + CpuCores: 1, |
150 | + Mem: 1.75 * GB, |
151 | + OSDiskSpace: 127 * GB, |
152 | + TempDiskSpace: 40 * GB, |
153 | + MaxDataDisks: 2, |
154 | +}, { |
155 | + Name: "Basic_A2", |
156 | + CpuCores: 2, |
157 | + Mem: 3.5 * GB, |
158 | + OSDiskSpace: 127 * GB, |
159 | + TempDiskSpace: 60 * GB, |
160 | + MaxDataDisks: 4, |
161 | +}, { |
162 | + Name: "Basic_A3", |
163 | + CpuCores: 4, |
164 | + Mem: 7 * GB, |
165 | + OSDiskSpace: 127 * GB, |
166 | + TempDiskSpace: 120 * GB, |
167 | + MaxDataDisks: 8, |
168 | +}, { |
169 | + Name: "Basic_A4", |
170 | + CpuCores: 8, |
171 | + Mem: 14 * GB, |
172 | + OSDiskSpace: 127 * GB, |
173 | + TempDiskSpace: 240 * GB, |
174 | + MaxDataDisks: 16, |
175 | +}} |
176 | + |
177 | +// Standard tier roles. |
178 | +var standardRoleSizes = []RoleSize{{ // A0..A4: general purpose |
179 | + Name: "ExtraSmall", // A0 |
180 | + CpuCores: 1, // shared |
181 | + Mem: 768 * MB, |
182 | + OSDiskSpace: 127 * GB, |
183 | + TempDiskSpace: 20 * GB, |
184 | + MaxDataDisks: 1, |
185 | +}, { |
186 | + Name: "Small", // A1 |
187 | + CpuCores: 1, |
188 | + Mem: 1.75 * GB, |
189 | + OSDiskSpace: 127 * GB, |
190 | + TempDiskSpace: 70 * GB, |
191 | + MaxDataDisks: 2, |
192 | +}, { |
193 | + Name: "Medium", // A2 |
194 | + CpuCores: 2, |
195 | + Mem: 3.5 * GB, |
196 | + OSDiskSpace: 127 * GB, |
197 | + TempDiskSpace: 135 * GB, |
198 | + MaxDataDisks: 4, |
199 | +}, { |
200 | + Name: "Large", // A3 |
201 | + CpuCores: 4, |
202 | + Mem: 7 * GB, |
203 | + OSDiskSpace: 127 * GB, |
204 | + TempDiskSpace: 285 * GB, |
205 | + MaxDataDisks: 8, |
206 | +}, { |
207 | + Name: "ExtraLarge", // A4 |
208 | + CpuCores: 8, |
209 | + Mem: 14 * GB, |
210 | + OSDiskSpace: 127 * GB, |
211 | + TempDiskSpace: 605 * GB, |
212 | + MaxDataDisks: 16, |
213 | +}, { // A5..A7: memory intensive |
214 | + Name: "A5", |
215 | + CpuCores: 2, |
216 | + Mem: 14 * GB, |
217 | + OSDiskSpace: 127 * GB, |
218 | + TempDiskSpace: 135 * GB, |
219 | + MaxDataDisks: 4, |
220 | +}, { |
221 | + Name: "A6", |
222 | + CpuCores: 4, |
223 | + Mem: 28 * GB, |
224 | + OSDiskSpace: 127 * GB, |
225 | + TempDiskSpace: 285 * GB, |
226 | + MaxDataDisks: 8, |
227 | +}, { |
228 | + Name: "A7", |
229 | + CpuCores: 8, |
230 | + Mem: 56 * GB, |
231 | + OSDiskSpace: 127 * GB, |
232 | + TempDiskSpace: 605 * GB, |
233 | + MaxDataDisks: 16, |
234 | +}, { // A8..A9: compute intensive |
235 | + Name: "A8", |
236 | + CpuCores: 8, |
237 | + Mem: 56 * GB, |
238 | + OSDiskSpace: 127 * GB, |
239 | + TempDiskSpace: 382 * GB, |
240 | + MaxDataDisks: 16, |
241 | +}, { |
242 | + Name: "A9", |
243 | + CpuCores: 16, |
244 | + Mem: 112 * GB, |
245 | + OSDiskSpace: 127 * GB, |
246 | + TempDiskSpace: 382 * GB, |
247 | + MaxDataDisks: 16, |
248 | +}} |
249 | + |
250 | +// RoleSizes describes all known role sizes. |
251 | +var RoleSizes = append(append([]RoleSize{}, basicRoleSizes...), standardRoleSizes...) |
252 | + |
253 | +var allRegionRoleCosts = map[string]map[string]decicentsPerHour{ |
254 | + "East US": { |
255 | + "Basic_A0": 18, |
256 | + "Basic_A1": 44, |
257 | + "Basic_A2": 88, |
258 | + "Basic_A3": 176, |
259 | + "Basic_A4": 352, |
260 | + "ExtraSmall": 20, |
261 | + "Small": 60, |
262 | + "Medium": 120, |
263 | + "Large": 240, |
264 | + "ExtraLarge": 480, |
265 | + "A5": 250, |
266 | + "A6": 500, |
267 | + "A7": 1000, |
268 | + "A8": 1970, |
269 | + "A9": 4470, |
270 | + }, |
271 | + "West US": { |
272 | + "Basic_A0": 18, |
273 | + "Basic_A1": 47, |
274 | + "Basic_A2": 94, |
275 | + "Basic_A3": 188, |
276 | + "Basic_A4": 376, |
277 | + "ExtraSmall": 20, |
278 | + "Small": 60, |
279 | + "Medium": 120, |
280 | + "Large": 240, |
281 | + "ExtraLarge": 480, |
282 | + "A5": 250, |
283 | + "A6": 500, |
284 | + "A7": 1000, |
285 | + "A8": 1970, |
286 | + "A9": 4470, |
287 | + }, |
288 | + "North Central US": { |
289 | + "Basic_A0": 18, |
290 | + "Basic_A1": 47, |
291 | + "Basic_A2": 94, |
292 | + "Basic_A3": 188, |
293 | + "Basic_A4": 376, |
294 | + "ExtraSmall": 20, |
295 | + "Small": 60, |
296 | + "Medium": 120, |
297 | + "Large": 240, |
298 | + "ExtraLarge": 480, |
299 | + "A5": 250, |
300 | + "A6": 500, |
301 | + "A7": 1000, |
302 | + "A8": 1970, |
303 | + "A9": 4470, |
304 | + }, |
305 | + "South Central US": { |
306 | + "Basic_A0": 18, |
307 | + "Basic_A1": 44, |
308 | + "Basic_A2": 88, |
309 | + "Basic_A3": 176, |
310 | + "Basic_A4": 352, |
311 | + "ExtraSmall": 20, |
312 | + "Small": 60, |
313 | + "Medium": 120, |
314 | + "Large": 240, |
315 | + "ExtraLarge": 480, |
316 | + "A5": 220, |
317 | + "A6": 440, |
318 | + "A7": 880, |
319 | + "A8": 1970, |
320 | + "A9": 4470, |
321 | + }, |
322 | + "North Europe": { |
323 | + "Basic_A0": 18, |
324 | + "Basic_A1": 47, |
325 | + "Basic_A2": 94, |
326 | + "Basic_A3": 188, |
327 | + "Basic_A4": 376, |
328 | + "ExtraSmall": 20, |
329 | + "Small": 60, |
330 | + "Medium": 120, |
331 | + "Large": 240, |
332 | + "ExtraLarge": 480, |
333 | + "A5": 248, |
334 | + "A6": 496, |
335 | + "A7": 992, |
336 | + "A8": 1970, |
337 | + "A9": 4470, |
338 | + }, |
339 | + "West Europe": { |
340 | + "Basic_A0": 18, |
341 | + "Basic_A1": 51, |
342 | + "Basic_A2": 102, |
343 | + "Basic_A3": 204, |
344 | + "Basic_A4": 408, |
345 | + "ExtraSmall": 20, |
346 | + "Small": 60, |
347 | + "Medium": 120, |
348 | + "Large": 240, |
349 | + "ExtraLarge": 480, |
350 | + "A5": 270, |
351 | + "A6": 540, |
352 | + "A7": 1080, |
353 | + "A8": 1970, |
354 | + "A9": 4470, |
355 | + }, |
356 | + "Southeast Asia": { |
357 | + "Basic_A0": 18, |
358 | + "Basic_A1": 58, |
359 | + "Basic_A2": 116, |
360 | + "Basic_A3": 232, |
361 | + "Basic_A4": 464, |
362 | + "ExtraSmall": 20, |
363 | + "Small": 60, |
364 | + "Medium": 120, |
365 | + "Large": 240, |
366 | + "ExtraLarge": 480, |
367 | + "A5": 270, |
368 | + "A6": 540, |
369 | + "A7": 1080, |
370 | + "A8": 1970, |
371 | + "A9": 4470, |
372 | + }, |
373 | + "East Asia": { |
374 | + "Basic_A0": 18, |
375 | + "Basic_A1": 58, |
376 | + "Basic_A2": 116, |
377 | + "Basic_A3": 232, |
378 | + "Basic_A4": 464, |
379 | + "ExtraSmall": 20, |
380 | + "Small": 60, |
381 | + "Medium": 120, |
382 | + "Large": 240, |
383 | + "ExtraLarge": 480, |
384 | + "A5": 294, |
385 | + "A6": 588, |
386 | + "A7": 1176, |
387 | + "A8": 1970, |
388 | + "A9": 4470, |
389 | + }, |
390 | + "Japan East": { |
391 | + "Basic_A0": 18, |
392 | + "Basic_A1": 69, |
393 | + "Basic_A2": 138, |
394 | + "Basic_A3": 276, |
395 | + "Basic_A4": 552, |
396 | + "ExtraSmall": 27, |
397 | + "Small": 81, |
398 | + "Medium": 162, |
399 | + "Large": 324, |
400 | + "ExtraLarge": 648, |
401 | + "A5": 281, |
402 | + "A6": 562, |
403 | + "A7": 1124, |
404 | + "A8": 1970, |
405 | + "A9": 4470, |
406 | + }, |
407 | + "Japan West": { |
408 | + "Basic_A0": 18, |
409 | + "Basic_A1": 61, |
410 | + "Basic_A2": 122, |
411 | + "Basic_A3": 244, |
412 | + "Basic_A4": 488, |
413 | + "ExtraSmall": 25, |
414 | + "Small": 73, |
415 | + "Medium": 146, |
416 | + "Large": 292, |
417 | + "ExtraLarge": 584, |
418 | + "A5": 258, |
419 | + "A6": 516, |
420 | + "A7": 1032, |
421 | + "A8": 1970, |
422 | + "A9": 4470, |
423 | + }, |
424 | + "Brazil South": { |
425 | + "Basic_A0": 22, |
426 | + "Basic_A1": 58, |
427 | + "Basic_A2": 116, |
428 | + "Basic_A3": 232, |
429 | + "Basic_A4": 464, |
430 | + "ExtraSmall": 27, |
431 | + "Small": 80, |
432 | + "Medium": 160, |
433 | + "Large": 320, |
434 | + "ExtraLarge": 640, |
435 | + "A5": 291, |
436 | + "A6": 582, |
437 | + "A7": 1164, |
438 | + "A8": 1970, |
439 | + "A9": 4470, |
440 | }, |
441 | } |
442 | |
443 | -var RoleNameMap map[string]RoleSize = make(map[string]RoleSize) |
444 | - |
445 | -func init() { |
446 | - for _, rolesize := range RoleSizes { |
447 | - RoleNameMap[rolesize.Name] = rolesize |
448 | - } |
449 | +// RoleSizeCost returns the cost associated with the given role size and region. |
450 | +func RoleSizeCost(region string, roleSize string) (decicentsPerHour uint64, err error) { |
451 | + costs, ok := allRegionRoleCosts[region] |
452 | + if !ok { |
453 | + return 0, fmt.Errorf("no cost data for region %q", region) |
454 | + } |
455 | + cost, ok := costs[roleSize] |
456 | + if ok { |
457 | + return uint64(cost), nil |
458 | + } |
459 | + return 0, fmt.Errorf( |
460 | + "no cost data for role size %q in region %q", |
461 | + roleSize, region, |
462 | + ) |
463 | } |
464 | |
465 | === modified file 'rolesizes_test.go' |
466 | --- rolesizes_test.go 2013-07-22 03:46:15 +0000 |
467 | +++ rolesizes_test.go 2014-06-24 03:26:22 +0000 |
468 | @@ -11,6 +11,42 @@ |
469 | |
470 | var _ = Suite(&rolesizeSuite{}) |
471 | |
472 | -func (suite *rolesizeSuite) TestMapIsCreated(c *C) { |
473 | - c.Check(RoleNameMap, HasLen, len(RoleSizes)) |
474 | +var knownRegions = []string{ |
475 | + "East US", |
476 | + "West US", |
477 | + "North Central US", |
478 | + "South Central US", |
479 | + "North Europe", |
480 | + "West Europe", |
481 | + "Southeast Asia", |
482 | + "East Asia", |
483 | + "Japan East", |
484 | + "Japan West", |
485 | + "Brazil South", |
486 | +} |
487 | + |
488 | +var knownSizes = []string{ |
489 | + "Basic_A0", "Basic_A1", "Basic_A2", "Basic_A3", "Basic_A4", |
490 | + "ExtraSmall", "Small", "Medium", "Large", "ExtraLarge", |
491 | + "A5", "A6", "A7", "A8", "A9", |
492 | +} |
493 | + |
494 | +func (suite *rolesizeSuite) TestRoleCostKnownRegions(c *C) { |
495 | + for _, region := range knownRegions { |
496 | + for _, roleSize := range knownSizes { |
497 | + cost, err := RoleSizeCost(region, roleSize) |
498 | + c.Check(err, IsNil) |
499 | + c.Check(cost, Not(Equals), uint64(0)) |
500 | + } |
501 | + } |
502 | +} |
503 | + |
504 | +func (suite *rolesizeSuite) TestRoleCostUnknownRegion(c *C) { |
505 | + _, err := RoleSizeCost("Eastasia", "A0") |
506 | + c.Assert(err, ErrorMatches, `no cost data for region "Eastasia"`) |
507 | +} |
508 | + |
509 | +func (suite *rolesizeSuite) TestRoleCostUnknownRoleSize(c *C) { |
510 | + _, err := RoleSizeCost("East US", "A10") |
511 | + c.Assert(err, ErrorMatches, `no cost data for role size "A10" in region "East US"`) |
512 | } |
I think a type alias would be good.