Merge branch 'stable-2.17'
authorBrian Foley <bpfoley@google.com>
Mon, 19 Dec 2016 12:02:39 +0000 (12:02 +0000)
committerBrian Foley <bpfoley@google.com>
Mon, 19 Dec 2016 13:50:08 +0000 (13:50 +0000)
* stable-2.17
  1143: Add gnt-cluster modify --modify-ssh-setup option

* stable-2.15
  Fix gnt-instance console instance unpausing for xl toolstack
  Disable pylint too-many-nested-blocks in _RunCmdPipe
  Reduce nesting in import-export ProcessChildIO
  Reduce nesting in LUOobCommand.Exec
  Reduce nesting in LUInstanceCreate.RunOsScripts
  Reduce nesting in RemoveNodeSshKeyBulk key calculation
  Reduce nesting in RemoveNodeSshKeyBulk ssh logic
  Reduce nesting in gnt-cluster VerifyDisks missing disk loop
  Reduce nesting in _CheckVLANArguments
  Reduce nesting in StartDaemon
  Disable pylint bad-continuation warning
  Disable pylint superfluous-parens warning
  Disable pylint redefined-variable-type warning
  Disable pylint too-many-branches warnings
  Disable pylint broad-except warnings
  Disable incorrect pylint assigning-non-slot warning
  Quell pylint unbalanced-tuple-unpacking warning
  Cleanup: Use new-style classes everywhere
  Quell pylint socket.timeout warning
  Quell the pylint wrong-import-order warnings
  Quell cell-var-from-loop warning
  Use default value lambda param to avoid cell-var-from-loop
  Quell too-many-boolean-expressions
  Remove pylint tests removed in pylint 2.0
  Quell trailing newline
  Quell bad-whitespace warning
  Quell consider-using-enumerate warning
  Disable pylint unsubscriptable-object warning
  Disable pylint bare-except warning
  Disable unwanted pylint wrong-import-position warnings
  Disable pylint unused-wildcard-import warning
  Disable incorrect pylint not-callable warning
  Disable pylint unpacking-non-sequence warning
  Disable pylint misplaced-comparison-constant warning
  Disable incorect pylint simplify-if-statement warning
  Disable pylint eval-used warning
  Disable pylint invalid-name warning
  Disable pylint import-self warning
  Disable some pylint unused-import warnings
  Replace deprecated pylint >=0.27 pragma with new form
  Delete old warning disables removed from pylint 1.6
  Fix pylint >1.4 pycurl no-member warnings
  Cleanup: Remove unused/duplicate module/fn import
  Cleanup: Fix unidiomatic-typecheck
  Cleanup: Remove some unneeded pylint disables
  Cleanup: Iterate dict rather than key list
  Cleanup: Remove unused format key
  Cleanup: StartInstance and RebootInstance return None
  Cleanup: Fix for/else with no break in AddAuthorizedKeys
  Cleanup: Replace map/filters with list comprehensions
  Cleanup: del is a statement not a function
  Cleanup: Use FOO not in BAR instead of not FOO in BAR
  Cleanup: Simplify boolean assignment
  Cleanup: Remove some unnecessary if (...) parens
  Fix invalid variable error for file-based disks
  FIX: Refactor DiagnoseOS to use a loop, not an inner fn
  FIX: Set INSTANCE_NICn_NETWORK_NAME only if net is defined
  StartInstance restores instance state if running
  Allow migrate --cleanup to adopt an instance
  Make migrate --cleanup more robust
  Make finalize_migration_{src,dst} a single op
  Make FinalizeMigration{Src,Dst} more robust
  Fix instance state detection in _Shutdowninstance
  Code cleanup in hypervisor backend
  Fix for incorrect parsing of DRBD versions
  Fix for instance reinstall not updating config
  Change a few errors to report names, not UUIDs
  Give atomicWriteFile temp filenames a more distinct pattern
  LV check failure should print instance name
  Add ganeti-noded and ganeti-rapi --max-clients options
  Disable logging CallRPCMethod timings in non-debug configs
  568 Update hv_kvm to handle output from qemu >= 1.6.0
  Improve cluster verify ssh key errors

Resolve merge conflicts:
  lib/cmdlib/common.py
    caused by 81a68a3 use names not uuids in warnings

  lib/rapi/testutils.py
    trivial module import tweaks

  lib/server/rapi.py
    caused by c1e18c4 --max-clients and pam options

  lib/storage/drbd_info.py
  test/py/ganeti.storage.drbd_unittest.py
    caused by 49980c6 DRBD version parsing -- fixed differently (and
    less flexibly) on master. Use 2.17's version

  test/hs/Test/Ganeti/OpCodes.hs
    caused by e763a23 improve test data generation touching code
    code in 2.16, and modify_ssh_setup cluster param

Signed-off-by: Brian Foley <bpfoley@google.com>
Reviewed-by: Federico Pareschi <morg@google.com>

25 files changed:
1  2 
Makefile.am
lib/backend.py
lib/bootstrap.py
lib/cli_opts.py
lib/client/gnt_cluster.py
lib/client/gnt_instance.py
lib/cmdlib/cluster/__init__.py
lib/cmdlib/common.py
lib/cmdlib/instance_operation.py
lib/cmdlib/instance_set_params.py
lib/errors.py
lib/http/auth.py
lib/hypervisor/hv_kvm/__init__.py
lib/jqueue/__init__.py
lib/rapi/baserlib.py
lib/rapi/testutils.py
lib/server/rapi.py
lib/storage/bdev.py
lib/utils/__init__.py
src/Ganeti/OpCodes.hs
src/Ganeti/OpParams.hs
test/hs/Test/Ganeti/OpCodes.hs
test/py/cmdlib/cluster_unittest.py
test/py/cmdlib/testsupport/cmdlib_testcase.py
test/py/ganeti.hypervisor.hv_kvm_unittest.py

diff --cc Makefile.am
Simple merge
diff --cc lib/backend.py
Simple merge
Simple merge
diff --cc lib/cli_opts.py
Simple merge
Simple merge
Simple merge
Simple merge
@@@ -1600,10 -1595,9 +1601,10 @@@ def EnsureKvmdOnNodes(lu, feedback_fn, 
    # Stop KVM where necessary
    if stop_nodes:
      results = lu.rpc.call_node_ensure_daemon(stop_nodes, constants.KVMD, False)
 -    for node_uuid in stop_nodes:
 -      results[node_uuid].Warn("Failed to stop KVM daemon on node '%s'" %
 -                              lu.cfg.GetNodeName(node_uuid), feedback_fn)
 +    if not silent_stop:
 +      for node_uuid in stop_nodes:
 +        results[node_uuid].Warn("Failed to stop KVM daemon in node '%s'" %
-                                 node_uuid, feedback_fn)
++                                lu.cfg.GetNodeName(node_uuid), feedback_fn)
  
  
  def WarnAboutFailedSshUpdates(result, master_uuid, feedback_fn):
Simple merge
Simple merge
diff --cc lib/errors.py
Simple merge
@@@ -36,11 -36,12 +36,11 @@@ import r
  import base64
  import binascii
  
+ from cStringIO import StringIO
  from ganeti import compat
  from ganeti import http
 -from ganeti import utils
  
- from cStringIO import StringIO
  # Digest types from RFC2617
  HTTP_BASIC_AUTH = "Basic"
  HTTP_DIGEST_AUTH = "Digest"
Simple merge
Simple merge
Simple merge
@@@ -49,10 -51,10 +51,10 @@@ import ganeti.rpc.client as rpcc
  from ganeti import rapi
  
  import ganeti.http.server # pylint: disable=W0611
- import ganeti.server.rapi
+ import ganeti.server.rapi # pylint: disable=W0611
 +from ganeti.rapi.auth import users_file
- import ganeti.rapi.client
+ import ganeti.rapi.client # pylint: disable=W0611
  
 -
  _URI_RE = re.compile(r"https://(?P<host>.*):(?P<port>\d+)(?P<path>/.*)")
  
  
@@@ -48,11 -57,10 +48,10 @@@ from ganeti import serialize
  from ganeti import pathutils
  from ganeti.rapi import connector
  from ganeti.rapi import baserlib
 +from ganeti.rapi.auth import basic_auth
 +from ganeti.rapi.auth import pam
  
  import ganeti.http.auth   # pylint: disable=W0611
- import ganeti.http.server
  
  
  class RemoteApiRequestContext(object):
@@@ -228,18 -338,19 +232,17 @@@ def PrepRapi(options, _)
    """
    mainloop = daemon.Mainloop()
  
 -  users = RapiUsers()
 -
 -  handler = RemoteApiHandler(users.Get, options.reqauth)
 -
 -  # Setup file watcher (it'll be driven by asyncore)
 -  SetupFileWatcher(pathutils.RAPI_USERS_FILE,
 -                   compat.partial(users.Load, pathutils.RAPI_USERS_FILE))
 +  if options.pamauth:
 +    options.reqauth = True
 +    authenticator = pam.PamAuthenticator()
 +  else:
 +    authenticator = basic_auth.BasicAuthenticator()
  
 -  users.Load(pathutils.RAPI_USERS_FILE)
 +  handler = RemoteApiHandler(authenticator, options.reqauth)
  
-   server = \
-     http.server.HttpServer(mainloop, options.bind_address, options.port,
-                            handler,
-                            ssl_params=options.ssl_params, ssl_verify_peer=False)
+   server = http.server.HttpServer(
+       mainloop, options.bind_address, options.port, options.max_clients,
+       handler, ssl_params=options.ssl_params, ssl_verify_peer=False)
    server.Start()
  
    return (mainloop, server)
@@@ -271,10 -380,10 +274,14 @@@ def Main()
                      default=False, action="store_true",
                      help=("Disable anonymous HTTP requests and require"
                            " authentication"))
 +  parser.add_option("--pam-authentication", dest="pamauth",
 +                    default=False, action="store_true",
 +                    help=("Enable RAPI authentication and authorization via"
 +                          " PAM"))
+   parser.add_option("--max-clients", dest="max_clients",
+                     default=20, type="int",
+                     help="Number of simultaneous connections accepted"
+                     " by ganeti-rapi")
  
    daemon.GenericMain(constants.RAPI, parser, CheckRapi, PrepRapi, ExecRapi,
                       default_ssl_cert=pathutils.RAPI_CERT_FILE,
Simple merge
Simple merge
Simple merge
Simple merge
@@@ -143,412 -140,6 +143,413 @@@ arbitraryDataCollectorInterval = d
    intervals <- vector $ length els
    genMaybe . return . containerFromList $ zip els intervals
  
 +genOpCodeFromId :: String -> Maybe ConfigData -> Gen OpCodes.OpCode
 +genOpCodeFromId op_id cfg =
 +  case op_id of
 +    "OP_TEST_DELAY" ->
 +      OpCodes.OpTestDelay <$> arbitrary <*> arbitrary <*>
 +        genNodeNamesNE <*> return Nothing <*> arbitrary <*> arbitrary <*>
 +        arbitrary
 +    "OP_INSTANCE_REPLACE_DISKS" ->
 +      OpCodes.OpInstanceReplaceDisks <$> getInstanceName <*> return Nothing <*>
 +        arbitrary <*> arbitrary <*> arbitrary <*> genDiskIndices <*>
 +        genMaybe genNodeNameNE <*> return Nothing <*> genMaybe genNameNE
 +    "OP_INSTANCE_FAILOVER" ->
 +      OpCodes.OpInstanceFailover <$> getInstanceName <*> return Nothing <*>
 +      arbitrary <*> arbitrary <*> genMaybe genNodeNameNE <*>
 +      return Nothing <*> arbitrary <*> arbitrary <*> genMaybe genNameNE
 +    "OP_INSTANCE_MIGRATE" ->
 +      OpCodes.OpInstanceMigrate <$> getInstanceName <*> return Nothing <*>
 +        arbitrary <*> arbitrary <*> genMaybe getNodeName <*> return Nothing <*>
 +        arbitrary <*> arbitrary <*> arbitrary <*> genMaybe genNameNE <*>
 +        arbitrary <*> arbitrary
 +    "OP_TAGS_GET" ->
 +      arbitraryOpTagsGet
 +    "OP_TAGS_SEARCH" ->
 +      OpCodes.OpTagsSearch <$> genNameNE
 +    "OP_TAGS_SET" ->
 +      arbitraryOpTagsSet
 +    "OP_TAGS_DEL" ->
 +      arbitraryOpTagsDel
 +    "OP_CLUSTER_POST_INIT" -> pure OpCodes.OpClusterPostInit
 +    "OP_CLUSTER_RENEW_CRYPTO" -> OpCodes.OpClusterRenewCrypto
 +       <$> arbitrary -- Node SSL certificates
 +       <*> arbitrary -- renew_ssh_keys
 +       <*> arbitrary -- ssh_key_type
 +       <*> arbitrary -- ssh_key_bits
 +       <*> arbitrary -- verbose
 +       <*> arbitrary -- debug
 +    "OP_CLUSTER_DESTROY" -> pure OpCodes.OpClusterDestroy
 +    "OP_CLUSTER_QUERY" -> pure OpCodes.OpClusterQuery
 +    "OP_CLUSTER_VERIFY" ->
 +      OpCodes.OpClusterVerify <$> arbitrary <*> arbitrary <*>
 +        genListSet Nothing <*> genListSet Nothing <*> arbitrary <*>
 +        genMaybe getGroupName <*> arbitrary
 +    "OP_CLUSTER_VERIFY_CONFIG" ->
 +      OpCodes.OpClusterVerifyConfig <$> arbitrary <*> arbitrary <*>
 +        genListSet Nothing <*> arbitrary
 +    "OP_CLUSTER_VERIFY_GROUP" ->
 +      OpCodes.OpClusterVerifyGroup <$> getGroupName <*> arbitrary <*>
 +        arbitrary <*> genListSet Nothing <*> genListSet Nothing <*>
 +        arbitrary <*> arbitrary
 +    "OP_CLUSTER_VERIFY_DISKS" ->
 +      OpCodes.OpClusterVerifyDisks <$> genMaybe getGroupName <*> arbitrary
 +    "OP_GROUP_VERIFY_DISKS" ->
 +      OpCodes.OpGroupVerifyDisks <$> getGroupName <*> arbitrary
 +    "OP_CLUSTER_REPAIR_DISK_SIZES" ->
 +      OpCodes.OpClusterRepairDiskSizes <$> getInstanceNames
 +    "OP_CLUSTER_CONFIG_QUERY" ->
 +      OpCodes.OpClusterConfigQuery <$> genFieldsNE
 +    "OP_CLUSTER_RENAME" ->
 +      OpCodes.OpClusterRename <$> genNameNE
 +    "OP_CLUSTER_SET_PARAMS" ->
 +      OpCodes.OpClusterSetParams
 +        <$> arbitrary                    -- force
 +        <*> emptyMUD                     -- hv_state
 +        <*> emptyMUD                     -- disk_state
 +        <*> genMaybe genName             -- vg_name
 +        <*> genMaybe arbitrary           -- enabled_hypervisors
 +        <*> genMaybe genEmptyContainer   -- hvparams
 +        <*> emptyMUD                     -- beparams
 +        <*> genMaybe genEmptyContainer   -- os_hvp
 +        <*> genMaybe genEmptyContainer   -- osparams
 +        <*> genMaybe genEmptyContainer   -- osparams_private_cluster
 +        <*> genMaybe genEmptyContainer   -- diskparams
 +        <*> genMaybe arbitrary           -- candidate_pool_size
 +        <*> genMaybe arbitrary           -- max_running_jobs
 +        <*> genMaybe arbitrary           -- max_tracked_jobs
 +        <*> arbitrary                    -- uid_pool
 +        <*> arbitrary                    -- add_uids
 +        <*> arbitrary                    -- remove_uids
 +        <*> arbitrary                    -- maintain_node_health
 +        <*> arbitrary                    -- prealloc_wipe_disks
 +        <*> arbitrary                    -- nicparams
 +        <*> emptyMUD                     -- ndparams
 +        <*> emptyMUD                     -- ipolicy
 +        <*> genMaybe genPrintableAsciiString
 +                                         -- drbd_helper
 +        <*> genMaybe genPrintableAsciiString
 +                                         -- default_iallocator
 +        <*> emptyMUD                     -- default_iallocator_params
 +        <*> genMaybe genMacPrefix        -- mac_prefix
 +        <*> genMaybe genPrintableAsciiString
 +                                         -- master_netdev
 +        <*> arbitrary                    -- master_netmask
 +        <*> genMaybe (listOf genPrintableAsciiStringNE)
 +                                         -- reserved_lvs
 +        <*> genMaybe (listOf ((,) <$> arbitrary
 +                                  <*> genPrintableAsciiStringNE))
 +                                         -- hidden_os
 +        <*> genMaybe (listOf ((,) <$> arbitrary
 +                                  <*> genPrintableAsciiStringNE))
 +                                         -- blacklisted_os
 +        <*> arbitrary                    -- use_external_mip_script
 +        <*> arbitrary                    -- enabled_disk_templates
 +        <*> arbitrary                    -- modify_etc_hosts
++        <*> arbitrary                    -- modify_ssh_config
 +        <*> genMaybe genName             -- file_storage_dir
 +        <*> genMaybe genName             -- shared_file_storage_dir
 +        <*> genMaybe genName             -- gluster_file_storage_dir
 +        <*> genMaybe genPrintableAsciiString
 +                                         -- install_image
 +        <*> genMaybe genPrintableAsciiString
 +                                         -- instance_communication_network
 +        <*> genMaybe genPrintableAsciiString
 +                                         -- zeroing_image
 +        <*> genMaybe (listOf genPrintableAsciiStringNE)
 +                                         -- compression_tools
 +        <*> arbitrary                    -- enabled_user_shutdown
 +        <*> genMaybe arbitraryDataCollector   -- enabled_data_collectors
 +        <*> arbitraryDataCollectorInterval   -- data_collector_interval
 +        <*> genMaybe genName             -- diagnose_data_collector_filename
 +        <*> genMaybe (fromPositive <$> arbitrary) -- maintd round interval
 +        <*> genMaybe arbitrary           -- enable maintd balancing
 +        <*> genMaybe arbitrary           -- maintd balancing threshold
 +    "OP_CLUSTER_REDIST_CONF" -> pure OpCodes.OpClusterRedistConf
 +    "OP_CLUSTER_ACTIVATE_MASTER_IP" ->
 +      pure OpCodes.OpClusterActivateMasterIp
 +    "OP_CLUSTER_DEACTIVATE_MASTER_IP" ->
 +      pure OpCodes.OpClusterDeactivateMasterIp
 +    "OP_QUERY" ->
 +      OpCodes.OpQuery <$> arbitrary <*> arbitrary <*> genNamesNE <*>
 +      pure Nothing
 +    "OP_QUERY_FIELDS" ->
 +      OpCodes.OpQueryFields <$> arbitrary <*> genMaybe genNamesNE
 +    "OP_OOB_COMMAND" ->
 +      OpCodes.OpOobCommand <$> getNodeNames <*> return Nothing <*>
 +        arbitrary <*> arbitrary <*> arbitrary <*> (arbitrary `suchThat` (>0))
 +    "OP_NODE_REMOVE" ->
 +      OpCodes.OpNodeRemove <$> getNodeName <*> return Nothing <*>
 +        arbitrary <*> arbitrary
 +    "OP_NODE_ADD" ->
 +      OpCodes.OpNodeAdd <$> getNodeName <*> emptyMUD <*> emptyMUD <*>
 +        genMaybe genNameNE <*> genMaybe genNameNE <*> arbitrary <*>
 +        genMaybe genNameNE <*> arbitrary <*> arbitrary <*> emptyMUD <*>
 +        arbitrary <*> arbitrary <*> arbitrary
 +    "OP_NODE_QUERYVOLS" ->
 +      OpCodes.OpNodeQueryvols <$> genNamesNE <*> genNodeNamesNE
 +    "OP_NODE_QUERY_STORAGE" ->
 +      OpCodes.OpNodeQueryStorage <$> genNamesNE <*> arbitrary <*>
 +        getNodeNames <*> genMaybe genNameNE
 +    "OP_NODE_MODIFY_STORAGE" ->
 +      OpCodes.OpNodeModifyStorage <$> getNodeName <*> return Nothing <*>
 +        arbitrary <*> genMaybe genNameNE <*> pure emptyJSObject
 +    "OP_REPAIR_NODE_STORAGE" ->
 +      OpCodes.OpRepairNodeStorage <$> getNodeName <*> return Nothing <*>
 +        arbitrary <*> genMaybe genNameNE <*> arbitrary
 +    "OP_NODE_SET_PARAMS" ->
 +      OpCodes.OpNodeSetParams <$> getNodeName <*> return Nothing <*>
 +        arbitrary <*> emptyMUD <*> emptyMUD <*> arbitrary <*> arbitrary <*>
 +        arbitrary <*> arbitrary <*> arbitrary <*> arbitrary <*>
 +        genMaybe genNameNE <*> emptyMUD <*> arbitrary <*> arbitrary <*>
 +        arbitrary
 +    "OP_NODE_POWERCYCLE" ->
 +      OpCodes.OpNodePowercycle <$> getNodeName <*> return Nothing <*> arbitrary
 +    "OP_NODE_MIGRATE" ->
 +      OpCodes.OpNodeMigrate <$> getNodeName <*> return Nothing <*>
 +        arbitrary <*> arbitrary <*> genMaybe getNodeName <*> return Nothing <*>
 +        arbitrary <*> arbitrary <*> genMaybe genNameNE
 +    "OP_NODE_EVACUATE" ->
 +      OpCodes.OpNodeEvacuate <$> arbitrary <*> getNodeName <*>
 +        return Nothing <*> genMaybe getNodeName <*> return Nothing <*>
 +        genMaybe genNameNE <*> arbitrary <*> arbitrary
 +    "OP_INSTANCE_CREATE" ->
 +      OpCodes.OpInstanceCreate
 +        <$> genFQDN                         -- instance_name
 +        <*> arbitrary                       -- force_variant
 +        <*> arbitrary                       -- wait_for_sync
 +        <*> arbitrary                       -- name_check
 +        <*> arbitrary                       -- ignore_ipolicy
 +        <*> arbitrary                       -- opportunistic_locking
 +        <*> pure emptyJSObject              -- beparams
 +        <*> arbitrary                       -- disks
 +        <*> arbitrary                       -- disk_template
 +        <*> genMaybe getGroupName           -- group_name
 +        <*> arbitrary                       -- file_driver
 +        <*> genMaybe genNameNE              -- file_storage_dir
 +        <*> pure emptyJSObject              -- hvparams
 +        <*> arbitrary                       -- hypervisor
 +        <*> genMaybe genNameNE              -- iallocator
 +        <*> arbitrary                       -- identify_defaults
 +        <*> arbitrary                       -- ip_check
 +        <*> arbitrary                       -- conflicts_check
 +        <*> arbitrary                       -- mode
 +        <*> arbitrary                       -- nics
 +        <*> arbitrary                       -- no_install
 +        <*> pure emptyJSObject              -- osparams
 +        <*> genMaybe arbitraryPrivateJSObj  -- osparams_private
 +        <*> genMaybe arbitrarySecretJSObj   -- osparams_secret
 +        <*> genMaybe genNameNE              -- os_type
 +        <*> genMaybe getNodeName            -- pnode
 +        <*> return Nothing                  -- pnode_uuid
 +        <*> genMaybe getNodeName            -- snode
 +        <*> return Nothing                  -- snode_uuid
 +        <*> genMaybe (pure [])              -- source_handshake
 +        <*> genMaybe genNodeNameNE          -- source_instance_name
 +        <*> arbitrary                       -- source_shutdown_timeout
 +        <*> genMaybe genNodeNameNE          -- source_x509_ca
 +        <*> return Nothing                  -- src_node
 +        <*> genMaybe genNodeNameNE          -- src_node_uuid
 +        <*> genMaybe genNameNE              -- src_path
 +        <*> genPrintableAsciiString         -- compress
 +        <*> arbitrary                       -- start
 +        <*> arbitrary                       -- forthcoming
 +        <*> arbitrary                       -- commit
 +        <*> (genTags >>= mapM mkNonEmpty)   -- tags
 +        <*> arbitrary                       -- instance_communication
 +        <*> arbitrary                       -- helper_startup_timeout
 +        <*> arbitrary                       -- helper_shutdown_timeout
 +    "OP_INSTANCE_MULTI_ALLOC" ->
 +      OpCodes.OpInstanceMultiAlloc <$> arbitrary <*> genMaybe genNameNE <*>
 +      pure []
 +    "OP_INSTANCE_REINSTALL" ->
 +      OpCodes.OpInstanceReinstall <$> getInstanceName <*> return Nothing <*>
 +        arbitrary <*> genMaybe genNameNE <*> genMaybe (pure emptyJSObject)
 +        <*> genMaybe arbitraryPrivateJSObj <*> genMaybe arbitrarySecretJSObj
 +        <*> arbitrary <*> arbitrary
 +        <*> genMaybe (listOf genPrintableAsciiString)
 +        <*> genMaybe (listOf genPrintableAsciiString)
 +    "OP_INSTANCE_REMOVE" ->
 +      OpCodes.OpInstanceRemove <$> getInstanceName <*> return Nothing <*>
 +        arbitrary <*> arbitrary
 +    "OP_INSTANCE_RENAME" ->
 +      OpCodes.OpInstanceRename <$> getInstanceName <*> return Nothing <*>
 +        (genFQDN >>= mkNonEmpty) <*> arbitrary <*> arbitrary
 +    "OP_INSTANCE_STARTUP" ->
 +      OpCodes.OpInstanceStartup <$>
 +        getInstanceName <*>     -- instance_name
 +        return Nothing <*>      -- instance_uuid
 +        arbitrary <*>           -- force
 +        arbitrary <*>           -- ignore_offline_nodes
 +        pure emptyJSObject <*>  -- hvparams
 +        pure emptyJSObject <*>  -- beparams
 +        arbitrary <*>           -- no_remember
 +        arbitrary <*>           -- startup_paused
 +        arbitrary               -- shutdown_timeout
 +    "OP_INSTANCE_SHUTDOWN" ->
 +      OpCodes.OpInstanceShutdown <$> getInstanceName <*> return Nothing <*>
 +        arbitrary <*> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary
 +    "OP_INSTANCE_REBOOT" ->
 +      OpCodes.OpInstanceReboot <$> getInstanceName <*> return Nothing <*>
 +        arbitrary <*> arbitrary <*> arbitrary
 +    "OP_INSTANCE_MOVE" ->
 +      OpCodes.OpInstanceMove <$> getInstanceName <*> return Nothing <*>
 +        arbitrary <*> arbitrary <*> getNodeName <*>
 +        return Nothing <*> genPrintableAsciiString <*> arbitrary
 +    "OP_INSTANCE_CONSOLE" -> OpCodes.OpInstanceConsole <$> getInstanceName <*>
 +        return Nothing
 +    "OP_INSTANCE_ACTIVATE_DISKS" ->
 +      OpCodes.OpInstanceActivateDisks <$> getInstanceName <*> return Nothing <*>
 +        arbitrary <*> arbitrary
 +    "OP_INSTANCE_DEACTIVATE_DISKS" ->
 +      OpCodes.OpInstanceDeactivateDisks <$> genFQDN <*> return Nothing <*>
 +        arbitrary
 +    "OP_INSTANCE_RECREATE_DISKS" ->
 +      OpCodes.OpInstanceRecreateDisks <$> getInstanceName <*> return Nothing <*>
 +        arbitrary <*> genNodeNamesNE <*> return Nothing <*> genMaybe getNodeName
 +    "OP_INSTANCE_QUERY_DATA" ->
 +      OpCodes.OpInstanceQueryData <$> arbitrary <*>
 +        getInstanceNames <*> arbitrary
 +    "OP_INSTANCE_SET_PARAMS" ->
 +      OpCodes.OpInstanceSetParams
 +        <$> getInstanceName                 -- instance_name
 +        <*> return Nothing                  -- instance_uuid
 +        <*> arbitrary                       -- force
 +        <*> arbitrary                       -- force_variant
 +        <*> arbitrary                       -- ignore_ipolicy
 +        <*> arbitrary                       -- nics
 +        <*> arbitrary                       -- disks
 +        <*> pure emptyJSObject              -- beparams
 +        <*> arbitrary                       -- runtime_mem
 +        <*> pure emptyJSObject              -- hvparams
 +        <*> arbitrary                       -- disk_template
 +        <*> pure emptyJSObject              -- ext_params
 +        <*> arbitrary                       -- file_driver
 +        <*> genMaybe genNameNE              -- file_storage_dir
 +        <*> genMaybe getNodeName            -- pnode
 +        <*> return Nothing                  -- pnode_uuid
 +        <*> genMaybe getNodeName            -- remote_node
 +        <*> return Nothing                  -- remote_node_uuid
 +        <*> genMaybe genNameNE              -- iallocator
 +        <*> genMaybe genNameNE              -- os_name
 +        <*> pure emptyJSObject              -- osparams
 +        <*> genMaybe arbitraryPrivateJSObj  -- osparams_private
 +        <*> arbitrary                       -- clear_osparams
 +        <*> arbitrary                       -- clear_osparams_private
 +        <*> genMaybe (listOf genPrintableAsciiString) -- remove_osparams
 +        <*> genMaybe (listOf genPrintableAsciiString) -- remove_osparams_private
 +        <*> arbitrary                       -- wait_for_sync
 +        <*> arbitrary                       -- offline
 +        <*> arbitrary                       -- conflicts_check
 +        <*> arbitrary                       -- hotplug
 +        <*> arbitrary                       -- hotplug_if_possible
 +        <*> arbitrary                       -- instance_communication
 +    "OP_INSTANCE_GROW_DISK" ->
 +      OpCodes.OpInstanceGrowDisk <$> getInstanceName <*> return Nothing <*>
 +        arbitrary <*> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary
 +    "OP_INSTANCE_CHANGE_GROUP" ->
 +      OpCodes.OpInstanceChangeGroup <$> getInstanceName <*> return Nothing <*>
 +        arbitrary <*> genMaybe genNameNE <*>
 +        genMaybe (resize maxNodes (listOf genNameNE))
 +    "OP_GROUP_ADD" ->
 +      OpCodes.OpGroupAdd <$> genNameNE <*> arbitrary <*>
 +        emptyMUD <*> genMaybe genEmptyContainer <*>
 +        emptyMUD <*> emptyMUD <*> emptyMUD
 +    "OP_GROUP_ASSIGN_NODES" ->
 +      OpCodes.OpGroupAssignNodes <$> getGroupName <*>
 +        arbitrary <*> getNodeNames <*> return Nothing
 +    "OP_GROUP_SET_PARAMS" ->
 +      OpCodes.OpGroupSetParams <$> getGroupName <*>
 +        arbitrary <*> emptyMUD <*> genMaybe genEmptyContainer <*>
 +        emptyMUD <*> emptyMUD <*> emptyMUD
 +    "OP_GROUP_REMOVE" ->
 +      OpCodes.OpGroupRemove <$> getGroupName
 +    "OP_GROUP_RENAME" ->
 +      OpCodes.OpGroupRename <$> getGroupName <*> genNameNE
 +    "OP_GROUP_EVACUATE" ->
 +      OpCodes.OpGroupEvacuate <$> getGroupName <*>
 +        arbitrary <*> genMaybe genNameNE <*> genMaybe genNamesNE <*>
 +        arbitrary <*> arbitrary
 +    "OP_OS_DIAGNOSE" ->
 +      OpCodes.OpOsDiagnose <$> genFieldsNE <*> genNamesNE
 +    "OP_EXT_STORAGE_DIAGNOSE" ->
 +      OpCodes.OpOsDiagnose <$> genFieldsNE <*> genNamesNE
 +    "OP_BACKUP_PREPARE" ->
 +      OpCodes.OpBackupPrepare <$> getInstanceName <*>
 +        return Nothing <*> arbitrary
 +    "OP_BACKUP_EXPORT" ->
 +      OpCodes.OpBackupExport
 +        <$> getInstanceName          -- instance_name
 +        <*> return Nothing           -- instance_uuid
 +        <*> genPrintableAsciiString  -- compress
 +        <*> arbitrary                -- shutdown_timeout
 +        <*> arbitrary                -- target_node
 +        <*> return Nothing           -- target_node_uuid
 +        <*> arbitrary                -- shutdown
 +        <*> arbitrary                -- remove_instance
 +        <*> arbitrary                -- ignore_remove_failures
 +        <*> arbitrary                -- mode
 +        <*> genMaybe (pure [])       -- x509_key_name
 +        <*> genMaybe genNameNE       -- destination_x509_ca
 +        <*> arbitrary                -- zero_free_space
 +        <*> arbitrary                -- zeroing_timeout_fixed
 +        <*> arbitrary                -- zeroing_timeout_per_mib
 +        <*> arbitrary                -- long_sleep
 +    "OP_BACKUP_REMOVE" ->
 +      OpCodes.OpBackupRemove <$> getInstanceName <*> return Nothing
 +    "OP_TEST_ALLOCATOR" ->
 +      OpCodes.OpTestAllocator <$> arbitrary <*> arbitrary <*>
 +        genNameNE <*> genMaybe (pure []) <*> genMaybe (pure []) <*>
 +        arbitrary <*> genMaybe genNameNE <*>
 +        (genTags >>= mapM mkNonEmpty) <*>
 +        arbitrary <*> arbitrary <*> genMaybe genNameNE <*>
 +        arbitrary <*> genMaybe genNodeNamesNE <*> arbitrary <*>
 +        genMaybe genNamesNE <*> arbitrary <*> arbitrary <*>
 +        genMaybe getGroupName
 +    "OP_TEST_JQUEUE" ->
 +      OpCodes.OpTestJqueue <$> arbitrary <*> arbitrary <*>
 +        resize 20 (listOf genFQDN) <*> arbitrary
 +    "OP_TEST_OS_PARAMS" ->
 +      OpCodes.OpTestOsParams <$> genMaybe arbitrarySecretJSObj
 +    "OP_TEST_DUMMY" ->
 +      OpCodes.OpTestDummy <$> pure J.JSNull <*> pure J.JSNull <*>
 +        pure J.JSNull <*> pure J.JSNull
 +    "OP_NETWORK_ADD" ->
 +      OpCodes.OpNetworkAdd <$> genNameNE <*> genIPv4Network <*>
 +        genMaybe genIPv4Address <*> pure Nothing <*> pure Nothing <*>
 +        genMaybe genMacPrefix <*> genMaybe (listOf genIPv4Address) <*>
 +        arbitrary <*> (genTags >>= mapM mkNonEmpty)
 +    "OP_NETWORK_REMOVE" ->
 +      OpCodes.OpNetworkRemove <$> genNameNE <*> arbitrary
 +    "OP_NETWORK_SET_PARAMS" ->
 +      OpCodes.OpNetworkSetParams <$> genNameNE <*>
 +        genMaybe genIPv4Address <*> pure Nothing <*> pure Nothing <*>
 +        genMaybe genMacPrefix <*> genMaybe (listOf genIPv4Address) <*>
 +        genMaybe (listOf genIPv4Address)
 +    "OP_NETWORK_CONNECT" ->
 +      OpCodes.OpNetworkConnect <$> getGroupName <*>
 +        genNameNE <*> arbitrary <*> genNameNE <*> genPrintableAsciiString <*>
 +        arbitrary
 +    "OP_NETWORK_DISCONNECT" ->
 +      OpCodes.OpNetworkDisconnect <$> getGroupName <*>
 +        genNameNE
 +    "OP_RESTRICTED_COMMAND" ->
 +      OpCodes.OpRestrictedCommand <$> arbitrary <*> getNodeNames <*>
 +        return Nothing <*> genNameNE
 +    "OP_REPAIR_COMMAND" ->
 +      OpCodes.OpRepairCommand <$> getNodeName <*> genNameNE <*>
 +        genMaybe genPrintableAsciiStringNE
 +    _ -> fail $ "Undefined arbitrary for opcode " ++ op_id
 +  where getInstanceName =
 +          case cfg of
 +               Just c -> fmap (fromMaybe "") . genValidInstanceName $ c
 +               Nothing -> genFQDN
 +        getNodeName = maybe genFQDN genValidNodeName cfg >>= mkNonEmpty
 +        getGroupName = maybe genName genValidGroupName cfg >>= mkNonEmpty
 +        getInstanceNames = resize maxNodes (listOf getInstanceName) >>=
 +                           mapM mkNonEmpty
 +        getNodeNames = resize maxNodes (listOf getNodeName)
 +
  instance Arbitrary OpCodes.OpCode where
    arbitrary = do
      op_id <- elements OpCodes.allOpIDs
Simple merge