Revision 96f9b0a6

b/src/Ganeti/HTools/Backend/IAlloc.hs
134 134
  let vm_capable' = fromMaybe True vm_capable
135 135
  gidx <- lookupGroup ktg n guuid
136 136
  ndparams <- extract "ndparams" >>= asJSObject
137
  spindles <- tryFromObj desc (fromJSObject ndparams) "spindle_count"
138 137
  excl_stor <- tryFromObj desc (fromJSObject ndparams) "exclusive_storage"
139 138
  let live = not offline && not drained && vm_capable'
140 139
      lvextract def = eitherLive live def . extract
140
  sptotal <- if excl_stor
141
             then lvextract 0 "total_spindles"
142
             else tryFromObj desc (fromJSObject ndparams) "spindle_count"
143
  spfree <- lvextract 0 "free_spindles"
141 144
  mtotal <- lvextract 0.0 "total_memory"
142 145
  mnode  <- lvextract 0 "reserved_memory"
143 146
  mfree  <- lvextract 0 "free_memory"
......
145 148
  dfree  <- lvextract 0 "free_disk"
146 149
  ctotal <- lvextract 0.0 "total_cpus"
147 150
  let node = Node.create n mtotal mnode mfree dtotal dfree ctotal (not live)
148
             spindles gidx excl_stor
151
             sptotal spfree gidx excl_stor
149 152
  return (n, node)
150 153

  
151 154
-- | Parses a group as found in the cluster group list.
b/src/Ganeti/HTools/Backend/Luxi.hs
105 105
     ["name", "mtotal", "mnode", "mfree", "dtotal", "dfree",
106 106
      "ctotal", "offline", "drained", "vm_capable",
107 107
      "ndp/spindle_count", "group.uuid", "tags",
108
      "ndp/exclusive_storage"] Qlang.EmptyFilter
108
      "ndp/exclusive_storage", "sptotal", "spfree"] Qlang.EmptyFilter
109 109

  
110 110
-- | The input data for instance query.
111 111
queryInstancesMsg :: L.LuxiOp
......
187 187
parseNode :: NameAssoc -> [(JSValue, JSValue)] -> Result (String, Node.Node)
188 188
parseNode ktg [ name, mtotal, mnode, mfree, dtotal, dfree
189 189
              , ctotal, offline, drained, vm_capable, spindles, g_uuid
190
              , tags, excl_stor ]
190
              , tags, excl_stor, sptotal, spfree ]
191 191
    = do
192 192
  xname <- annotateResult "Parsing new node" (fromJValWithStatus name)
193 193
  let convert a = genericConvert "Node" xname a
194 194
  xoffline <- convert "offline" offline
195 195
  xdrained <- convert "drained" drained
196 196
  xvm_capable <- convert "vm_capable" vm_capable
197
  xspindles <- convert "spindles" spindles
198 197
  xgdx   <- convert "group.uuid" g_uuid >>= lookupGroup ktg xname
199 198
  xtags <- convert "tags" tags
200 199
  xexcl_stor <- convert "exclusive_storage" excl_stor
201 200
  let live = not xoffline && not xdrained && xvm_capable
202 201
      lvconvert def n d = eitherLive live def $ convert n d
202
  xsptotal <- if xexcl_stor
203
              then lvconvert 0 "sptotal" sptotal
204
              else convert "spindles" spindles
205
  xspfree <- lvconvert 0 "spfree" spfree
203 206
  xmtotal <- lvconvert 0.0 "mtotal" mtotal
204 207
  xmnode <- lvconvert 0 "mnode" mnode
205 208
  xmfree <- lvconvert 0 "mfree" mfree
......
208 211
  xctotal <- lvconvert 0.0 "ctotal" ctotal
209 212
  let node = flip Node.setNodeTags xtags $
210 213
             Node.create xname xmtotal xmnode xmfree xdtotal xdfree
211
             xctotal (not live) xspindles xgdx xexcl_stor
214
             xctotal (not live) xsptotal xspfree xgdx xexcl_stor
212 215
  return (xname, node)
213 216

  
214 217
parseNode _ v = fail ("Invalid node query result: " ++ show v)
b/src/Ganeti/HTools/Backend/Rapi.hs
156 156
  vm_cap  <- annotateResult desc $ maybeFromObj a "vm_capable"
157 157
  let vm_cap' = fromMaybe True vm_cap
158 158
  ndparams <- extract "ndparams" >>= asJSObject
159
  spindles <- tryFromObj desc (fromJSObject ndparams) "spindle_count"
160 159
  excl_stor <- tryFromObj desc (fromJSObject ndparams) "exclusive_storage"
161 160
  guuid   <- annotateResult desc $ maybeFromObj a "group.uuid"
162 161
  guuid' <-  lookupGroup ktg name (fromMaybe defaultGroupID guuid)
163 162
  let live = not offline && not drained && vm_cap'
164 163
      lvextract def = eitherLive live def . extract
164
  sptotal <- if excl_stor
165
             then lvextract 0 "sptotal"
166
             else tryFromObj desc (fromJSObject ndparams) "spindle_count"
167
  spfree <- lvextract 0 "spfree"
165 168
  mtotal <- lvextract 0.0 "mtotal"
166 169
  mnode <- lvextract 0 "mnode"
167 170
  mfree <- lvextract 0 "mfree"
......
171 174
  tags <- extract "tags"
172 175
  let node = flip Node.setNodeTags tags $
173 176
             Node.create name mtotal mnode mfree dtotal dfree ctotal (not live)
174
             spindles guuid' excl_stor
177
             sptotal spfree guuid' excl_stor
175 178
  return (name, node)
176 179

  
177 180
-- | Construct a group from a JSON object.
b/src/Ganeti/HTools/Backend/Simu.hs
85 85
                    Node.create (printf "node-%02d-%03d" grpIndex idx)
86 86
                      (fromIntegral mem) 0 mem
87 87
                      (fromIntegral disk) disk
88
                      (fromIntegral cpu) False spindles grpIndex excl_stor
88
                      (fromIntegral cpu) False spindles 0 grpIndex excl_stor
89 89
                  ) [1..ncount]
90 90
      -- TODO: parse networks to which this group is connected
91 91
      grp = Group.create (printf "group-%02d" grpIndex)
b/src/Ganeti/HTools/Backend/Text.hs
84 84
              -> Node.Node  -- ^ The node to be serialised
85 85
              -> String
86 86
serializeNode gl node =
87
  printf "%s|%.0f|%d|%d|%.0f|%d|%.0f|%c|%s|%d|%s|%s" (Node.name node)
87
  printf "%s|%.0f|%d|%d|%.0f|%d|%.0f|%c|%s|%d|%s|%s|%d" (Node.name node)
88 88
           (Node.tMem node) (Node.nMem node) (Node.fMem node)
89 89
           (Node.tDsk node) (Node.fDsk node) (Node.tCpu node)
90 90
           (if Node.offline node then 'Y' else
91 91
              if Node.isMaster node then 'M' else 'N')
92 92
           (Group.uuid grp)
93
           (Node.spindleCount node)
93
           (Node.tSpindles node)
94 94
           (intercalate "," (Node.nTags node))
95 95
           (if Node.exclStorage node then "Y" else "N")
96
           (Node.fSpindles node)
96 97
    where grp = Container.find (Node.group node) gl
97 98

  
98 99
-- | Generate node file data from node objects.
......
205 206
         -> m (String, Node.Node) -- ^ The result, a tuple o node name
206 207
                                  -- and node object
207 208
loadNode ktg [name, tm, nm, fm, td, fd, tc, fo, gu, spindles, tags,
208
              excl_stor] = do
209
              excl_stor, free_spindles] = do
209 210
  gdx <- lookupGroup ktg name gu
210 211
  new_node <-
211 212
      if "?" `elem` [tm,nm,fm,td,fd,tc] || fo == "Y" then
212
          return $ Node.create name 0 0 0 0 0 0 True 0 gdx False
213
          return $ Node.create name 0 0 0 0 0 0 True 0 0 gdx False
213 214
      else do
214 215
        let vtags = commaSplit tags
215 216
        vtm <- tryRead name tm
......
219 220
        vfd <- tryRead name fd
220 221
        vtc <- tryRead name tc
221 222
        vspindles <- tryRead name spindles
223
        vfree_spindles <- tryRead name free_spindles
222 224
        vexcl_stor <- case excl_stor of
223 225
                        "Y" -> return True
224 226
                        "N" -> return False
......
226 228
                             "Invalid exclusive_storage value for node '" ++
227 229
                             name ++ "': " ++ excl_stor
228 230
        return . flip Node.setMaster (fo == "M") . flip Node.setNodeTags vtags $
229
          Node.create name vtm vnm vfm vtd vfd vtc False vspindles gdx
230
          vexcl_stor
231
          Node.create name vtm vnm vfm vtd vfd vtc False vspindles
232
          vfree_spindles gdx vexcl_stor
231 233
  return (name, new_node)
232 234

  
233 235
loadNode ktg [name, tm, nm, fm, td, fd, tc, fo, gu] =
......
239 241
loadNode ktg [name, tm, nm, fm, td, fd, tc, fo, gu, spindles, tags] =
240 242
  loadNode ktg [name, tm, nm, fm, td, fd, tc, fo, gu, spindles, tags, "N"]
241 243

  
244
loadNode ktg [name, tm, nm, fm, td, fd, tc, fo, gu, spindles, tags,
245
              excl_stor] =
246
  loadNode ktg [name, tm, nm, fm, td, fd, tc, fo, gu, spindles, tags,
247
                excl_stor, "0"]
248

  
242 249
loadNode _ s = fail $ "Invalid/incomplete node data: '" ++ show s ++ "'"
243 250

  
244 251
-- | Load an instance from a field list.
b/src/Ganeti/HTools/Node.hs
111 111
  , fDsk     :: Int       -- ^ Free disk space (MiB)
112 112
  , tCpu     :: Double    -- ^ Total CPU count
113 113
  , uCpu     :: Int       -- ^ Used VCPU count
114
  , spindleCount :: Int   -- ^ Node spindles (spindle_count node parameter)
114
  , tSpindles :: Int      -- ^ Node spindles (spindle_count node parameter,
115
                          -- or actual spindles, see note below)
116
  , fSpindles :: Int      -- ^ Free spindles (see note below)
115 117
  , pList    :: [T.Idx]   -- ^ List of primary instance indices
116 118
  , sList    :: [T.Idx]   -- ^ List of secondary instance indices
117 119
  , idx      :: T.Ndx     -- ^ Internal index for book-keeping
......
128 130
                          -- threshold
129 131
  , hiCpu    :: Int       -- ^ Autocomputed from mCpu high cpu
130 132
                          -- threshold
131
  , hiSpindles :: Double  -- ^ Auto-computed from policy spindle_ratio
132
                          -- and the node spindle count
133
  , instSpindles :: Double -- ^ Spindles used by instances
133
  , hiSpindles :: Double  -- ^ Limit auto-computed from policy spindle_ratio
134
                          -- and the node spindle count (see note below)
135
  , instSpindles :: Double -- ^ Spindles used by instances (see note below)
134 136
  , offline  :: Bool      -- ^ Whether the node should not be used for
135 137
                          -- allocations and skipped from score
136 138
                          -- computations
......
143 145
  , iPolicy  :: T.IPolicy -- ^ The instance policy (of the node's group)
144 146
  , exclStorage :: Bool   -- ^ Effective value of exclusive_storage
145 147
  } deriving (Show, Eq)
148
{- A note on how we handle spindles
149

  
150
With exclusive storage spindles is a resource, so we track the number of
151
spindles still available (fSpindles). This is the only reliable way, as some
152
spindles could be used outside of Ganeti. When exclusive storage is off,
153
spindles are a way to represent disk I/O pressure, and hence we track the amount
154
used by the instances. We compare it against 'hiSpindles', computed from the
155
instance policy, to avoid policy violations. In both cases we store the total
156
spindles in 'tSpindles'.
157
-}
146 158

  
147 159
instance T.Element Node where
148 160
  nameOf = name
......
217 229
-- The index and the peers maps are empty, and will be need to be
218 230
-- update later via the 'setIdx' and 'buildPeers' functions.
219 231
create :: String -> Double -> Int -> Int -> Double
220
       -> Int -> Double -> Bool -> Int -> T.Gdx -> Bool -> Node
232
       -> Int -> Double -> Bool -> Int -> Int -> T.Gdx -> Bool -> Node
221 233
create name_init mem_t_init mem_n_init mem_f_init
222
       dsk_t_init dsk_f_init cpu_t_init offline_init spindles_init
223
       group_init excl_stor =
234
       dsk_t_init dsk_f_init cpu_t_init offline_init spindles_t_init
235
       spindles_f_init group_init excl_stor =
224 236
  Node { name = name_init
225 237
       , alias = name_init
226 238
       , tMem = mem_t_init
......
229 241
       , tDsk = dsk_t_init
230 242
       , fDsk = dsk_f_init
231 243
       , tCpu = cpu_t_init
232
       , spindleCount = spindles_init
244
       , tSpindles = spindles_t_init
245
       , fSpindles = spindles_f_init
233 246
       , uCpu = 0
234 247
       , pList = []
235 248
       , sList = []
......
249 262
       , loDsk = mDskToloDsk T.defReservedDiskRatio dsk_t_init
250 263
       , hiCpu = mCpuTohiCpu (T.iPolicyVcpuRatio T.defIPolicy) cpu_t_init
251 264
       , hiSpindles = computeHiSpindles (T.iPolicySpindleRatio T.defIPolicy)
252
                      spindles_init
265
                      spindles_t_init
253 266
       , instSpindles = 0
254 267
       , utilPool = T.baseUtil
255 268
       , utilLoad = T.zeroUtil
......
316 329
  node { iPolicy = pol
317 330
       , hiCpu = mCpuTohiCpu (T.iPolicyVcpuRatio pol) (tCpu node)
318 331
       , hiSpindles = computeHiSpindles (T.iPolicySpindleRatio pol)
319
                      (spindleCount node)
332
                      (tSpindles node)
320 333
       }
321 334

  
322 335
-- | Computes the maximum reserved memory for peers from a peer map.
......
665 678
    "ptags" -> intercalate "," . map (uncurry (printf "%s=%d")) .
666 679
               Map.toList $ pTags t
667 680
    "peermap" -> show $ peers t
668
    "spindle_count" -> show $ spindleCount t
681
    "spindle_count" -> show $ tSpindles t
669 682
    "hi_spindles" -> show $ hiSpindles t
670 683
    "inst_spindles" -> show $ instSpindles t
671 684
    _ -> T.unknownField
b/test/data/htools/hail-alloc-drbd.json
435 435
      "total_memory": 32763,
436 436
      "primary_ip": "192.168.1.1",
437 437
      "i_pri_memory": 0,
438
      "free_spindles": 12,
439
      "total_spindles": 12,
438 440
      "vm_capable": true,
439 441
      "offline": false
440 442
    },
......
459 461
      "total_memory": 32763,
460 462
      "primary_ip": "192.168.1.2",
461 463
      "i_pri_memory": 0,
464
      "free_spindles": 12,
465
      "total_spindles": 12,
462 466
      "vm_capable": true,
463 467
      "offline": false
464 468
    },
......
483 487
      "total_memory": 32763,
484 488
      "primary_ip": "192.168.1.3",
485 489
      "i_pri_memory": 2432,
490
      "free_spindles": 6,
491
      "total_spindles": 12,
486 492
      "vm_capable": true,
487 493
      "offline": false
488 494
    },
......
507 513
      "total_memory": 32763,
508 514
      "primary_ip": "192.168.1.4",
509 515
      "i_pri_memory": 23552,
516
      "free_spindles": 0,
517
      "total_spindles": 12,
510 518
      "vm_capable": true,
511 519
      "offline": false
512 520
    }
b/test/data/htools/hail-alloc-invalid-network.json
98 98
      "drained": false,
99 99
      "free_disk": 7168,
100 100
      "free_memory": 4096,
101
      "free_spindles": 0,
101 102
      "group": "uuid-group-1",
102 103
      "ndparams": {
103 104
        "spindle_count": 1,
......
107 108
      "reserved_memory": 1017,
108 109
      "total_cpus": 4,
109 110
      "total_disk": 7168,
110
      "total_memory": 4096
111
      "total_memory": 4096,
112
      "total_spindles": 0
111 113
    },
112 114
    "node2_1": {
113 115
      "drained": false,
114 116
      "free_disk": 7168,
115 117
      "free_memory": 4096,
118
      "free_spindles": 0,
116 119
      "group": "uuid-group-2",
117 120
      "ndparams": {
118 121
        "spindle_count": 1,
......
122 125
      "reserved_memory": 1017,
123 126
      "total_cpus": 4,
124 127
      "total_disk": 7168,
125
      "total_memory": 4096
128
      "total_memory": 4096,
129
      "total_spindles": 0
126 130
    }
127 131
  },
128 132
  "request": {
b/test/data/htools/hail-alloc-invalid-twodisks.json
57 57
      "drained": false,
58 58
      "free_disk": 1377280,
59 59
      "free_memory": 31389,
60
      "free_spindles": 12,
60 61
      "group": "uuid-group-1",
61 62
      "ndparams": {
62 63
        "spindle_count": 1,
......
66 67
      "reserved_memory": 1017,
67 68
      "total_cpus": 4,
68 69
      "total_disk": 1377280,
69
      "total_memory": 32763
70
      "total_memory": 32763,
71
      "total_spindles": 12
70 72
    }
71 73
  },
72 74
  "request": {
b/test/data/htools/hail-alloc-restricted-network.json
189 189
      "drained": false,
190 190
      "free_disk": 4096,
191 191
      "free_memory": 3840,
192
      "free_spindles": 0,
192 193
      "group": "uuid-group-1",
193 194
      "ndparams": {
194 195
        "spindle_count": 1,
......
198 199
      "reserved_memory": 1017,
199 200
      "total_cpus": 4,
200 201
      "total_disk": 7168,
201
      "total_memory": 4096
202
      "total_memory": 4096,
203
      "total_spindles": 0
202 204
    },
203 205
    "node1_2": {
204 206
      "drained": false,
205 207
      "free_disk": 4096,
206 208
      "free_memory": 3968,
209
      "free_spindles": 0,
207 210
      "group": "uuid-group-1",
208 211
      "ndparams": {
209 212
        "spindle_count": 1,
......
213 216
      "reserved_memory": 1017,
214 217
      "total_cpus": 4,
215 218
      "total_disk": 7168,
216
      "total_memory": 32763
219
      "total_memory": 32763,
220
      "total_spindles": 0
217 221
    },
218 222
    "node2_1": {
219 223
      "drained": false,
220 224
      "free_disk": 7168,
221 225
      "free_memory": 4096,
226
      "free_spindles": 0,
222 227
      "group": "uuid-group-2",
223 228
      "ndparams": {
224 229
        "spindle_count": 1,
......
228 233
      "reserved_memory": 1017,
229 234
      "total_cpus": 4,
230 235
      "total_disk": 7168,
231
      "total_memory": 4096
236
      "total_memory": 4096,
237
      "total_spindles": 0
232 238
    },
233 239
    "node2_2": {
234 240
      "drained": false,
235 241
      "free_disk": 7168,
236 242
      "free_memory": 4096,
243
      "free_spindles": 0,
237 244
      "group": "uuid-group-2",
238 245
      "ndparams": {
239 246
        "spindle_count": 1,
......
243 250
      "reserved_memory": 1017,
244 251
      "total_cpus": 4,
245 252
      "total_disk": 7168,
246
      "total_memory": 4096
253
      "total_memory": 4096,
254
      "total_spindles": 0
247 255
    }
248 256
  },
249 257
  "request": {
b/test/data/htools/hail-alloc-spindles.json
290 290
      "total_memory": 32763,
291 291
      "primary_ip": "192.168.1.1",
292 292
      "i_pri_memory": 1024,
293
      "free_spindles": 1,
294
      "total_spindles": 2,
293 295
      "vm_capable": true,
294 296
      "offline": false
295 297
    },
......
314 316
      "total_memory": 32763,
315 317
      "primary_ip": "192.168.1.2",
316 318
      "i_pri_memory": 1024,
319
      "free_spindles": 0,
320
      "total_spindles": 2,
317 321
      "vm_capable": true,
318 322
      "offline": false
319 323
    },
......
338 342
      "total_memory": 32763,
339 343
      "primary_ip": "192.168.1.3",
340 344
      "i_pri_memory": 1204,
345
      "free_spindles": 1,
346
      "total_spindles": 2,
341 347
      "vm_capable": true,
342 348
      "offline": false
343 349
    },
......
362 368
      "total_memory": 32763,
363 369
      "primary_ip": "192.168.1.4",
364 370
      "i_pri_memory": 1024,
371
      "free_spindles": 0,
372
      "total_spindles": 2,
365 373
      "vm_capable": true,
366 374
      "offline": false
367 375
    }
b/test/data/htools/hail-alloc-twodisks.json
57 57
      "drained": false,
58 58
      "free_disk": 1377280,
59 59
      "free_memory": 31389,
60
      "free_spindles": 12,
60 61
      "group": "uuid-group-1",
61 62
      "ndparams": {
62 63
        "spindle_count": 1,
......
66 67
      "reserved_memory": 1017,
67 68
      "total_cpus": 4,
68 69
      "total_disk": 1377280,
69
      "total_memory": 32763
70
      "total_memory": 32763,
71
      "total_spindles": 12
70 72
    }
71 73
  },
72 74
  "request": {
b/test/data/htools/hail-change-group.json
180 180
    "instance13": {
181 181
      "disks": [
182 182
        {
183
          "spindles": 2,
183
          "spindles": 1,
184 184
          "mode": "rw",
185 185
          "size": 512
186 186
        }
......
307 307
          "size": 256
308 308
        },
309 309
        {
310
          "spindles": 1,
310 311
          "mode": "rw",
311 312
          "size": 128
312 313
        }
......
481 482
      "total_memory": 32763,
482 483
      "primary_ip": "192.168.1.1",
483 484
      "i_pri_memory": 0,
485
      "free_spindles": 12,
486
      "total_spindles": 12,
484 487
      "vm_capable": true,
485 488
      "offline": false
486 489
    },
......
505 508
      "total_memory": 32763,
506 509
      "primary_ip": "192.168.1.3",
507 510
      "i_pri_memory": 2432,
511
      "free_spindles": 6,
512
      "total_spindles": 12,
508 513
      "vm_capable": true,
509 514
      "offline": false
510 515
    },
......
529 534
      "total_memory": 32763,
530 535
      "primary_ip": "192.168.1.4",
531 536
      "i_pri_memory": 23552,
537
      "free_spindles": 0,
538
      "total_spindles": 12,
532 539
      "vm_capable": true,
533 540
      "offline": false
534 541
    },
......
553 560
      "total_memory": 32763,
554 561
      "primary_ip": "192.168.1.10",
555 562
      "i_pri_memory": 23552,
563
      "free_spindles": 12,
564
      "total_spindles": 12,
556 565
      "vm_capable": true,
557 566
      "offline": false
558 567
    },
......
577 586
      "total_memory": 32763,
578 587
      "primary_ip": "192.168.1.11",
579 588
      "i_pri_memory": 23552,
589
      "free_spindles": 12,
590
      "total_spindles": 12,
580 591
      "vm_capable": true,
581 592
      "offline": false
582 593
    }
b/test/data/htools/hail-node-evac.json
431 431
      "total_memory": 32763,
432 432
      "primary_ip": "192.168.1.1",
433 433
      "i_pri_memory": 0,
434
      "free_spindles": 12,
435
      "total_spindles": 12,
434 436
      "vm_capable": true,
435 437
      "offline": false
436 438
    },
......
455 457
      "total_memory": 32763,
456 458
      "primary_ip": "192.168.1.2",
457 459
      "i_pri_memory": 0,
460
      "free_spindles": 12,
461
      "total_spindles": 12,
458 462
      "vm_capable": true,
459 463
      "offline": false
460 464
    },
......
479 483
      "total_memory": 32763,
480 484
      "primary_ip": "192.168.1.3",
481 485
      "i_pri_memory": 2432,
486
      "free_spindles": 6,
487
      "total_spindles": 12,
482 488
      "vm_capable": true,
483 489
      "offline": false
484 490
    },
......
503 509
      "total_memory": 32763,
504 510
      "primary_ip": "192.168.1.4",
505 511
      "i_pri_memory": 23552,
512
      "free_spindles": 0,
513
      "total_spindles": 12,
506 514
      "vm_capable": true,
507 515
      "offline": false
508 516
    }
b/test/data/htools/hail-reloc-drbd.json
435 435
      "total_memory": 32763,
436 436
      "primary_ip": "192.168.1.1",
437 437
      "i_pri_memory": 0,
438
      "free_spindles": 12,
439
      "total_spindles": 12,
438 440
      "vm_capable": true,
439 441
      "offline": false
440 442
    },
......
459 461
      "total_memory": 32763,
460 462
      "primary_ip": "192.168.1.2",
461 463
      "i_pri_memory": 0,
464
      "free_spindles": 12,
465
      "total_spindles": 12,
462 466
      "vm_capable": true,
463 467
      "offline": false
464 468
    },
......
483 487
      "total_memory": 32763,
484 488
      "primary_ip": "192.168.1.3",
485 489
      "i_pri_memory": 2432,
490
      "free_spindles": 6,
491
      "total_spindles": 12,
486 492
      "vm_capable": true,
487 493
      "offline": false
488 494
    },
......
507 513
      "total_memory": 32763,
508 514
      "primary_ip": "192.168.1.4",
509 515
      "i_pri_memory": 23552,
516
      "free_spindles": 0,
517
      "total_spindles": 12,
510 518
      "vm_capable": true,
511 519
      "offline": false
512 520
    }
b/test/data/htools/rapi/nodes.json
24 24
    "sinst_cnt": 0,
25 25
    "sinst_list": [],
26 26
    "sip": "192.168.1.2",
27
    "spfree": 0,
28
    "sptotal": 0,
27 29
    "tags": [],
28 30
    "uuid": "7750ef3d-450f-4724-9d3d-8726d6335417",
29 31
    "vm_capable": true,
......
58 60
    "sinst_cnt": 0,
59 61
    "sinst_list": [],
60 62
    "sip": "192.168.2.2",
63
    "spfree": 0,
64
    "sptotal": 0,
61 65
    "tags": [],
62 66
    "uuid": "7750ef3d-450f-4724-9d3d-8726d6335417",
63 67
    "vm_capable": true,
......
96 100
    "master_candidate": true,
97 101
    "ctime": 1271425438.5,
98 102
    "mnode": 1017,
103
    "spfree": 0,
104
    "sptotal": 0,
99 105
    "pinst_list": [
100 106
      "instance14",
101 107
      "instance19",
......
142 148
    "master_candidate": true,
143 149
    "ctime": 1309185898.51,
144 150
    "mnode": 1017,
151
    "spfree": 0,
152
    "sptotal": 0,
145 153
    "pinst_list": [
146 154
      "instance20",
147 155
      "instance3",
b/test/hs/Test/Ganeti/HTools/Node.hs
90 90
  cpu_t <- choose (base_cpu, top_cpu)
91 91
  offl  <- arbitrary
92 92
  let n = Node.create name (fromIntegral mem_t) mem_n mem_f
93
          (fromIntegral dsk_t) dsk_f (fromIntegral cpu_t) offl 1 0 False
93
          (fromIntegral dsk_t) dsk_f (fromIntegral cpu_t) offl 1 0 0 False
94 94
      n' = Node.setPolicy nullIPolicy n
95 95
  return $ Node.buildPeers n' Container.empty
96 96

  

Also available in: Unified diff