]>
Commit | Line | Data |
---|---|---|
47a4cb89 | 1 | #!/usr/bin/python |
b792d887 MT |
2 | ############################################################################### |
3 | # # | |
4 | # Pakfire - The IPFire package management system # | |
5 | # Copyright (C) 2011 Pakfire development team # | |
6 | # # | |
7 | # This program is free software: you can redistribute it and/or modify # | |
8 | # it under the terms of the GNU General Public License as published by # | |
9 | # the Free Software Foundation, either version 3 of the License, or # | |
10 | # (at your option) any later version. # | |
11 | # # | |
12 | # This program is distributed in the hope that it will be useful, # | |
13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # | |
14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # | |
15 | # GNU General Public License for more details. # | |
16 | # # | |
17 | # You should have received a copy of the GNU General Public License # | |
18 | # along with this program. If not, see <http://www.gnu.org/licenses/>. # | |
19 | # # | |
20 | ############################################################################### | |
47a4cb89 | 21 | |
a6bd96bc | 22 | import io |
47a4cb89 | 23 | import os |
c62d93f1 | 24 | import socket |
47a4cb89 MT |
25 | |
26 | from ConfigParser import ConfigParser | |
27 | ||
3eca2587 MT |
28 | import logging |
29 | log = logging.getLogger("pakfire") | |
30 | ||
a6bd96bc | 31 | import logger |
c62d93f1 | 32 | from system import system |
47a4cb89 MT |
33 | |
34 | from constants import * | |
c62d93f1 | 35 | from i18n import _ |
47a4cb89 | 36 | |
a6bd96bc MT |
37 | class _Config(object): |
38 | files = [] | |
47a4cb89 | 39 | |
a6bd96bc MT |
40 | global_default_settings = { |
41 | "logger" : { | |
42 | "file" : "/var/log/pakfire.log", | |
43 | "level" : "normal", | |
44 | "mode" : "rotate", | |
45 | "rotation_threshold" : 10485760, | |
46 | }, | |
81bb7698 MT |
47 | |
48 | "signatures" : { | |
49 | "mode" : "strict", | |
50 | }, | |
a6bd96bc | 51 | } |
47a4cb89 | 52 | |
a6bd96bc MT |
53 | # A dict with default settings for this config class. |
54 | default_settings = {} | |
47a4cb89 | 55 | |
a6bd96bc MT |
56 | def __init__(self, files=None): |
57 | # Configuration settings. | |
58 | self._config = self.global_default_settings.copy() | |
59 | self._config.update(self.default_settings) | |
47a4cb89 | 60 | |
a6bd96bc MT |
61 | # List of files that were already loaded. |
62 | self._files = [] | |
47a4cb89 | 63 | |
a6bd96bc MT |
64 | # If no files were given, load the default files. |
65 | if files is None: | |
66 | # Read default configuration file. | |
67 | self.read(*self.files) | |
47a4cb89 | 68 | |
a6bd96bc MT |
69 | repo_path = self.get(None, "repo_path", CONFIG_REPOS_DIR) |
70 | if repo_path: | |
71 | self.read_dir(repo_path, ext=".repo") | |
6a509182 | 72 | |
854d8ccf MT |
73 | # Always read overwrite.conf. |
74 | # This is a undocumented feature to make bootstrapping easier. | |
75 | self.read("overwrite.conf") | |
76 | ||
47a4cb89 | 77 | def get_repos(self): |
a6bd96bc | 78 | repos = [] |
47a4cb89 | 79 | |
a6bd96bc MT |
80 | for name, settings in self._config.items(): |
81 | if not name.startswith("repo:"): | |
82 | continue | |
c62d93f1 | 83 | |
a6bd96bc MT |
84 | # Strip "repo:" from name of the repository. |
85 | name = name[5:] | |
c62d93f1 | 86 | |
a6bd96bc | 87 | repos.append((name, settings)) |
c62d93f1 | 88 | |
a6bd96bc | 89 | return repos |
c62d93f1 | 90 | |
a6bd96bc MT |
91 | def read_dir(self, where, ext=".conf"): |
92 | for file in os.listdir(where): | |
93 | if not file.endswith(ext): | |
94 | continue | |
c62d93f1 | 95 | |
a6bd96bc MT |
96 | file = os.path.join(where, file) |
97 | self.read(file) | |
c62d93f1 MT |
98 | |
99 | def read(self, *files): | |
100 | # Do nothing for no files. | |
101 | if not files: | |
102 | return | |
103 | ||
a6bd96bc MT |
104 | for file in files: |
105 | if not file.startswith("/"): | |
106 | file = os.path.join(CONFIG_DIR, file) | |
107 | ||
108 | if not os.path.exists(file): | |
109 | continue | |
110 | ||
c62d93f1 | 111 | # Normalize filename. |
a6bd96bc | 112 | file = os.path.abspath(file) |
c62d93f1 MT |
113 | |
114 | # Check if file has already been read or | |
115 | # does not exist. Then skip it. | |
a6bd96bc | 116 | if file in self._files or not os.path.exists(file): |
c62d93f1 MT |
117 | continue |
118 | ||
119 | # Parse the file. | |
a6bd96bc MT |
120 | with open(file) as f: |
121 | self.parse(f.read()) | |
c62d93f1 MT |
122 | |
123 | # Save the filename to the list of read files. | |
a6bd96bc MT |
124 | self._files.append(file) |
125 | ||
126 | def parse(self, s): | |
127 | if not s: | |
128 | return | |
129 | ||
73c2707c | 130 | s = str(s) |
a6bd96bc MT |
131 | buf = io.BytesIO(s) |
132 | ||
133 | config = ConfigParser() | |
134 | config.readfp(buf) | |
c62d93f1 MT |
135 | |
136 | # Read all data from the configuration file in the _config dict. | |
137 | for section in config.sections(): | |
138 | items = dict(config.items(section)) | |
139 | ||
a6bd96bc MT |
140 | if section == "DEFAULT": |
141 | section = "main" | |
142 | ||
c62d93f1 MT |
143 | try: |
144 | self._config[section].update(items) | |
145 | except KeyError: | |
146 | self._config[section] = items | |
147 | ||
a6bd96bc MT |
148 | # Update the logger, because the logging configuration may |
149 | # have been altered. | |
150 | logger.setup_logging(self) | |
151 | ||
c62d93f1 MT |
152 | def set(self, section, key, value): |
153 | try: | |
154 | self._config[section][key] = value | |
155 | except KeyError: | |
156 | self._config[section] = { key : value } | |
157 | ||
a6bd96bc MT |
158 | def get_section(self, section): |
159 | try: | |
160 | return self._config[section] | |
161 | except KeyError: | |
162 | return {} | |
163 | ||
c62d93f1 | 164 | def get(self, section, key, default=None): |
a6bd96bc MT |
165 | s = self.get_section(section) |
166 | ||
c62d93f1 | 167 | try: |
a6bd96bc | 168 | return s[key] |
c62d93f1 MT |
169 | except KeyError: |
170 | return default | |
171 | ||
172 | def get_int(self, section, key, default=None): | |
173 | val = self.get(section=section, key=key, default=default) | |
174 | try: | |
175 | val = int(val) | |
176 | except ValueError: | |
177 | return default | |
178 | ||
179 | def get_bool(self, section, key, default=None): | |
180 | val = self.get(section=section, key=key, default=default) | |
181 | ||
182 | if val in (True, "true", "1", "on"): | |
183 | return True | |
184 | elif val in (False, "false", "0", "off"): | |
185 | return False | |
186 | ||
187 | return default | |
188 | ||
a6bd96bc | 189 | def update(self, section, what): |
98733451 | 190 | if not type(what) == type({}): |
685cb819 | 191 | log.error(_("Unhandled configuration update: %s = %s") % (section, what)) |
98733451 MT |
192 | return |
193 | ||
a6bd96bc MT |
194 | try: |
195 | self._config[section].update(what) | |
196 | except KeyError: | |
197 | self._config[section] = what | |
198 | ||
c62d93f1 MT |
199 | def dump(self): |
200 | """ | |
201 | Dump the configuration that was read. | |
202 | ||
203 | (Only in debugging mode.) | |
204 | """ | |
205 | log.debug(_("Configuration:")) | |
206 | for section, settings in self._config.items(): | |
207 | log.debug(" " + _("Section: %s") % section) | |
208 | ||
209 | for k, v in settings.items(): | |
210 | log.debug(" %-20s: %s" % (k, v)) | |
211 | else: | |
212 | log.debug(" " + _("No settings in this section.")) | |
213 | ||
214 | log.debug(" " + _("Loaded from files:")) | |
215 | for f in self._files: | |
216 | log.debug(" %s" % f) | |
217 | ||
36b328f2 | 218 | def has_distro_conf(self): |
854d8ccf MT |
219 | return self._config.has_key("distro") |
220 | ||
36b328f2 MT |
221 | def get_distro_conf(self): |
222 | return self.get_section("distro") | |
223 | ||
c62d93f1 | 224 | |
a6bd96bc | 225 | class Config(_Config): |
b5f5688e | 226 | files = ["general.conf", "distro.conf"] |
a6bd96bc MT |
227 | |
228 | ||
c62d93f1 | 229 | class ConfigBuilder(_Config): |
854d8ccf MT |
230 | files = ["general.conf", "builder.conf"] |
231 | ||
232 | def load_distro_config(self, distro_name): | |
233 | if distro_name is None: | |
234 | return False | |
235 | ||
236 | filename = os.path.join(CONFIG_DISTRO_DIR, "%s.conf" % distro_name) | |
237 | ||
238 | if not os.path.exists(filename): | |
239 | return False | |
240 | ||
241 | self.read(filename) | |
242 | return True | |
c62d93f1 MT |
243 | |
244 | ||
245 | class ConfigClient(_Config): | |
a6bd96bc | 246 | files = ["general.conf", "client.conf"] |
c62d93f1 MT |
247 | |
248 | default_settings = { | |
249 | "client" : { | |
250 | # The default server is the official Pakfire | |
251 | # server. | |
0f882359 | 252 | "server" : PAKFIRE_HUB, |
c62d93f1 MT |
253 | }, |
254 | } | |
255 | ||
aa14071d MT |
256 | def get_hub_credentials(self): |
257 | hub_url = self.get("client", "server") | |
258 | username = self.get("client", "username") | |
259 | password = self.get("client", "password") | |
260 | ||
261 | return hub_url, username, password | |
262 | ||
c62d93f1 MT |
263 | |
264 | class ConfigDaemon(_Config): | |
a6bd96bc | 265 | files = ["general.conf", "daemon.conf"] |
c62d93f1 MT |
266 | |
267 | default_settings = { | |
268 | "daemon" : { | |
269 | # The default server is the official Pakfire | |
270 | # server. | |
0f882359 | 271 | "server" : PAKFIRE_HUB, |
c62d93f1 MT |
272 | |
273 | # The default hostname is the host name of this | |
274 | # machine. | |
275 | "hostname" : system.hostname, | |
276 | }, | |
277 | } | |
aa14071d MT |
278 | |
279 | def get_hub_credentials(self): | |
280 | hub_url = self.get("daemon", "server") | |
281 | hostname = self.get("daemon", "hostname") | |
282 | password = self.get("daemon", "secret") | |
283 | ||
284 | return hub_url, hostname, password |