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
=== modified file 'rolesizes.go'
--- rolesizes.go 2014-01-31 08:32:00 +0000
+++ rolesizes.go 2014-06-24 03:26:22 +0000
@@ -5,32 +5,38 @@
55
6package gwacl6package gwacl
77
8import (
9 "fmt"
10)
11
8// RoleSize is a representation of the machine specs available in the Azure12// RoleSize is a representation of the machine specs available in the Azure
9// documentation here:13// documentation here:
10// http://msdn.microsoft.com/en-us/library/windowsazure/dn197896.aspx and14// http://msdn.microsoft.com/en-us/library/windowsazure/dn197896.aspx
11//15//
12// Pricing from here:16// Pricing from here:
13// http://www.windowsazure.com/en-us/pricing/details/cloud-services/17// http://azure.microsoft.com/en-us/pricing/details/virtual-machines
14//18//
15// Detailed specifications here:19// Detailed specifications here:
16// http://msdn.microsoft.com/en-us/library/windowsazure/dn197896.aspx20// http://msdn.microsoft.com/en-us/library/windowsazure/dn197896.aspx
17//21//
18// Our specifications may be inaccurate or out of date. When in doubt, check!22// Our specifications may be inaccurate or out of date. When in doubt, check!
19//23//
20// The Disk Space values are only the maxumim permitted; actual space is24// The Disk Space values are only the maxumim permitted; actual space is
21// determined by the OS image being used.25// determined by the OS image being used.
22//26//
23// Sizes and costs last updated 2014-01-31.27// Sizes and costs last updated 2014-06-23.
24type RoleSize struct {28type RoleSize struct {
25 Name string29 Name string
26 CpuCores uint6430 CpuCores uint64
27 Mem uint64 // In MB31 Mem uint64 // In MB
28 OSDiskSpaceCloud uint64 // In MB32 OSDiskSpace uint64 // In MB
29 OSDiskSpaceVirt uint64 // In MB33 TempDiskSpace uint64 // In MB
30 MaxDataDisks uint64 // 1TB each34 MaxDataDisks uint64 // 1TB each
31 Cost uint64 // USD cents per hour
32}35}
3336
37// decicentsPerHour is the unit of cost we store for RoleSizeCost.
38type decicentsPerHour uint64
39
34const (40const (
35 // MB is the unit in which we specify sizes, so it's 1.41 // MB is the unit in which we specify sizes, so it's 1.
36 // But please include it anyway, so that units are always explicit.42 // But please include it anyway, so that units are always explicit.
@@ -39,94 +45,322 @@
39 TB = 1024 * GB45 TB = 1024 * GB
40)46)
4147
42var RoleSizes = []RoleSize{48// Basic tier roles.
43 {49var basicRoleSizes = []RoleSize{{ // A0..A4: general purpose
44 Name: "ExtraSmall",50 Name: "Basic_A0",
45 CpuCores: 1, // shared51 CpuCores: 1, // shared
46 Mem: 768 * MB,52 Mem: 768 * MB,
47 OSDiskSpaceCloud: 19 * GB,53 OSDiskSpace: 127 * GB,
48 OSDiskSpaceVirt: 20 * GB,54 TempDiskSpace: 20 * GB,
49 MaxDataDisks: 1,55 MaxDataDisks: 1,
50 Cost: 2,56}, {
51 }, {57 Name: "Basic_A1",
52 Name: "Small",58 CpuCores: 1,
53 CpuCores: 1,59 Mem: 1.75 * GB,
54 Mem: 1.75 * GB,60 OSDiskSpace: 127 * GB,
55 OSDiskSpaceCloud: 224 * GB,61 TempDiskSpace: 40 * GB,
56 OSDiskSpaceVirt: 70 * GB,62 MaxDataDisks: 2,
57 MaxDataDisks: 2,63}, {
58 Cost: 8,64 Name: "Basic_A2",
59 }, {65 CpuCores: 2,
60 Name: "Medium",66 Mem: 3.5 * GB,
61 CpuCores: 2,67 OSDiskSpace: 127 * GB,
62 Mem: 3.5 * GB,68 TempDiskSpace: 60 * GB,
63 OSDiskSpaceCloud: 489 * GB,69 MaxDataDisks: 4,
64 OSDiskSpaceVirt: 135 * GB,70}, {
65 MaxDataDisks: 4,71 Name: "Basic_A3",
66 Cost: 16,72 CpuCores: 4,
67 }, {73 Mem: 7 * GB,
68 Name: "Large",74 OSDiskSpace: 127 * GB,
69 CpuCores: 4,75 TempDiskSpace: 120 * GB,
70 Mem: 7 * GB,76 MaxDataDisks: 8,
71 OSDiskSpaceCloud: 999 * GB,77}, {
72 OSDiskSpaceVirt: 285 * GB,78 Name: "Basic_A4",
73 MaxDataDisks: 8,79 CpuCores: 8,
74 Cost: 32,80 Mem: 14 * GB,
75 }, {81 OSDiskSpace: 127 * GB,
76 Name: "ExtraLarge",82 TempDiskSpace: 240 * GB,
77 CpuCores: 8,83 MaxDataDisks: 16,
78 Mem: 14 * GB,84}}
79 OSDiskSpaceCloud: 2039 * GB,85
80 OSDiskSpaceVirt: 605 * GB,86// Standard tier roles.
81 MaxDataDisks: 16,87var standardRoleSizes = []RoleSize{{ // A0..A4: general purpose
82 Cost: 64,88 Name: "ExtraSmall", // A0
83 }, {89 CpuCores: 1, // shared
84 Name: "A5",90 Mem: 768 * MB,
85 CpuCores: 2,91 OSDiskSpace: 127 * GB,
86 Mem: 14 * GB,92 TempDiskSpace: 20 * GB,
87 OSDiskSpaceCloud: 489 * GB,93 MaxDataDisks: 1,
88 OSDiskSpaceVirt: 135 * GB,94}, {
89 MaxDataDisks: 4,95 Name: "Small", // A1
90 Cost: 35,96 CpuCores: 1,
91 }, {97 Mem: 1.75 * GB,
92 Name: "A6",98 OSDiskSpace: 127 * GB,
93 CpuCores: 4,99 TempDiskSpace: 70 * GB,
94 Mem: 28 * GB,100 MaxDataDisks: 2,
95 OSDiskSpaceCloud: 999 * GB,101}, {
96 OSDiskSpaceVirt: 285 * GB,102 Name: "Medium", // A2
97 MaxDataDisks: 8,103 CpuCores: 2,
98 Cost: 71,104 Mem: 3.5 * GB,
99 }, {105 OSDiskSpace: 127 * GB,
100 Name: "A7",106 TempDiskSpace: 135 * GB,
101 CpuCores: 8,107 MaxDataDisks: 4,
102 Mem: 56 * GB,108}, {
103 OSDiskSpaceCloud: 2039 * GB,109 Name: "Large", // A3
104 OSDiskSpaceVirt: 605 * GB,110 CpuCores: 4,
105 MaxDataDisks: 16,111 Mem: 7 * GB,
106 Cost: 141,112 OSDiskSpace: 127 * GB,
107 }, {113 TempDiskSpace: 285 * GB,
108 Name: "A8",114 MaxDataDisks: 8,
109 CpuCores: 8,115}, {
110 Mem: 56 * GB,116 Name: "ExtraLarge", // A4
111 OSDiskSpaceCloud: 2039 * GB, // Estimate; not yet announced.117 CpuCores: 8,
112 OSDiskSpaceVirt: 605 * GB, // Estimate; not yet announced.118 Mem: 14 * GB,
113 MaxDataDisks: 16, // Estimate; not yet announced.119 OSDiskSpace: 127 * GB,
114 Cost: 245,120 TempDiskSpace: 605 * GB,
115 }, {121 MaxDataDisks: 16,
116 Name: "A9",122}, { // A5..A7: memory intensive
117 CpuCores: 16,123 Name: "A5",
118 Mem: 112 * GB,124 CpuCores: 2,
119 OSDiskSpaceCloud: 2039 * GB, // Estimate; not yet announced.125 Mem: 14 * GB,
120 OSDiskSpaceVirt: 605 * GB, // Estimate; not yet announced.126 OSDiskSpace: 127 * GB,
121 MaxDataDisks: 16, // Estimate; not yet announced.127 TempDiskSpace: 135 * GB,
122 Cost: 490,128 MaxDataDisks: 4,
129}, {
130 Name: "A6",
131 CpuCores: 4,
132 Mem: 28 * GB,
133 OSDiskSpace: 127 * GB,
134 TempDiskSpace: 285 * GB,
135 MaxDataDisks: 8,
136}, {
137 Name: "A7",
138 CpuCores: 8,
139 Mem: 56 * GB,
140 OSDiskSpace: 127 * GB,
141 TempDiskSpace: 605 * GB,
142 MaxDataDisks: 16,
143}, { // A8..A9: compute intensive
144 Name: "A8",
145 CpuCores: 8,
146 Mem: 56 * GB,
147 OSDiskSpace: 127 * GB,
148 TempDiskSpace: 382 * GB,
149 MaxDataDisks: 16,
150}, {
151 Name: "A9",
152 CpuCores: 16,
153 Mem: 112 * GB,
154 OSDiskSpace: 127 * GB,
155 TempDiskSpace: 382 * GB,
156 MaxDataDisks: 16,
157}}
158
159// RoleSizes describes all known role sizes.
160var RoleSizes = append(append([]RoleSize{}, basicRoleSizes...), standardRoleSizes...)
161
162var allRegionRoleCosts = map[string]map[string]decicentsPerHour{
163 "East US": {
164 "Basic_A0": 18,
165 "Basic_A1": 44,
166 "Basic_A2": 88,
167 "Basic_A3": 176,
168 "Basic_A4": 352,
169 "ExtraSmall": 20,
170 "Small": 60,
171 "Medium": 120,
172 "Large": 240,
173 "ExtraLarge": 480,
174 "A5": 250,
175 "A6": 500,
176 "A7": 1000,
177 "A8": 1970,
178 "A9": 4470,
179 },
180 "West US": {
181 "Basic_A0": 18,
182 "Basic_A1": 47,
183 "Basic_A2": 94,
184 "Basic_A3": 188,
185 "Basic_A4": 376,
186 "ExtraSmall": 20,
187 "Small": 60,
188 "Medium": 120,
189 "Large": 240,
190 "ExtraLarge": 480,
191 "A5": 250,
192 "A6": 500,
193 "A7": 1000,
194 "A8": 1970,
195 "A9": 4470,
196 },
197 "North Central US": {
198 "Basic_A0": 18,
199 "Basic_A1": 47,
200 "Basic_A2": 94,
201 "Basic_A3": 188,
202 "Basic_A4": 376,
203 "ExtraSmall": 20,
204 "Small": 60,
205 "Medium": 120,
206 "Large": 240,
207 "ExtraLarge": 480,
208 "A5": 250,
209 "A6": 500,
210 "A7": 1000,
211 "A8": 1970,
212 "A9": 4470,
213 },
214 "South Central US": {
215 "Basic_A0": 18,
216 "Basic_A1": 44,
217 "Basic_A2": 88,
218 "Basic_A3": 176,
219 "Basic_A4": 352,
220 "ExtraSmall": 20,
221 "Small": 60,
222 "Medium": 120,
223 "Large": 240,
224 "ExtraLarge": 480,
225 "A5": 220,
226 "A6": 440,
227 "A7": 880,
228 "A8": 1970,
229 "A9": 4470,
230 },
231 "North Europe": {
232 "Basic_A0": 18,
233 "Basic_A1": 47,
234 "Basic_A2": 94,
235 "Basic_A3": 188,
236 "Basic_A4": 376,
237 "ExtraSmall": 20,
238 "Small": 60,
239 "Medium": 120,
240 "Large": 240,
241 "ExtraLarge": 480,
242 "A5": 248,
243 "A6": 496,
244 "A7": 992,
245 "A8": 1970,
246 "A9": 4470,
247 },
248 "West Europe": {
249 "Basic_A0": 18,
250 "Basic_A1": 51,
251 "Basic_A2": 102,
252 "Basic_A3": 204,
253 "Basic_A4": 408,
254 "ExtraSmall": 20,
255 "Small": 60,
256 "Medium": 120,
257 "Large": 240,
258 "ExtraLarge": 480,
259 "A5": 270,
260 "A6": 540,
261 "A7": 1080,
262 "A8": 1970,
263 "A9": 4470,
264 },
265 "Southeast Asia": {
266 "Basic_A0": 18,
267 "Basic_A1": 58,
268 "Basic_A2": 116,
269 "Basic_A3": 232,
270 "Basic_A4": 464,
271 "ExtraSmall": 20,
272 "Small": 60,
273 "Medium": 120,
274 "Large": 240,
275 "ExtraLarge": 480,
276 "A5": 270,
277 "A6": 540,
278 "A7": 1080,
279 "A8": 1970,
280 "A9": 4470,
281 },
282 "East Asia": {
283 "Basic_A0": 18,
284 "Basic_A1": 58,
285 "Basic_A2": 116,
286 "Basic_A3": 232,
287 "Basic_A4": 464,
288 "ExtraSmall": 20,
289 "Small": 60,
290 "Medium": 120,
291 "Large": 240,
292 "ExtraLarge": 480,
293 "A5": 294,
294 "A6": 588,
295 "A7": 1176,
296 "A8": 1970,
297 "A9": 4470,
298 },
299 "Japan East": {
300 "Basic_A0": 18,
301 "Basic_A1": 69,
302 "Basic_A2": 138,
303 "Basic_A3": 276,
304 "Basic_A4": 552,
305 "ExtraSmall": 27,
306 "Small": 81,
307 "Medium": 162,
308 "Large": 324,
309 "ExtraLarge": 648,
310 "A5": 281,
311 "A6": 562,
312 "A7": 1124,
313 "A8": 1970,
314 "A9": 4470,
315 },
316 "Japan West": {
317 "Basic_A0": 18,
318 "Basic_A1": 61,
319 "Basic_A2": 122,
320 "Basic_A3": 244,
321 "Basic_A4": 488,
322 "ExtraSmall": 25,
323 "Small": 73,
324 "Medium": 146,
325 "Large": 292,
326 "ExtraLarge": 584,
327 "A5": 258,
328 "A6": 516,
329 "A7": 1032,
330 "A8": 1970,
331 "A9": 4470,
332 },
333 "Brazil South": {
334 "Basic_A0": 22,
335 "Basic_A1": 58,
336 "Basic_A2": 116,
337 "Basic_A3": 232,
338 "Basic_A4": 464,
339 "ExtraSmall": 27,
340 "Small": 80,
341 "Medium": 160,
342 "Large": 320,
343 "ExtraLarge": 640,
344 "A5": 291,
345 "A6": 582,
346 "A7": 1164,
347 "A8": 1970,
348 "A9": 4470,
123 },349 },
124}350}
125351
126var RoleNameMap map[string]RoleSize = make(map[string]RoleSize)352// RoleSizeCost returns the cost associated with the given role size and region.
127353func RoleSizeCost(region string, roleSize string) (decicentsPerHour uint64, err error) {
128func init() {354 costs, ok := allRegionRoleCosts[region]
129 for _, rolesize := range RoleSizes {355 if !ok {
130 RoleNameMap[rolesize.Name] = rolesize356 return 0, fmt.Errorf("no cost data for region %q", region)
131 }357 }
358 cost, ok := costs[roleSize]
359 if ok {
360 return uint64(cost), nil
361 }
362 return 0, fmt.Errorf(
363 "no cost data for role size %q in region %q",
364 roleSize, region,
365 )
132}366}
133367
=== modified file 'rolesizes_test.go'
--- rolesizes_test.go 2013-07-22 03:46:15 +0000
+++ rolesizes_test.go 2014-06-24 03:26:22 +0000
@@ -11,6 +11,42 @@
1111
12var _ = Suite(&rolesizeSuite{})12var _ = Suite(&rolesizeSuite{})
1313
14func (suite *rolesizeSuite) TestMapIsCreated(c *C) {14var knownRegions = []string{
15 c.Check(RoleNameMap, HasLen, len(RoleSizes))15 "East US",
16 "West US",
17 "North Central US",
18 "South Central US",
19 "North Europe",
20 "West Europe",
21 "Southeast Asia",
22 "East Asia",
23 "Japan East",
24 "Japan West",
25 "Brazil South",
26}
27
28var knownSizes = []string{
29 "Basic_A0", "Basic_A1", "Basic_A2", "Basic_A3", "Basic_A4",
30 "ExtraSmall", "Small", "Medium", "Large", "ExtraLarge",
31 "A5", "A6", "A7", "A8", "A9",
32}
33
34func (suite *rolesizeSuite) TestRoleCostKnownRegions(c *C) {
35 for _, region := range knownRegions {
36 for _, roleSize := range knownSizes {
37 cost, err := RoleSizeCost(region, roleSize)
38 c.Check(err, IsNil)
39 c.Check(cost, Not(Equals), uint64(0))
40 }
41 }
42}
43
44func (suite *rolesizeSuite) TestRoleCostUnknownRegion(c *C) {
45 _, err := RoleSizeCost("Eastasia", "A0")
46 c.Assert(err, ErrorMatches, `no cost data for region "Eastasia"`)
47}
48
49func (suite *rolesizeSuite) TestRoleCostUnknownRoleSize(c *C) {
50 _, err := RoleSizeCost("East US", "A10")
51 c.Assert(err, ErrorMatches, `no cost data for role size "A10" in region "East US"`)
16}52}

Subscribers

People subscribed via source and target branches

to all changes: