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_SSCONF: ht.TDictOf(ht.TNonEmptyString, ht.TString),
55 constants.NDS_START_NODE_DAEMON: ht.TBool,
56 constants.NDS_NODE_NAME: ht.TString,
57 })
58
59
61 """Local class for reporting errors.
62
63 """
64
65
67 """Parses the options passed to the program.
68
69 @return: Options and arguments
70
71 """
72 parser = optparse.OptionParser(usage="%prog [--dry-run]",
73 prog=os.path.basename(sys.argv[0]))
74 parser.add_option(cli.DEBUG_OPT)
75 parser.add_option(cli.VERBOSE_OPT)
76 parser.add_option(cli.DRY_RUN_OPT)
77
78 (opts, args) = parser.parse_args()
79
80 return VerifyOptions(parser, opts, args)
81
82
84 """Verifies options and arguments for correctness.
85
86 """
87 if args:
88 parser.error("No arguments are expected")
89
90 return opts
91
92
94 """Verifies ssconf names.
95
96 @type data: dict
97
98 """
99 items = data.get(constants.NDS_SSCONF)
100
101 if not items:
102 raise SetupError("Ssconf values must be specified")
103
104
105
106 _verify_fn(items.keys())
107
108 if items.get(constants.SS_CLUSTER_NAME) != cluster_name:
109 raise SetupError("Cluster name in ssconf does not match")
110
111 return items
112
113
115 """Main routine.
116
117 """
118 opts = ParseOptions()
119
120 utils.SetupToolLogging(opts.debug, opts.verbose)
121
122 try:
123 getent = runtime.GetEnts()
124
125 data = common.LoadData(sys.stdin.read(), SetupError)
126
127 cluster_name = common.VerifyClusterName(data, SetupError,
128 constants.NDS_CLUSTER_NAME)
129 cert_pem = common.VerifyCertificateStrong(data, SetupError)
130 ssdata = VerifySsconf(data, cluster_name)
131
132 logging.info("Writing ssconf files ...")
133 ssconf.WriteSsconfFiles(ssdata, dry_run=opts.dry_run)
134
135 logging.info("Writing node daemon certificate ...")
136 utils.WriteFile(pathutils.NODED_CERT_FILE, data=cert_pem,
137 mode=pathutils.NODED_CERT_MODE,
138 uid=getent.masterd_uid, gid=getent.masterd_gid,
139 dry_run=opts.dry_run)
140 common.GenerateClientCertificate(data, SetupError)
141
142 if (data.get(constants.NDS_START_NODE_DAEMON) and
143 not opts.dry_run):
144 logging.info("Restarting node daemon ...")
145
146 stop_cmd = "%s stop-all" % pathutils.DAEMON_UTIL
147 noded_cmd = "%s start %s" % (pathutils.DAEMON_UTIL, constants.NODED)
148 mond_cmd = ""
149 if constants.ENABLE_MOND:
150 mond_cmd = "%s start %s" % (pathutils.DAEMON_UTIL, constants.MOND)
151
152 cmd = "; ".join([stop_cmd, noded_cmd, mond_cmd])
153
154 result = utils.RunCmd(cmd, interactive=True)
155 if result.failed:
156 raise SetupError("Could not start the node daemons, command '%s'"
157 " failed: %s" % (result.cmd, result.fail_reason))
158
159 logging.info("Node daemon successfully configured")
160 except Exception, err:
161 logging.debug("Caught unhandled exception", exc_info=True)
162
163 (retcode, message) = cli.FormatError(err)
164 logging.error(message)
165
166 return retcode
167 else:
168 return constants.EXIT_SUCCESS
169