RAPI: Export beparams as dict. The patch also enables LUQueryInstances to accept...
[ganeti-local] / lib / ssconf.py
1 #
2 #
3
4 # Copyright (C) 2006, 2007, 2008 Google Inc.
5 #
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2 of the License, or
9 # (at your option) any later version.
10 #
11 # This program is distributed in the hope that it will be useful, but
12 # WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 # General Public License for more details.
15 #
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 # 02110-1301, USA.
20
21
22 """Global Configuration data for Ganeti.
23
24 This module provides the interface to a special case of cluster
25 configuration data, which is mostly static and available to all nodes.
26
27 """
28
29 import socket
30 import sys
31
32 from ganeti import errors
33 from ganeti import constants
34 from ganeti import utils
35 from ganeti import serializer
36
37
38 class SimpleConfigReader(object):
39   """Simple class to read configuration file.
40
41   """
42   def __init__(self, file_name=constants.CLUSTER_CONF_FILE):
43     """Initializes this class.
44
45     @type file_name: string
46     @param file_name: Configuration file path
47
48     """
49     self._file_name = file_name
50     self._config_data = serializer.Load(utils.ReadFile(file_name))
51     # TODO: Error handling
52
53   def GetClusterName(self):
54     return self._config_data["cluster"]["cluster_name"]
55
56   def GetHostKey(self):
57     return self._config_data["cluster"]["rsahostkeypub"]
58
59   def GetMasterNode(self):
60     return self._config_data["cluster"]["master_node"]
61
62   def GetMasterIP(self):
63     return self._config_data["cluster"]["master_ip"]
64
65   def GetMasterNetdev(self):
66     return self._config_data["cluster"]["master_netdev"]
67
68   def GetFileStorageDir(self):
69     return self._config_data["cluster"]["file_storage_dir"]
70
71   def GetHypervisorType(self):
72     return self._config_data["cluster"]["hypervisor"]
73
74   def GetNodeList(self):
75     return self._config_data["nodes"].keys()
76
77   @classmethod
78   def FromDict(cls, val, cfg_file=constants.CLUSTER_CONF_FILE):
79     """Alternative construction from a dictionary.
80
81     """
82     obj = SimpleConfigReader.__new__(cls)
83     obj._config_data = val
84     obj._file_name = cfg_file
85     return obj
86
87
88 class SimpleConfigWriter(SimpleConfigReader):
89   """Simple class to write configuration file.
90
91   """
92   def SetMasterNode(self, node):
93     """Change master node.
94
95     """
96     self._config_data["cluster"]["master_node"] = node
97
98   def Save(self):
99     """Writes configuration file.
100
101     Warning: Doesn't take care of locking or synchronizing with other
102     processes.
103
104     """
105     utils.WriteFile(self._file_name,
106                     data=serializer.Dump(self._config_data),
107                     mode=0600)
108
109
110 def GetMasterAndMyself(ss=None):
111   """Get the master node and my own hostname.
112
113   This can be either used for a 'soft' check (compared to CheckMaster,
114   which exits) or just for computing both at the same time.
115
116   The function does not handle any errors, these should be handled in
117   the caller (errors.ConfigurationError, errors.ResolverError).
118
119   """
120   if ss is None:
121     ss = SimpleConfigReader()
122   return ss.GetMasterNode(), utils.HostInfo().name
123
124
125 def CheckMaster(debug, ss=None):
126   """Checks the node setup.
127
128   If this is the master, the function will return. Otherwise it will
129   exit with an exit code based on the node status.
130
131   """
132   try:
133     master_name, myself = GetMasterAndMyself(ss)
134   except errors.ConfigurationError, err:
135     print "Cluster configuration incomplete: '%s'" % str(err)
136     sys.exit(constants.EXIT_NODESETUP_ERROR)
137   except errors.ResolverError, err:
138     sys.stderr.write("Cannot resolve my own name (%s)\n" % err.args[0])
139     sys.exit(constants.EXIT_NODESETUP_ERROR)
140
141   if myself != master_name:
142     if debug:
143       sys.stderr.write("Not master, exiting.\n")
144     sys.exit(constants.EXIT_NOTMASTER)