Revision 6bce7ba2

b/lib/backend.py
3266 3266
  for name, value in instance.osparams.items():
3267 3267
    config.set(constants.INISECT_OSP, name, str(value))
3268 3268

  
3269
  config.add_section(constants.INISECT_OSP_PRIVATE)
3270
  for name, value in instance.osparams_private.items():
3271
    config.set(constants.INISECT_OSP_PRIVATE, name, str(value.Get()))
3272

  
3269 3273
  utils.WriteFile(utils.PathJoin(destdir, constants.EXPORT_CONF_FILE),
3270 3274
                  data=config.Dumps())
3271 3275
  shutil.rmtree(finaldestdir, ignore_errors=True)
b/lib/cli.py
2794 2794
                                hvparams=hvparams,
2795 2795
                                beparams=opts.beparams,
2796 2796
                                osparams=opts.osparams,
2797
                                osparams_private=opts.osparams_private,
2798
                                osparams_secret=opts.osparams_secret,
2797 2799
                                mode=mode,
2798 2800
                                start=start,
2799 2801
                                os_type=os_type,
b/lib/client/gnt_instance.py
1485 1485

  
1486 1486
commands = {
1487 1487
  "add": (
1488
    AddInstance, [ArgHost(min=1, max=1)], COMMON_CREATE_OPTS + add_opts,
1488
    AddInstance, [ArgHost(min=1, max=1)],
1489
    COMMON_CREATE_OPTS + add_opts + [OSPARAMS_PRIVATE_OPT, OSPARAMS_SECRET_OPT],
1489 1490
    "[...] -t disk-type -n node[:secondary-node] -o os-type <name>",
1490 1491
    "Creates and adds a new instance to the cluster"),
1491 1492
  "batch-create": (
......
1548 1549
     m_pri_node_opt, m_sec_node_opt, m_clust_opt, m_inst_opt, m_node_tags_opt,
1549 1550
     m_pri_node_tags_opt, m_sec_node_tags_opt, m_inst_tags_opt, SELECT_OS_OPT]
1550 1551
    + SUBMIT_OPTS + [DRY_RUN_OPT, PRIORITY_OPT, OSPARAMS_OPT,
1551
                     OSPARAMS_NOLOG_OPT, OSPARAMS_NOLOG_NOSAVE_OPT],
1552
                     OSPARAMS_PRIVATE_OPT, OSPARAMS_SECRET_OPT],
1552 1553
    "[-f] <instance>", "Reinstall a stopped instance"),
1553 1554
  "remove": (
1554 1555
    RemoveInstance, ARGS_ONE_INSTANCE,
......
1572 1573
    SetInstanceParams, ARGS_ONE_INSTANCE,
1573 1574
    [BACKEND_OPT, DISK_OPT, FORCE_OPT, HVOPTS_OPT, NET_OPT] + SUBMIT_OPTS +
1574 1575
    [DISK_TEMPLATE_OPT, SINGLE_NODE_OPT, OS_OPT, FORCE_VARIANT_OPT,
1575
     OSPARAMS_OPT, OSPARAMS_NOLOG_OPT, DRY_RUN_OPT, PRIORITY_OPT, NWSYNC_OPT,
1576
     OSPARAMS_OPT, OSPARAMS_PRIVATE_OPT, DRY_RUN_OPT, PRIORITY_OPT, NWSYNC_OPT,
1576 1577
     OFFLINE_INST_OPT, ONLINE_INST_OPT, IGNORE_IPOLICY_OPT, RUNTIME_MEM_OPT,
1577 1578
     NOCONFLICTSCHECK_OPT, NEW_PRIMARY_OPT, HOTPLUG_OPT,
1578 1579
     HOTPLUG_IF_POSSIBLE_OPT],
b/lib/cmdlib/instance.py
37 37
from ganeti import netutils
38 38
from ganeti import objects
39 39
from ganeti import pathutils
40
from ganeti import serializer
40 41
import ganeti.rpc.node as rpc
41 42
from ganeti import utils
42 43

  
......
847 848
        if name not in self.op.osparams:
848 849
          self.op.osparams[name] = value
849 850

  
851
    if einfo.has_section(constants.INISECT_OSP_PRIVATE):
852
      # use the parameters, without overriding
853
      for name, value in einfo.items(constants.INISECT_OSP_PRIVATE):
854
        if name not in self.op.osparams_private:
855
          self.op.osparams_private[name] = serializer.Private(value, descr=name)
856

  
850 857
  def _RevertToDefaults(self, cluster):
851 858
    """Revert the instance parameters to the default values.
852 859

  
......
873 880
      if name in os_defs and os_defs[name] == self.op.osparams[name]:
874 881
        del self.op.osparams[name]
875 882

  
883
    os_defs_ = cluster.SimpleFillOS(self.op.os_type, {},
884
                                    os_params_private={})
885
    for name in self.op.osparams_private.keys():
886
      if name in os_defs_ and os_defs_[name] == self.op.osparams_private[name]:
887
        del self.op.osparams_private[name]
888

  
876 889
  def _CalculateFileStorageDir(self):
877 890
    """Calculate final instance file storage dir.
878 891

  
......
977 990
    self.be_full = _ComputeFullBeParams(self.op, cluster)
978 991

  
979 992
    # build os parameters
980
    self.os_full = cluster.SimpleFillOS(self.op.os_type, self.op.osparams)
993
    if self.op.osparams_private is None:
994
      self.op.osparams_private = serializer.PrivateDict()
995
    if self.op.osparams_secret is None:
996
      self.op.osparams_secret = serializer.PrivateDict()
997

  
998
    self.os_full = cluster.SimpleFillOS(
999
      self.op.os_type,
1000
      self.op.osparams,
1001
      os_params_private=self.op.osparams_private,
1002
      os_params_secret=self.op.osparams_secret
1003
    )
981 1004

  
982 1005
    # now that hvp/bep are in final format, let's reset to defaults,
983 1006
    # if told to do so
......
1332 1355
                            hvparams=self.op.hvparams,
1333 1356
                            hypervisor=self.op.hypervisor,
1334 1357
                            osparams=self.op.osparams,
1358
                            osparams_private=self.op.osparams_private,
1335 1359
                            )
1336 1360

  
1337 1361
    if self.op.tags:
......
1428 1452
          feedback_fn("* running the instance OS create scripts...")
1429 1453
          # FIXME: pass debug option from opcode to backend
1430 1454
          os_add_result = \
1431
            self.rpc.call_instance_os_add(self.pnode.uuid, (iobj, None), False,
1455
            self.rpc.call_instance_os_add(self.pnode.uuid,
1456
                                          (iobj, self.op.osparams_secret),
1457
                                          False,
1432 1458
                                          self.op.debug_level)
1433 1459
          if pause_sync:
1434 1460
            feedback_fn("* resuming disk sync")
......
3008 3034
                                hvspecs)
3009 3035

  
3010 3036
    # osparams processing
3011
    if self.op.osparams or self.op.osparams_private_cluster:
3037
    if self.op.osparams or self.op.osparams_private:
3012 3038
      public_parms = self.op.osparams or {}
3013
      private_parms = self.op.osparams_private_cluster or {}
3039
      private_parms = self.op.osparams_private or {}
3014 3040
      dupe_keys = utils.GetRepeatedKeys(public_parms, private_parms)
3015 3041

  
3016 3042
      if dupe_keys:
b/man/gnt-instance.rst
37 37
| [{-B|\--backend-parameters} *BEPARAMS*]
38 38
| [{-H|\--hypervisor-parameters} *HYPERVISOR* [: option=*value*... ]]
39 39
| [{-O|\--os-parameters} *param*=*value*... ]
40
| [--os-parameters-private *param*=*value*... ]
41
| [--os-parameters-secret *param*=*value*... ]
40 42
| [\--file-storage-dir *dir\_path*] [\--file-driver {loop \| blktap \| blktap2}]
41 43
| {{-n|\--node} *node[:secondary-node]* \| {-I|\--iallocator} *name*}
42 44
| {{-o|\--os-type} *os-type*}
......
827 829

  
828 830
    gnt-instance add -O dhcp=yes ...
829 831

  
832
You can also specify OS parameters that should not be logged but reused
833
at the next reinstall with ``--os-parameters-private`` and OS parameters
834
that should not be logged or saved to configuration with
835
``--os-parameters-secret``. Bear in mind that:
836

  
837
  * Launching the daemons in debug mode will cause debug logging to
838
    happen, which leaks private and secret parameters to the log files.
839
    Do not use the debug mode in production. Deamons will emit a warning
840
    on startup if they are in debug mode.
841
  * You will have to pass again all ``--os-parameters-secret`` parameters
842
    should you want to reinstall this instance.
843

  
830 844
The ``-I (--iallocator)`` option specifies the instance allocator plugin
831 845
to use (``.`` means the default allocator). If you pass in this option
832 846
the allocator will select nodes for this instance automatically, so you
b/src/Ganeti/Constants.hs
1104 1104
inisectOsp :: String
1105 1105
inisectOsp = "os"
1106 1106

  
1107
inisectOspPrivate :: String
1108
inisectOspPrivate = "os_private"
1109

  
1107 1110
-- * Dynamic device modification
1108 1111

  
1109 1112
ddmAdd :: String
b/src/Ganeti/OpCodes.hs
438 438
     , pInstNics
439 439
     , pNoInstall
440 440
     , pInstOsParams
441
     , pInstOsParamsPrivate
442
     , pInstOsParamsSecret
441 443
     , pInstOs
442 444
     , pPrimaryNode
443 445
     , pPrimaryNodeUuid
b/src/Ganeti/OpParams.hs
120 120
  , pClusterOsParams
121 121
  , pClusterOsParamsPrivate
122 122
  , pInstOsParams
123
  , pInstOsParamsPrivate
124
  , pInstOsParamsSecret
123 125
  , pCandidatePoolSize
124 126
  , pMaxRunningJobs
125 127
  , pUidPool
......
1098 1100
  defaultField [| toJSObject [] |] $
1099 1101
  simpleField "osparams" [t| JSObject JSValue |]
1100 1102

  
1103
pInstOsParamsPrivate :: Field
1104
pInstOsParamsPrivate =
1105
  withDoc "Private OS parameters for instance" .
1106
  optionalField $
1107
  simpleField "osparams_private" [t| JSObject (Private JSValue) |]
1108

  
1109
pInstOsParamsSecret :: Field
1110
pInstOsParamsSecret =
1111
  withDoc "Secret OS parameters for instance" .
1112
  optionalField $
1113
  simpleField "osparams_secret" [t| JSObject (Private JSValue) |]
1114

  
1101 1115
pPrimaryNode :: Field
1102 1116
pPrimaryNode =
1103 1117
  withDoc "Primary node for an instance" $
b/test/hs/Test/Ganeti/OpCodes.hs
255 255
          return Nothing <*> genMaybe genNodeNameNE <*> return Nothing <*>
256 256
          genMaybe genNameNE <*> arbitrary
257 257
      "OP_INSTANCE_CREATE" ->
258
        OpCodes.OpInstanceCreate <$> genFQDN <*> arbitrary <*>
259
          arbitrary <*> arbitrary <*> arbitrary <*> arbitrary <*>
260
          pure emptyJSObject <*> arbitrary <*> arbitrary <*> arbitrary <*>
261
          genMaybe genNameNE <*> pure emptyJSObject <*> arbitrary <*>
262
          genMaybe genNameNE <*> arbitrary <*> arbitrary <*> arbitrary <*>
263
          arbitrary <*> arbitrary <*> arbitrary <*> pure emptyJSObject <*>
264
          genMaybe genNameNE <*> genMaybe genNodeNameNE <*> return Nothing <*>
265
          genMaybe genNodeNameNE <*> return Nothing <*> genMaybe (pure []) <*>
266
          genMaybe genNodeNameNE <*> arbitrary <*> genMaybe genNodeNameNE <*>
267
          return Nothing <*> genMaybe genNodeNameNE <*> genMaybe genNameNE <*>
268
          arbitrary <*> arbitrary <*> (genTags >>= mapM mkNonEmpty) <*>
269
          arbitrary
258
        OpCodes.OpInstanceCreate
259
          <$> genFQDN                         -- instance_name
260
          <*> arbitrary                       -- force_variant
261
          <*> arbitrary                       -- wait_for_sync
262
          <*> arbitrary                       -- name_check
263
          <*> arbitrary                       -- ignore_ipolicy
264
          <*> arbitrary                       -- opportunistic_locking
265
          <*> pure emptyJSObject              -- beparams
266
          <*> arbitrary                       -- disks
267
          <*> arbitrary                       -- disk_template
268
          <*> arbitrary                       -- file_driver
269
          <*> genMaybe genNameNE              -- file_storage_dir
270
          <*> pure emptyJSObject              -- hvparams
271
          <*> arbitrary                       -- hypervisor
272
          <*> genMaybe genNameNE              -- iallocator
273
          <*> arbitrary                       -- identify_defaults
274
          <*> arbitrary                       -- ip_check
275
          <*> arbitrary                       -- conflicts_check
276
          <*> arbitrary                       -- mode
277
          <*> arbitrary                       -- nics
278
          <*> arbitrary                       -- no_install
279
          <*> pure emptyJSObject              -- osparams
280
          <*> genMaybe arbitraryPrivateJSObj  -- osparams_private
281
          <*> genMaybe arbitraryPrivateJSObj  -- osparams_secret
282
          <*> genMaybe genNameNE              -- os_type
283
          <*> genMaybe genNodeNameNE          -- pnode
284
          <*> return Nothing                  -- pnode_uuid
285
          <*> genMaybe genNodeNameNE          -- snode
286
          <*> return Nothing                  -- snode_uuid
287
          <*> genMaybe (pure [])              -- source_handshake
288
          <*> genMaybe genNodeNameNE          -- source_instance_name
289
          <*> arbitrary                       -- source_shutdown_timeout
290
          <*> genMaybe genNodeNameNE          -- source_x509_ca
291
          <*> return Nothing                  -- src_node
292
          <*> genMaybe genNodeNameNE          -- src_node_uuid
293
          <*> genMaybe genNameNE              -- src_path
294
          <*> arbitrary                       -- compress
295
          <*> arbitrary                       -- start
296
          <*> (genTags >>= mapM mkNonEmpty)   -- tags
297
          <*> arbitrary                       -- instance_communication
270 298
      "OP_INSTANCE_MULTI_ALLOC" ->
271 299
        OpCodes.OpInstanceMultiAlloc <$> arbitrary <*> genMaybe genNameNE <*>
272 300
        pure []
b/test/py/cmdlib/instance_unittest.py
465 465
                         osparams={
466 466
                           self.os_name_variant: {}
467 467
                         },
468
                         osparams_private={},
468 469
                         identify_defaults=True)
469 470
    self.ExecOpCode(op)
470 471

  

Also available in: Unified diff