Revision a5efec93

b/lib/bootstrap.py
786 786
    disk_state_static=disk_state,
787 787
    enabled_disk_templates=enabled_disk_templates,
788 788
    candidate_certs=candidate_certs,
789
    osparams={},
790
    osparams_private_cluster={}
789 791
    )
790 792
  master_node_config = objects.Node(name=hostname.name,
791 793
                                    primary_ip=hostname.ip,
b/lib/luxi.py
95 95
    return self.CallMethod(REQ_PICKUP_JOB, (job,))
96 96

  
97 97
  def SubmitJob(self, ops):
98
    ops_state = map(lambda op: op.__getstate__(), ops)
98
    ops_state = map(lambda op: op.__getstate__()
99
                               if not isinstance(op, objects.ConfigObject)
100
                               else op.ToDict(_with_private=True), ops)
99 101
    return self.CallMethod(REQ_SUBMIT_JOB, (ops_state, ))
100 102

  
101 103
  def SubmitJobToDrainedQueue(self, ops):
b/lib/objects.py
47 47
from ganeti import netutils
48 48
from ganeti import outils
49 49
from ganeti import utils
50
from ganeti import serializer
50 51

  
51 52
from socket import AF_INET
52 53

  
......
213 214

  
214 215
    """
215 216

  
216
  def ToDict(self):
217
  def ToDict(self, _with_private=False):
217 218
    """Convert to a dict holding only standard python types.
218 219

  
219 220
    The generic routine just dumps all of this object's attributes in
......
222 223
    which case the object should subclass the function in order to
223 224
    make sure all objects returned are only standard python types.
224 225

  
226
    Private fields can be included or not with the _with_private switch.
227
    The actual implementation of this switch is left for those subclassses
228
    with private fields to implement.
229

  
230
    @type _with_private: bool
231
    @param _with_private: if True, the object will leak its private fields in
232
                          the dictionary representation. If False, the values
233
                          will be replaced with None.
234

  
225 235
    """
226 236
    result = {}
227 237
    for name in self.GetAllSlots():
......
333 343
    except KeyError:
334 344
      raise errors.TagError("Tag not found")
335 345

  
336
  def ToDict(self):
346
  def ToDict(self, _with_private=False):
337 347
    """Taggable-object-specific conversion to standard python types.
338 348

  
339 349
    This replaces the tags set with a list.
340 350

  
341 351
    """
342
    bo = super(TaggableObject, self).ToDict()
352
    bo = super(TaggableObject, self).ToDict(_with_private=_with_private)
343 353

  
344 354
    tags = bo.get("tags", None)
345 355
    if isinstance(tags, set):
......
388 398
    "serial_no",
389 399
    ] + _TIMESTAMPS
390 400

  
391
  def ToDict(self):
401
  def ToDict(self, _with_private=False):
392 402
    """Custom function for top-level config data.
393 403

  
394 404
    This just replaces the list of instances, nodes and the cluster
395 405
    with standard python types.
396 406

  
397 407
    """
398
    mydict = super(ConfigData, self).ToDict()
408
    mydict = super(ConfigData, self).ToDict(_with_private=_with_private)
399 409
    mydict["cluster"] = mydict["cluster"].ToDict()
400 410
    for key in "nodes", "instances", "nodegroups", "networks":
401 411
      mydict[key] = outils.ContainerToDicts(mydict[key])
......
746 756
    self.dynamic_params = dyn_disk_params
747 757

  
748 758
  # pylint: disable=W0221
749
  def ToDict(self, include_dynamic_params=False):
759
  def ToDict(self, include_dynamic_params=False,
760
             _with_private=False):
750 761
    """Disk-specific conversion to standard python types.
751 762

  
752 763
    This replaces the children lists of objects with lists of
......
1063 1074
    "hvparams",
1064 1075
    "beparams",
1065 1076
    "osparams",
1077
    "osparams_private",
1066 1078
    "admin_state",
1067 1079
    "nics",
1068 1080
    "disks",
......
1187 1199
                                 " 0 to %d" % (idx, len(self.disks) - 1),
1188 1200
                                 errors.ECODE_INVAL)
1189 1201

  
1190
  def ToDict(self):
1202
  def ToDict(self, _with_private=False):
1191 1203
    """Instance-specific conversion to standard python types.
1192 1204

  
1193 1205
    This replaces the children lists of objects with lists of standard
1194 1206
    python types.
1195 1207

  
1196 1208
    """
1197
    bo = super(Instance, self).ToDict()
1209
    bo = super(Instance, self).ToDict(_with_private=_with_private)
1210

  
1211
    if _with_private:
1212
      bo["osparams_private"] = self.osparams_private.Unprivate()
1198 1213

  
1199 1214
    for attr in "nics", "disks":
1200 1215
      alist = bo.get(attr, None)
......
1238 1253
          pass
1239 1254
    if self.osparams is None:
1240 1255
      self.osparams = {}
1256
    if self.osparams_private is None:
1257
      self.osparams_private = serializer.PrivateDict()
1241 1258
    UpgradeBeParams(self.beparams)
1242 1259
    if self.disks_active is None:
1243 1260
      self.disks_active = self.admin_state == constants.ADMINST_UP
......
1407 1424
    if self.powered is None:
1408 1425
      self.powered = True
1409 1426

  
1410
  def ToDict(self):
1427
  def ToDict(self, _with_private=False):
1411 1428
    """Custom function for serializing.
1412 1429

  
1413 1430
    """
1414
    data = super(Node, self).ToDict()
1431
    data = super(Node, self).ToDict(_with_private=_with_private)
1415 1432

  
1416 1433
    hv_state = data.get("hv_state", None)
1417 1434
    if hv_state is not None:
......
1459 1476
    "networks",
1460 1477
    ] + _TIMESTAMPS + _UUID
1461 1478

  
1462
  def ToDict(self):
1479
  def ToDict(self, _with_private=False):
1463 1480
    """Custom function for nodegroup.
1464 1481

  
1465 1482
    This discards the members object, which gets recalculated and is only kept
1466 1483
    in memory.
1467 1484

  
1468 1485
    """
1469
    mydict = super(NodeGroup, self).ToDict()
1486
    mydict = super(NodeGroup, self).ToDict(_with_private=_with_private)
1470 1487
    del mydict["members"]
1471 1488
    return mydict
1472 1489

  
......
1559 1576
    "os_hvp",
1560 1577
    "beparams",
1561 1578
    "osparams",
1579
    "osparams_private_cluster",
1562 1580
    "nicparams",
1563 1581
    "ndparams",
1564 1582
    "diskparams",
......
1600 1618
    if self.os_hvp is None:
1601 1619
      self.os_hvp = {}
1602 1620

  
1603
    # osparams added before 2.2
1604 1621
    if self.osparams is None:
1605 1622
      self.osparams = {}
1623
    # osparams_private_cluster added in 2.12
1624
    if self.osparams_private_cluster is None:
1625
      self.osparams_private_cluster = {}
1606 1626

  
1607 1627
    self.ndparams = UpgradeNDParams(self.ndparams)
1608 1628

  
......
1719 1739
    """
1720 1740
    return self.enabled_hypervisors[0]
1721 1741

  
1722
  def ToDict(self):
1742
  def ToDict(self, _with_private=False):
1723 1743
    """Custom function for cluster.
1724 1744

  
1725 1745
    """
1726
    mydict = super(Cluster, self).ToDict()
1746
    mydict = super(Cluster, self).ToDict(_with_private=_with_private)
1747

  
1748
    # Explicitly save private parameters.
1749
    if _with_private:
1750
      for os in mydict["osparams_private_cluster"]:
1751
        mydict["osparams_private_cluster"][os] = \
1752
          self.osparams_private_cluster[os].Unprivate()
1727 1753

  
1728 1754
    if self.tcpudp_port_pool is None:
1729 1755
      tcpudp_port_pool = []
......
1855 1881
    """
1856 1882
    return FillDict(self.nicparams.get(constants.PP_DEFAULT, {}), nicparams)
1857 1883

  
1858
  def SimpleFillOS(self, os_name, os_params):
1884
  def SimpleFillOS(self, os_name,
1885
                    os_params_public,
1886
                    os_params_private=None,
1887
                    os_params_secret=None):
1859 1888
    """Fill an instance's osparams dict with cluster defaults.
1860 1889

  
1861 1890
    @type os_name: string
1862 1891
    @param os_name: the OS name to use
1863
    @type os_params: dict
1864
    @param os_params: the dict to fill with default values
1892
    @type os_params_public: dict
1893
    @param os_params_public: the dict to fill with default values
1894
    @type os_params_private: dict
1895
    @param os_params_private: the dict with private fields to fill
1896
                              with default values. Not passing this field
1897
                              results in no private fields being added to the
1898
                              return value. Private fields will be wrapped in
1899
                              L{Private} objects.
1900
    @type os_params_secret: dict
1901
    @param os_params_secret: the dict with secret fields to fill
1902
                             with default values. Not passing this field
1903
                             results in no secret fields being added to the
1904
                             return value. Private fields will be wrapped in
1905
                             L{Private} objects.
1865 1906
    @rtype: dict
1866 1907
    @return: a copy of the instance's osparams with missing keys filled from
1867
        the cluster defaults
1908
        the cluster defaults. Private and secret parameters are not included
1909
        unless the respective optional parameters are supplied.
1868 1910

  
1869 1911
    """
1870 1912
    name_only = os_name.split("+", 1)[0]
1871
    # base OS
1872
    result = self.osparams.get(name_only, {})
1873
    # OS with variant
1874
    result = FillDict(result, self.osparams.get(os_name, {}))
1875
    # specified params
1876
    return FillDict(result, os_params)
1913

  
1914
    defaults_base_public = self.osparams.get(name_only, {})
1915
    defaults_public = FillDict(defaults_base_public,
1916
                               self.osparams.get(os_name, {}))
1917
    params_public = FillDict(defaults_public, os_params_public)
1918

  
1919
    if os_params_private is not None:
1920
      defaults_base_private = self.osparams_private_cluster.get(name_only, {})
1921
      defaults_private = FillDict(defaults_base_private,
1922
                                  self.osparams_private_cluster.get(os_name,
1923
                                                                    {}))
1924
      params_private = FillDict(defaults_private, os_params_private)
1925
    else:
1926
      params_private = {}
1927

  
1928
    if os_params_secret is not None:
1929
      # There can't be default secret settings, so there's nothing to be done.
1930
      params_secret = os_params_secret
1931
    else:
1932
      params_secret = {}
1933

  
1934
    # Enforce that the set of keys be distinct:
1935
    duplicate_keys = utils.GetRepeatedKeys(params_public,
1936
                                           params_private,
1937
                                           params_secret)
1938
    if not duplicate_keys:
1939

  
1940
      # Actually update them:
1941
      params_public.update(params_private)
1942
      params_public.update(params_secret)
1943

  
1944
      return params_public
1945

  
1946
    else:
1947

  
1948
      def formatter(keys):
1949
        return utils.CommaJoin(sorted(map(repr, keys))) if keys else "(none)"
1950

  
1951
      #Lose the values.
1952
      params_public = set(params_public)
1953
      params_private = set(params_private)
1954
      params_secret = set(params_secret)
1955

  
1956
      msg = """Cannot assign multiple values to OS parameters.
1957

  
1958
      Conflicting OS parameters that would have been set by this operation:
1959
      - at public visibility:  {public}
1960
      - at private visibility: {private}
1961
      - at secret visibility:  {secret}
1962
      """.format(dupes=formatter(duplicate_keys),
1963
                 public=formatter(params_public & duplicate_keys),
1964
                 private=formatter(params_private & duplicate_keys),
1965
                 secret=formatter(params_secret & duplicate_keys))
1966
      raise errors.OpPrereqError(msg)
1877 1967

  
1878 1968
  @staticmethod
1879 1969
  def SimpleFillHvState(hv_state):
......
2061 2151
    "fields",
2062 2152
    ]
2063 2153

  
2064
  def ToDict(self):
2154
  def ToDict(self, _with_private=False):
2065 2155
    """Custom function for serializing.
2066 2156

  
2067 2157
    """
b/src/Ganeti/Config.hs
276 276
  return $ fillBeParams parentParams (instBeparams inst)
277 277

  
278 278
-- | Retrieves the instance os params, missing values filled with cluster
279
-- defaults.
279
-- defaults. This does NOT include private and secret parameters.
280 280
getFilledInstOsParams :: ConfigData -> Instance -> OsParams
281 281
getFilledInstOsParams cfg inst =
282 282
  let osLookupName = takeWhile (/= '+') (instOs inst)
b/src/Ganeti/HTools/Program/Harep.hs
307 307
                                 , opInstanceUuid = Nothing
308 308
                                 , opOsType = Nothing
309 309
                                 , opTempOsParams = Nothing
310
                                 , opOsparamsPrivate = Nothing
311
                                 , opOsparamsSecret = Nothing
310 312
                                 , opForceVariant = False
311 313
                                 }
312 314
           ])
......
359 361
                                 , opInstanceUuid = Nothing
360 362
                                 , opOsType = Nothing
361 363
                                 , opTempOsParams = Nothing
364
                                 , opOsparamsPrivate = Nothing
365
                                 , opOsparamsSecret = Nothing
362 366
                                 , opForceVariant = False
363 367
                                 }
364 368
           ])
b/src/Ganeti/Objects.hs
31 31
module Ganeti.Objects
32 32
  ( HvParams
33 33
  , OsParams
34
  , OsParamsPrivate
34 35
  , PartialNicParams(..)
35 36
  , FilledNicParams(..)
36 37
  , fillNicParams
......
123 124
-- container, since the keys are dynamically declared by the OSes, and
124 125
-- the values are always strings.
125 126
type OsParams = Container String
127
type OsParamsPrivate = Container (Private String)
126 128

  
127 129
-- | Class of objects that have timestamps.
128 130
class TimeStampObject a where
......
440 442
  ])
441 443

  
442 444
$(buildObject "Instance" "inst" $
443
  [ simpleField "name"           [t| String             |]
444
  , simpleField "primary_node"   [t| String             |]
445
  , simpleField "os"             [t| String             |]
446
  , simpleField "hypervisor"     [t| Hypervisor         |]
447
  , simpleField "hvparams"       [t| HvParams           |]
448
  , simpleField "beparams"       [t| PartialBeParams    |]
449
  , simpleField "osparams"       [t| OsParams           |]
450
  , simpleField "admin_state"    [t| AdminState         |]
451
  , simpleField "nics"           [t| [PartialNic]       |]
452
  , simpleField "disks"          [t| [Disk]             |]
453
  , simpleField "disk_template"  [t| DiskTemplate       |]
454
  , simpleField "disks_active"   [t| Bool               |]
445
  [ simpleField "name"             [t| String             |]
446
  , simpleField "primary_node"     [t| String             |]
447
  , simpleField "os"               [t| String             |]
448
  , simpleField "hypervisor"       [t| Hypervisor         |]
449
  , simpleField "hvparams"         [t| HvParams           |]
450
  , simpleField "beparams"         [t| PartialBeParams    |]
451
  , simpleField "osparams"         [t| OsParams           |]
452
  , simpleField "osparams_private" [t| OsParamsPrivate    |]
453
  , simpleField "admin_state"      [t| AdminState         |]
454
  , simpleField "nics"             [t| [PartialNic]       |]
455
  , simpleField "disks"            [t| [Disk]             |]
456
  , simpleField "disk_template"    [t| DiskTemplate       |]
457
  , simpleField "disks_active"     [t| Bool               |]
455 458
  , optionalField $ simpleField "network_port" [t| Int  |]
456 459
  ]
457 460
  ++ timeStampFields
......
650 653

  
651 654
-- | Cluster OsParams.
652 655
type ClusterOsParams = Container OsParams
656
type ClusterOsParamsPrivate = Container (Private OsParams)
653 657

  
654 658
-- | Cluster NicParams.
655 659
type ClusterNicParams = Container FilledNicParams
......
665 669

  
666 670
-- * Cluster definitions
667 671
$(buildObject "Cluster" "cluster" $
668
  [ simpleField "rsahostkeypub"             [t| String           |]
672
  [ simpleField "rsahostkeypub"             [t| String                 |]
669 673
  , optionalField $
670
    simpleField "dsahostkeypub"             [t| String           |]
671
  , simpleField "highest_used_port"         [t| Int              |]
672
  , simpleField "tcpudp_port_pool"          [t| [Int]            |]
673
  , simpleField "mac_prefix"                [t| String           |]
674
    simpleField "dsahostkeypub"             [t| String                 |]
675
  , simpleField "highest_used_port"         [t| Int                    |]
676
  , simpleField "tcpudp_port_pool"          [t| [Int]                  |]
677
  , simpleField "mac_prefix"                [t| String                 |]
674 678
  , optionalField $
675
    simpleField "volume_group_name"         [t| String           |]
676
  , simpleField "reserved_lvs"              [t| [String]         |]
679
    simpleField "volume_group_name"         [t| String                 |]
680
  , simpleField "reserved_lvs"              [t| [String]               |]
677 681
  , optionalField $
678
    simpleField "drbd_usermode_helper"      [t| String           |]
679
  , simpleField "master_node"               [t| String           |]
680
  , simpleField "master_ip"                 [t| String           |]
681
  , simpleField "master_netdev"             [t| String           |]
682
  , simpleField "master_netmask"            [t| Int              |]
683
  , simpleField "use_external_mip_script"   [t| Bool             |]
684
  , simpleField "cluster_name"              [t| String           |]
685
  , simpleField "file_storage_dir"          [t| String           |]
686
  , simpleField "shared_file_storage_dir"   [t| String           |]
687
  , simpleField "gluster_storage_dir"       [t| String           |]
688
  , simpleField "enabled_hypervisors"       [t| [Hypervisor]     |]
689
  , simpleField "hvparams"                  [t| ClusterHvParams  |]
690
  , simpleField "os_hvp"                    [t| OsHvParams       |]
691
  , simpleField "beparams"                  [t| ClusterBeParams  |]
692
  , simpleField "osparams"                  [t| ClusterOsParams  |]
693
  , simpleField "nicparams"                 [t| ClusterNicParams |]
694
  , simpleField "ndparams"                  [t| FilledNDParams   |]
695
  , simpleField "diskparams"                [t| DiskParams       |]
696
  , simpleField "candidate_pool_size"       [t| Int              |]
697
  , simpleField "modify_etc_hosts"          [t| Bool             |]
698
  , simpleField "modify_ssh_setup"          [t| Bool             |]
699
  , simpleField "maintain_node_health"      [t| Bool             |]
700
  , simpleField "uid_pool"                  [t| UidPool          |]
701
  , simpleField "default_iallocator"        [t| String           |]
702
  , simpleField "default_iallocator_params" [t| IAllocatorParams |]
703
  , simpleField "hidden_os"                 [t| [String]         |]
704
  , simpleField "blacklisted_os"            [t| [String]         |]
705
  , simpleField "primary_ip_family"         [t| IpFamily         |]
706
  , simpleField "prealloc_wipe_disks"       [t| Bool             |]
707
  , simpleField "ipolicy"                   [t| FilledIPolicy    |]
708
  , simpleField "enabled_disk_templates"    [t| [DiskTemplate]   |]
709
  , simpleField "candidate_certs"           [t| CandidateCertificates |]
710
  , simpleField "max_running_jobs"          [t| Int              |]
682
    simpleField "drbd_usermode_helper"      [t| String                 |]
683
  , simpleField "master_node"               [t| String                 |]
684
  , simpleField "master_ip"                 [t| String                 |]
685
  , simpleField "master_netdev"             [t| String                 |]
686
  , simpleField "master_netmask"            [t| Int                    |]
687
  , simpleField "use_external_mip_script"   [t| Bool                   |]
688
  , simpleField "cluster_name"              [t| String                 |]
689
  , simpleField "file_storage_dir"          [t| String                 |]
690
  , simpleField "shared_file_storage_dir"   [t| String                 |]
691
  , simpleField "gluster_storage_dir"       [t| String                 |]
692
  , simpleField "enabled_hypervisors"       [t| [Hypervisor]           |]
693
  , simpleField "hvparams"                  [t| ClusterHvParams        |]
694
  , simpleField "os_hvp"                    [t| OsHvParams             |]
695
  , simpleField "beparams"                  [t| ClusterBeParams        |]
696
  , simpleField "osparams"                  [t| ClusterOsParams        |]
697
  , simpleField "osparams_private_cluster"  [t| ClusterOsParamsPrivate |]
698
  , simpleField "nicparams"                 [t| ClusterNicParams       |]
699
  , simpleField "ndparams"                  [t| FilledNDParams         |]
700
  , simpleField "diskparams"                [t| DiskParams             |]
701
  , simpleField "candidate_pool_size"       [t| Int                    |]
702
  , simpleField "modify_etc_hosts"          [t| Bool                   |]
703
  , simpleField "modify_ssh_setup"          [t| Bool                   |]
704
  , simpleField "maintain_node_health"      [t| Bool                   |]
705
  , simpleField "uid_pool"                  [t| UidPool                |]
706
  , simpleField "default_iallocator"        [t| String                 |]
707
  , simpleField "default_iallocator_params" [t| IAllocatorParams       |]
708
  , simpleField "hidden_os"                 [t| [String]               |]
709
  , simpleField "blacklisted_os"            [t| [String]               |]
710
  , simpleField "primary_ip_family"         [t| IpFamily               |]
711
  , simpleField "prealloc_wipe_disks"       [t| Bool                   |]
712
  , simpleField "ipolicy"                   [t| FilledIPolicy          |]
713
  , simpleField "enabled_disk_templates"    [t| [DiskTemplate]         |]
714
  , simpleField "candidate_certs"           [t| CandidateCertificates  |]
715
  , simpleField "max_running_jobs"          [t| Int                    |]
711 716
 ]
712 717
 ++ timeStampFields
713 718
 ++ uuidFields
b/test/data/instance-prim-sec.txt
72 72
   ],
73 73
   "os": "busybox",
74 74
   "osparams": {},
75
   "osparams_private": {},
75 76
   "primary_node": "60e687a0-21fc-4577-997f-ccd08925fa65",
76 77
   "serial_no": 2,
77 78
   "uuid": "aec390cb-5eae-44e6-bcc2-ec14d31347f0"
b/test/hs/Test/Ganeti/Objects.hs
123 123
      <*> arbitrary
124 124
      -- osparams
125 125
      <*> pure (GenericContainer Map.empty)
126
      -- osparams_private
127
      <*> pure (GenericContainer Map.empty)
126 128
      -- admin_state
127 129
      <*> arbitrary
128 130
      -- nics
b/test/hs/Test/Ganeti/Query/Instance.hs
52 52
  Instance name pnodeUuid "" Kvm
53 53
    (GenericContainer Map.empty)
54 54
    (PartialBeParams Nothing Nothing Nothing Nothing Nothing Nothing)
55
    (GenericContainer Map.empty)
55
    (GenericContainer Map.empty) (GenericContainer Map.empty)
56 56
    adminState [] [] DTDrbd8 False Nothing epochTime epochTime "" 0 Set.empty
57 57
  where epochTime = TOD 0 0
58 58

  
b/test/py/cmdlib/testsupport/config_mock.py
181 181
                     hvparams=None,
182 182
                     beparams=None,
183 183
                     osparams=None,
184
                     osparams_private=None,
184 185
                     admin_state=None,
185 186
                     nics=None,
186 187
                     disks=None,
......
217 218
      beparams = {}
218 219
    if osparams is None:
219 220
      osparams = {}
221
    if osparams_private is None:
222
      osparams_private = {}
220 223
    if admin_state is None:
221 224
      admin_state = constants.ADMINST_DOWN
222 225
    if nics is None:
......
247 250
                            hvparams=hvparams,
248 251
                            beparams=beparams,
249 252
                            osparams=osparams,
253
                            osparams_private=osparams_private,
250 254
                            admin_state=admin_state,
251 255
                            nics=nics,
252 256
                            disks=disks,
......
571 575
      os_hvp={self.GetDefaultOs().name: constants.HVC_DEFAULTS.copy()},
572 576
      beparams=None,
573 577
      osparams=None,
578
      osparams_private_cluster=None,
574 579
      nicparams={constants.PP_DEFAULT: constants.NICC_DEFAULTS},
575 580
      ndparams=None,
576 581
      diskparams=None,
b/test/py/ganeti.config_unittest.py
35 35
from ganeti import utils
36 36
from ganeti import netutils
37 37
from ganeti import compat
38
from ganeti import serializer
38 39
from ganeti.cmdlib import instance
39 40

  
40 41
from ganeti.config import TemporaryReservationManager
......
109 110
                            uuid="test-uuid",
110 111
                            disks=[], nics=[],
111 112
                            disk_template=constants.DT_DISKLESS,
112
                            primary_node=self._get_object().GetMasterNode())
113
                            primary_node=self._get_object().GetMasterNode(),
114
                            osparams_private=serializer.PrivateDict())
113 115
    return inst
114 116

  
115 117
  def testEmpty(self):
b/test/py/ganeti.ovf_unittest.py
173 173
  "os": "lenny-image",
174 174
  "hypervisor": ("xen-pvm", {}),
175 175
  "osparams":{},
176
  "osparams_private":{},
176 177
  "disks": [],
177 178
})
178 179
ARGS_COMPLETE = dict(ARGS_VBOX, **{
......
188 189
  "name": "test-instance",
189 190
  "os": "lenny-image",
190 191
  "osparams": {},
192
  "osparams_private":{},
191 193
})
192 194

  
193 195
EXP_ARGS_COMPRESSED = dict(ARGS_EXPORT_DIR, **{

Also available in: Unified diff