Package ganeti :: Package tools :: Module node_daemon_setup
[hide private]
[frames] | no frames]

Source Code for Module ganeti.tools.node_daemon_setup

  1  # 
  2  # 
  3   
  4  # Copyright (C) 2012 Google Inc. 
  5  # All rights reserved. 
  6  # 
  7  # Redistribution and use in source and binary forms, with or without 
  8  # modification, are permitted provided that the following conditions are 
  9  # met: 
 10  # 
 11  # 1. Redistributions of source code must retain the above copyright notice, 
 12  # this list of conditions and the following disclaimer. 
 13  # 
 14  # 2. Redistributions in binary form must reproduce the above copyright 
 15  # notice, this list of conditions and the following disclaimer in the 
 16  # documentation and/or other materials provided with the distribution. 
 17  # 
 18  # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 
 19  # IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 
 20  # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
 21  # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
 22  # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
 23  # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
 24  # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
 25  # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
 26  # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
 27  # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
 28  # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 29   
 30  """Script to configure the node daemon. 
 31   
 32  """ 
 33   
 34  import os 
 35  import os.path 
 36  import optparse 
 37  import sys 
 38  import logging 
 39   
 40  from ganeti import cli 
 41  from ganeti import constants 
 42  from ganeti import errors 
 43  from ganeti import pathutils 
 44  from ganeti import utils 
 45  from ganeti import runtime 
 46  from ganeti import ht 
 47  from ganeti import ssconf 
 48  from ganeti.tools import common 
 49   
 50   
 51  _DATA_CHECK = ht.TStrictDict(False, True, { 
 52    constants.NDS_CLUSTER_NAME: ht.TNonEmptyString, 
 53    constants.NDS_NODE_DAEMON_CERTIFICATE: ht.TNonEmptyString, 
 54    constants.NDS_HMAC: ht.TNonEmptyString, 
 55    constants.NDS_SSCONF: ht.TDictOf(ht.TNonEmptyString, ht.TString), 
 56    constants.NDS_START_NODE_DAEMON: ht.TBool, 
 57    constants.NDS_NODE_NAME: ht.TString, 
 58    }) 
 59   
 60   
61 -class SetupError(errors.GenericError):
62 """Local class for reporting errors. 63 64 """
65 66
67 -def ParseOptions():
68 """Parses the options passed to the program. 69 70 @return: Options and arguments 71 72 """ 73 parser = optparse.OptionParser(usage="%prog [--dry-run]", 74 prog=os.path.basename(sys.argv[0])) 75 parser.add_option(cli.DEBUG_OPT) 76 parser.add_option(cli.VERBOSE_OPT) 77 parser.add_option(cli.DRY_RUN_OPT) 78 79 (opts, args) = parser.parse_args() 80 81 return VerifyOptions(parser, opts, args)
82 83
84 -def VerifyOptions(parser, opts, args):
85 """Verifies options and arguments for correctness. 86 87 """ 88 if args: 89 parser.error("No arguments are expected") 90 91 return opts
92 93
94 -def VerifySsconf(data, cluster_name, _verify_fn=ssconf.VerifyKeys):
95 """Verifies ssconf names. 96 97 @type data: dict 98 99 """ 100 items = data.get(constants.NDS_SSCONF) 101 102 if not items: 103 raise SetupError("Ssconf values must be specified") 104 105 # TODO: Should all keys be required? Right now any subset of valid keys is 106 # accepted. 107 _verify_fn(items.keys()) 108 109 if items.get(constants.SS_CLUSTER_NAME) != cluster_name: 110 raise SetupError("Cluster name in ssconf does not match") 111 112 return items
113 114
115 -def Main():
116 """Main routine. 117 118 """ 119 opts = ParseOptions() 120 121 utils.SetupToolLogging( 122 opts.debug, opts.verbose, 123 toolname=os.path.splitext(os.path.basename(__file__))[0]) 124 125 try: 126 getent = runtime.GetEnts() 127 128 data = common.LoadData(sys.stdin.read(), SetupError) 129 130 cluster_name = common.VerifyClusterName(data, SetupError, 131 constants.NDS_CLUSTER_NAME) 132 cert_pem = common.VerifyCertificateStrong(data, SetupError) 133 hmac_key = common.VerifyHmac(data, SetupError) 134 ssdata = VerifySsconf(data, cluster_name) 135 136 logging.info("Writing ssconf files ...") 137 ssconf.WriteSsconfFiles(ssdata, dry_run=opts.dry_run) 138 139 logging.info("Writing hmac.key ...") 140 utils.WriteFile(pathutils.CONFD_HMAC_KEY, data=hmac_key, 141 mode=pathutils.NODED_CERT_MODE, 142 uid=getent.masterd_uid, gid=getent.masterd_gid, 143 dry_run=opts.dry_run) 144 145 logging.info("Writing node daemon certificate ...") 146 utils.WriteFile(pathutils.NODED_CERT_FILE, data=cert_pem, 147 mode=pathutils.NODED_CERT_MODE, 148 uid=getent.masterd_uid, gid=getent.masterd_gid, 149 dry_run=opts.dry_run) 150 common.GenerateClientCertificate(data, SetupError) 151 152 if (data.get(constants.NDS_START_NODE_DAEMON) and # pylint: disable=E1103 153 not opts.dry_run): 154 logging.info("Restarting node daemon ...") 155 156 stop_cmd = "%s stop-all" % pathutils.DAEMON_UTIL 157 noded_cmd = "%s start %s" % (pathutils.DAEMON_UTIL, constants.NODED) 158 mond_cmd = "" 159 if constants.ENABLE_MOND: 160 mond_cmd = "%s start %s" % (pathutils.DAEMON_UTIL, constants.MOND) 161 162 cmd = "; ".join([stop_cmd, noded_cmd, mond_cmd]) 163 164 result = utils.RunCmd(cmd, interactive=True) 165 if result.failed: 166 raise SetupError("Could not start the node daemons, command '%s'" 167 " failed: %s" % (result.cmd, result.fail_reason)) 168 169 logging.info("Node daemon successfully configured") 170 except Exception, err: # pylint: disable=W0703 171 logging.debug("Caught unhandled exception", exc_info=True) 172 173 (retcode, message) = cli.FormatError(err) 174 logging.error(message) 175 176 return retcode 177 else: 178 return constants.EXIT_SUCCESS
179