1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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
62 """Local class for reporting errors.
63
64 """
65
66
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
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
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
106
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
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
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:
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