Merge lp:~axwalk/gwacl/rolesizes-update into lp:gwacl

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
Reviewer Review Type Date Requested Status
Ian Booth Approve
Review via email: mp+224103@code.launchpad.net

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.
Revision history for this message
Ian Booth (wallyworld) wrote :

I think a type alias would be good.

review: Approve
lp:~axwalk/gwacl/rolesizes-update updated
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 }

Subscribers

People subscribed via source and target branches

to all changes: