Revision 6e94b75c

b/src/Ganeti/HTools/Program/Harep.hs
268 268
  when (isJust arData) $ do
269 269
    let tag = arTag $ fromJust arData
270 270
    putStrLn (">>> Adding the following tag to " ++ iname ++ ":\n" ++ show tag)
271
    execJobsWaitOk' [OpTagsSet (TagInstance iname) [tag]]
271
    tagName <- mkNonEmpty iname
272
    execJobsWaitOk' [OpTagsSet TagKindInstance [tag] (Just tagName)]
272 273

  
273 274
  unless (null rmTags) $ do
274 275
    putStr (">>> Removing the following tags from " ++ iname ++ ":\n" ++
275 276
            unlines (map show rmTags))
276
    execJobsWaitOk' [OpTagsDel (TagInstance iname) rmTags]
277
    tagName <- mkNonEmpty iname
278
    execJobsWaitOk' [OpTagsDel TagKindInstance rmTags (Just tagName)]
277 279

  
278 280
  return instData { tagsToRemove = [] }
279 281

  
b/src/Ganeti/Query/Server.hs
52 52
import Ganeti.BasicTypes
53 53
import Ganeti.Logging
54 54
import Ganeti.Luxi
55
import Ganeti.OpCodes (TagObject(..))
56 55
import qualified Ganeti.Query.Language as Qlang
57 56
import qualified Ganeti.Query.Cluster as QCluster
58 57
import Ganeti.Query.Query
59 58
import Ganeti.Query.Filter (makeSimpleFilter)
59
import Ganeti.Types
60 60

  
61 61
-- | Helper for classic queries.
62 62
handleClassicQuery :: ConfigData      -- ^ Cluster config
......
149 149
    Ok _ -> return . Ok . J.makeObj $ obj
150 150
    Bad ex -> return $ Bad ex
151 151

  
152
handleCall cfg (QueryTags kind) =
152
handleCall cfg (QueryTags kind name) = do
153 153
  let tags = case kind of
154
               TagCluster       -> Ok . clusterTags $ configCluster cfg
155
               TagGroup    name -> groupTags <$> Config.getGroup    cfg name
156
               TagNode     name -> nodeTags  <$> Config.getNode     cfg name
157
               TagInstance name -> instTags  <$> Config.getInstance cfg name
158
  in return (J.showJSON <$> tags)
154
               TagKindCluster  -> Ok . clusterTags $ configCluster cfg
155
               TagKindGroup    -> groupTags <$> Config.getGroup    cfg name
156
               TagKindNode     -> nodeTags  <$> Config.getNode     cfg name
157
               TagKindInstance -> instTags  <$> Config.getInstance cfg name
158
  return (J.showJSON <$> tags)
159 159

  
160 160
handleCall cfg (Query qkind qfields qfilter) = do
161 161
  result <- query cfg True (Qlang.Query qkind qfields qfilter)
b/test/hs/Test/Ganeti/JQueue.hs
161 161
               Text.JSON.Ok jobs' -> return jobs'
162 162
               Error msg ->
163 163
                 assertFailure ("Unable to decode jobs: " ++ msg)
164
                 -- this already raised an expection, but we need it
164
                 -- this already raised an exception, but we need it
165 165
                 -- for proper types
166 166
                 >> fail "Unable to decode jobs"
167 167
  assertEqual "Mismatch in number of returned jobs"
b/test/hs/Test/Ganeti/Luxi.hs
73 73
                              listOf genFQDN <*> arbitrary
74 74
      Luxi.ReqQueryConfigValues -> Luxi.QueryConfigValues <$> genFields
75 75
      Luxi.ReqQueryClusterInfo -> pure Luxi.QueryClusterInfo
76
      Luxi.ReqQueryTags -> Luxi.QueryTags <$> arbitrary
76
      Luxi.ReqQueryTags -> do
77
        kind <- arbitrary
78
        Luxi.QueryTags kind <$> genLuxiTagName kind
77 79
      Luxi.ReqSubmitJob -> Luxi.SubmitJob <$> resize maxOpCodes arbitrary
78 80
      Luxi.ReqSubmitManyJobs -> Luxi.SubmitManyJobs <$>
79 81
                                resize maxOpCodes arbitrary
b/test/hs/Test/Ganeti/OpCodes.hs
45 45
import Test.Ganeti.TestHelper
46 46
import Test.Ganeti.TestCommon
47 47
import Test.Ganeti.Types ()
48
import Test.Ganeti.Query.Language
48
import Test.Ganeti.Query.Language ()
49 49

  
50 50
import Ganeti.BasicTypes
51 51
import qualified Ganeti.Constants as C
......
65 65
                    , pure OpCodes.TagCluster
66 66
                    ]
67 67

  
68
arbitraryOpTagsGet :: Gen OpCodes.OpCode
69
arbitraryOpTagsGet = do
70
  kind <- arbitrary
71
  OpCodes.OpTagsSet kind <$> arbitrary <*> genOpCodesTagName kind
72

  
73
arbitraryOpTagsSet :: Gen OpCodes.OpCode
74
arbitraryOpTagsSet = do
75
  kind <- arbitrary
76
  OpCodes.OpTagsSet kind <$> genTags <*> genOpCodesTagName kind
77

  
78
arbitraryOpTagsDel :: Gen OpCodes.OpCode
79
arbitraryOpTagsDel = do
80
  kind <- arbitrary
81
  OpCodes.OpTagsDel kind <$> genTags <*> genOpCodesTagName kind
82

  
68 83
$(genArbitrary ''OpCodes.ReplaceDisksMode)
69 84

  
70 85
$(genArbitrary ''DiskAccess)
......
74 89

  
75 90
instance Arbitrary INicParams where
76 91
  arbitrary = INicParams <$> genMaybe genNameNE <*> genMaybe genName <*>
77
              genMaybe genNameNE <*> genMaybe genNameNE <*> genMaybe genNameNE
78
              <*> genMaybe genNameNE
92
              genMaybe genNameNE <*> genMaybe genNameNE <*>
93
              genMaybe genNameNE <*> genMaybe genNameNE <*>
94
              genMaybe genNameNE
79 95

  
80 96
instance Arbitrary IDiskParams where
81 97
  arbitrary = IDiskParams <$> arbitrary <*> arbitrary <*>
......
125 141
          return Nothing <*> arbitrary <*> arbitrary <*> arbitrary <*>
126 142
          genMaybe genNameNE <*> arbitrary
127 143
      "OP_TAGS_GET" ->
128
        OpCodes.OpTagsGet <$> arbitrary <*> arbitrary
144
        arbitraryOpTagsGet
129 145
      "OP_TAGS_SEARCH" ->
130 146
        OpCodes.OpTagsSearch <$> genNameNE
131 147
      "OP_TAGS_SET" ->
132
        OpCodes.OpTagsSet <$> arbitrary <*> genTags
148
        arbitraryOpTagsSet
133 149
      "OP_TAGS_DEL" ->
134
        OpCodes.OpTagsSet <$> arbitrary <*> genTags
150
        arbitraryOpTagsDel
135 151
      "OP_CLUSTER_POST_INIT" -> pure OpCodes.OpClusterPostInit
136 152
      "OP_CLUSTER_DESTROY" -> pure OpCodes.OpClusterDestroy
137 153
      "OP_CLUSTER_QUERY" -> pure OpCodes.OpClusterQuery
......
156 172
        OpCodes.OpClusterRename <$> genNameNE
157 173
      "OP_CLUSTER_SET_PARAMS" ->
158 174
        OpCodes.OpClusterSetParams <$> arbitrary <*> emptyMUD <*> emptyMUD <*>
159
          arbitrary <*> genMaybe (listOf1 arbitrary >>= mkNonEmpty) <*>
175
          arbitrary <*> genMaybe arbitrary <*>
160 176
          genMaybe genEmptyContainer <*> emptyMUD <*>
161 177
          genMaybe genEmptyContainer <*> genMaybe genEmptyContainer <*>
162 178
          genMaybe genEmptyContainer <*> genMaybe arbitrary <*>
......
172 188
      "OP_CLUSTER_DEACTIVATE_MASTER_IP" ->
173 189
        pure OpCodes.OpClusterDeactivateMasterIp
174 190
      "OP_QUERY" ->
175
        OpCodes.OpQuery <$> arbitrary <*> arbitrary <*> arbitrary <*> genFilter
191
        OpCodes.OpQuery <$> arbitrary <*> arbitrary <*> arbitrary <*>
192
        pure Nothing
176 193
      "OP_QUERY_FIELDS" ->
177 194
        OpCodes.OpQueryFields <$> arbitrary <*> arbitrary
178 195
      "OP_OOB_COMMAND" ->
......
183 200
        OpCodes.OpNodeRemove <$> genNodeNameNE <*> return Nothing
184 201
      "OP_NODE_ADD" ->
185 202
        OpCodes.OpNodeAdd <$> genNodeNameNE <*> emptyMUD <*> emptyMUD <*>
186
          genMaybe genName <*> genMaybe genNameNE <*> arbitrary <*>
203
          genNameNE <*> genMaybe genNameNE <*> arbitrary <*>
187 204
          genMaybe genNameNE <*> arbitrary <*> arbitrary <*> emptyMUD
188 205
      "OP_NODE_QUERY" ->
189 206
        OpCodes.OpNodeQuery <$> genFieldsNE <*> genNamesNE <*> arbitrary
......
191 208
        OpCodes.OpNodeQueryvols <$> arbitrary <*> genNodeNamesNE
192 209
      "OP_NODE_QUERY_STORAGE" ->
193 210
        OpCodes.OpNodeQueryStorage <$> arbitrary <*> arbitrary <*>
194
          genNodeNamesNE <*> genNameNE
211
          genNodeNamesNE <*> genMaybe genNameNE
195 212
      "OP_NODE_MODIFY_STORAGE" ->
196 213
        OpCodes.OpNodeModifyStorage <$> genNodeNameNE <*> return Nothing <*>
197
          arbitrary <*> genNameNE <*> pure emptyJSObject
214
          arbitrary <*> genMaybe genNameNE <*> pure emptyJSObject
198 215
      "OP_REPAIR_NODE_STORAGE" ->
199 216
        OpCodes.OpRepairNodeStorage <$> genNodeNameNE <*> return Nothing <*>
200
          arbitrary <*> genNameNE <*> arbitrary
217
          arbitrary <*> genMaybe genNameNE <*> arbitrary
201 218
      "OP_NODE_SET_PARAMS" ->
202 219
        OpCodes.OpNodeSetParams <$> genNodeNameNE <*> return Nothing <*>
203 220
          arbitrary <*> emptyMUD <*> emptyMUD <*> arbitrary <*> arbitrary <*>
......
216 233
          genMaybe genNameNE <*> arbitrary
217 234
      "OP_INSTANCE_CREATE" ->
218 235
        OpCodes.OpInstanceCreate <$> genFQDN <*> arbitrary <*>
219
          arbitrary <*> arbitrary <*> arbitrary <*> pure emptyJSObject <*>
220
          arbitrary <*> arbitrary <*> arbitrary <*> genMaybe genNameNE <*>
221
          pure emptyJSObject <*> arbitrary <*> genMaybe genNameNE <*>
222 236
          arbitrary <*> arbitrary <*> arbitrary <*> arbitrary <*>
223
          arbitrary <*> arbitrary <*> pure emptyJSObject <*>
224
          genMaybe genNameNE <*>
225
          genMaybe genNodeNameNE <*> return Nothing <*>
226
          genMaybe genNodeNameNE <*> return Nothing <*>
227
          genMaybe (pure []) <*> genMaybe genNodeNameNE <*>
228
          arbitrary <*> genMaybe genNodeNameNE <*> return Nothing <*>
229
          genMaybe genNodeNameNE <*> genMaybe genNameNE <*>
230
          arbitrary <*> arbitrary <*> (genTags >>= mapM mkNonEmpty)
237
          pure emptyJSObject <*> arbitrary <*> arbitrary <*> arbitrary <*>
238
          genMaybe genNameNE <*> pure emptyJSObject <*> arbitrary <*>
239
          genMaybe genNameNE <*> arbitrary <*> arbitrary <*> arbitrary <*>
240
          arbitrary <*> arbitrary <*> arbitrary <*> pure emptyJSObject <*>
241
          genMaybe genNameNE <*> genMaybe genNodeNameNE <*> return Nothing <*>
242
          genMaybe genNodeNameNE <*> return Nothing <*> genMaybe (pure []) <*>
243
          genMaybe genNodeNameNE <*> arbitrary <*> genMaybe genNodeNameNE <*>
244
          return Nothing <*> genMaybe genNodeNameNE <*> genMaybe genNameNE <*>
245
          arbitrary <*> (genTags >>= mapM mkNonEmpty)
231 246
      "OP_INSTANCE_MULTI_ALLOC" ->
232
        OpCodes.OpInstanceMultiAlloc <$> genMaybe genNameNE <*> pure [] <*>
233
          arbitrary
247
        OpCodes.OpInstanceMultiAlloc <$> arbitrary <*> genMaybe genNameNE <*>
248
        pure []
234 249
      "OP_INSTANCE_REINSTALL" ->
235 250
        OpCodes.OpInstanceReinstall <$> genFQDN <*> return Nothing <*>
236 251
          arbitrary <*> genMaybe genNameNE <*> genMaybe (pure emptyJSObject)
......
267 282
          arbitrary <*> genNodeNamesNE <*> return Nothing <*>
268 283
          genMaybe genNameNE
269 284
      "OP_INSTANCE_QUERY" ->
270
        OpCodes.OpInstanceQuery <$> genFieldsNE <*> genNamesNE <*> arbitrary
285
        OpCodes.OpInstanceQuery <$> genFieldsNE <*> arbitrary <*> genNamesNE
271 286
      "OP_INSTANCE_QUERY_DATA" ->
272 287
        OpCodes.OpInstanceQueryData <$> arbitrary <*>
273 288
          genNodeNamesNE <*> arbitrary
......
323 338
        OpCodes.OpBackupRemove <$> genFQDN <*> return Nothing
324 339
      "OP_TEST_ALLOCATOR" ->
325 340
        OpCodes.OpTestAllocator <$> arbitrary <*> arbitrary <*>
326
          genNameNE <*> pure [] <*> pure [] <*>
341
          genNameNE <*> genMaybe (pure []) <*> genMaybe (pure []) <*>
327 342
          arbitrary <*> genMaybe genNameNE <*>
328 343
          (genTags >>= mapM mkNonEmpty) <*>
329 344
          arbitrary <*> arbitrary <*> genMaybe genNameNE <*>
......
336 351
        OpCodes.OpTestDummy <$> pure J.JSNull <*> pure J.JSNull <*>
337 352
          pure J.JSNull <*> pure J.JSNull
338 353
      "OP_NETWORK_ADD" ->
339
        OpCodes.OpNetworkAdd <$> genNameNE <*> genIp4Net <*>
340
          genMaybe genIp4Addr <*> pure Nothing <*> pure Nothing <*>
341
          genMaybe genMacPrefix <*> genMaybe (listOf genIp4Addr) <*>
354
        OpCodes.OpNetworkAdd <$> genNameNE <*> genIPv4Network <*>
355
          genMaybe genIPv4Address <*> pure Nothing <*> pure Nothing <*>
356
          genMaybe genMacPrefix <*> genMaybe (listOf genIPv4Address) <*>
342 357
          arbitrary <*> (genTags >>= mapM mkNonEmpty)
343 358
      "OP_NETWORK_REMOVE" ->
344 359
        OpCodes.OpNetworkRemove <$> genNameNE <*> arbitrary
345 360
      "OP_NETWORK_SET_PARAMS" ->
346 361
        OpCodes.OpNetworkSetParams <$> genNameNE <*>
347
          genMaybe genIp4Addr <*> pure Nothing <*> pure Nothing <*>
348
          genMaybe genMacPrefix <*> genMaybe (listOf genIp4Addr) <*>
349
          genMaybe (listOf genIp4Addr)
362
          genMaybe genIPv4Address <*> pure Nothing <*> pure Nothing <*>
363
          genMaybe genMacPrefix <*> genMaybe (listOf genIPv4Address) <*>
364
          genMaybe (listOf genIPv4Address)
350 365
      "OP_NETWORK_CONNECT" ->
351 366
        OpCodes.OpNetworkConnect <$> genNameNE <*> genNameNE <*>
352 367
          arbitrary <*> genNameNE <*> arbitrary
353 368
      "OP_NETWORK_DISCONNECT" ->
354 369
        OpCodes.OpNetworkDisconnect <$> genNameNE <*> genNameNE
355 370
      "OP_NETWORK_QUERY" ->
356
        OpCodes.OpNetworkQuery <$> genFieldsNE <*> genNamesNE <*> arbitrary
371
        OpCodes.OpNetworkQuery <$> genFieldsNE <*> arbitrary <*> genNamesNE
357 372
      "OP_RESTRICTED_COMMAND" ->
358 373
        OpCodes.OpRestrictedCommand <$> arbitrary <*> genNodeNamesNE <*>
359 374
          return Nothing <*> genNameNE
......
445 460
     runPython "from ganeti import opcodes\n\
446 461
               \from ganeti import serializer\n\
447 462
               \import sys\n\
448
               \print serializer.Dump([opid for opid in opcodes.OP_MAPPING])\n" ""
463
               \print serializer.Dump([opid for opid in opcodes.OP_MAPPING])\n"
464
               ""
449 465
     >>= checkPythonResult
450 466
  py_ops <- case J.decode py_stdout::J.Result [String] of
451 467
               J.Ok ops -> return ops
......
493 509
        ) opcodes
494 510
  py_stdout <-
495 511
     runPython "from ganeti import opcodes\n\
496
               \import sys\n\
497 512
               \from ganeti import serializer\n\
513
               \import sys\n\
498 514
               \op_data = serializer.Load(sys.stdin.read())\n\
499 515
               \decoded = [opcodes.OpCode.LoadOpCode(o) for o in op_data]\n\
500 516
               \for op in decoded:\n\
b/test/hs/Test/Ganeti/TestCommon.hs
50 50
  , SmallRatio(..)
51 51
  , genSetHelper
52 52
  , genSet
53
  , genIp4AddrStr
54
  , genIp4Addr
55
  , genIp4NetWithNetmask
56
  , genIp4Net
53
  , genIPv4Address
54
  , genIPv4Network
57 55
  , genIp6Addr
58 56
  , genIp6Net
57
  , genOpCodesTagName
58
  , genLuxiTagName
59 59
  , netmask2NumHosts
60 60
  , testSerialisation
61 61
  , resultProp
......
283 283
genSet :: (Ord a, Bounded a, Enum a) => Maybe Int -> Gen (Set.Set a)
284 284
genSet = genSetHelper [minBound..maxBound]
285 285

  
286
-- | Generate an arbitrary IPv4 address in textual form (non empty).
287
genIp4Addr :: Gen NonEmptyString
288
genIp4Addr = genIp4AddrStr >>= mkNonEmpty
289

  
290 286
-- | Generate an arbitrary IPv4 address in textual form.
291
genIp4AddrStr :: Gen String
292
genIp4AddrStr = do
287
genIPv4 :: Gen String
288
genIPv4 = do
293 289
  a <- choose (1::Int, 255)
294 290
  b <- choose (0::Int, 255)
295 291
  c <- choose (0::Int, 255)
296 292
  d <- choose (0::Int, 255)
297
  return $ intercalate "." (map show [a, b, c, d])
293
  return . intercalate "." $ map show [a, b, c, d]
298 294

  
299
-- | Generates an arbitrary IPv4 address with a given netmask in textual form.
300
genIp4NetWithNetmask :: Int -> Gen NonEmptyString
301
genIp4NetWithNetmask netmask = do
302
  ip <- genIp4AddrStr
303
  mkNonEmpty $ ip ++ "/" ++ show netmask
295
genIPv4Address :: Gen IPv4Address
296
genIPv4Address = mkIPv4Address =<< genIPv4
304 297

  
305 298
-- | Generate an arbitrary IPv4 network in textual form.
306
genIp4Net :: Gen NonEmptyString
307
genIp4Net = do
299
genIPv4AddrRange :: Gen String
300
genIPv4AddrRange = do
301
  ip <- genIPv4
308 302
  netmask <- choose (8::Int, 30)
309
  genIp4NetWithNetmask netmask
303
  return $ ip ++ "/" ++ show netmask
304

  
305
genIPv4Network :: Gen IPv4Network
306
genIPv4Network = mkIPv4Network =<< genIPv4AddrRange
310 307

  
311 308
-- | Helper function to compute the number of hosts in a network
312 309
-- given the netmask. (For IPv4 only.)
......
329 326
  ip <- genIp6Addr
330 327
  return $ ip ++ "/" ++ show netmask
331 328

  
329
-- | Generates a valid, arbitrary tag name with respect to the given
330
-- 'TagKind' for opcodes.
331
genOpCodesTagName :: TagKind -> Gen (Maybe NonEmptyString)
332
genOpCodesTagName TagKindCluster = return Nothing
333
genOpCodesTagName _ = Just <$> (mkNonEmpty =<< genFQDN)
334

  
335
-- | Generates a valid, arbitrary tag name with respect to the given
336
-- 'TagKind' for Luxi.
337
genLuxiTagName :: TagKind -> Gen String
338
genLuxiTagName TagKindCluster = return ""
339
genLuxiTagName _ = genFQDN
340

  
332 341
-- * Helper functions
333 342

  
334 343
-- | Checks for serialisation idempotence.

Also available in: Unified diff