OpenSim
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros
ConfigurationLoader.cs
Go to the documentation of this file.
1 /*
2  * Copyright (c) Contributors, http://opensimulator.org/
3  * See CONTRIBUTORS.TXT for a full list of copyright holders.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  * * Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * * Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  * * Neither the name of the OpenSimulator Project nor the
13  * names of its contributors may be used to endorse or promote products
14  * derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19  * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 using System;
29 using System.Collections.Generic;
30 using System.IO;
31 using System.Reflection;
32 using System.Threading;
33 using System.Xml;
34 using log4net;
35 using Nini.Config;
36 using OpenSim.Framework;
37 
38 namespace OpenSim
39 {
43  public class ConfigurationLoader
44  {
45  private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
46 
54 
59 
64 
73  IConfigSource argvSource, EnvConfigSource envConfigSource, out ConfigSettings configSettings,
74  out NetworkServersInfo networkInfo)
75  {
76  m_configSettings = configSettings = new ConfigSettings();
77  m_networkServersInfo = networkInfo = new NetworkServersInfo();
78 
79  bool iniFileExists = false;
80 
81  IConfig startupConfig = argvSource.Configs["Startup"];
82 
83  List<string> sources = new List<string>();
84 
85  string masterFileName = startupConfig.GetString("inimaster", "OpenSimDefaults.ini");
86 
87  if (masterFileName == "none")
88  masterFileName = String.Empty;
89 
90  if (IsUri(masterFileName))
91  {
92  if (!sources.Contains(masterFileName))
93  sources.Add(masterFileName);
94  }
95  else
96  {
97  string masterFilePath = Path.GetFullPath(
98  Path.Combine(Util.configDir(), masterFileName));
99 
100  if (masterFileName != String.Empty)
101  {
102  if (File.Exists(masterFilePath))
103  {
104  if (!sources.Contains(masterFilePath))
105  sources.Add(masterFilePath);
106  }
107  else
108  {
109  m_log.ErrorFormat("Master ini file {0} not found", Path.GetFullPath(masterFilePath));
110  Environment.Exit(1);
111  }
112  }
113  }
114 
115  string iniFileName = startupConfig.GetString("inifile", "OpenSim.ini");
116 
117  if (IsUri(iniFileName))
118  {
119  if (!sources.Contains(iniFileName))
120  sources.Add(iniFileName);
121  Application.iniFilePath = iniFileName;
122  }
123  else
124  {
125  Application.iniFilePath = Path.GetFullPath(
126  Path.Combine(Util.configDir(), iniFileName));
127 
128  if (!File.Exists(Application.iniFilePath))
129  {
130  iniFileName = "OpenSim.xml";
131  Application.iniFilePath = Path.GetFullPath(Path.Combine(Util.configDir(), iniFileName));
132  }
133 
134  if (File.Exists(Application.iniFilePath))
135  {
136  if (!sources.Contains(Application.iniFilePath))
137  sources.Add(Application.iniFilePath);
138  }
139  }
140 
142  m_config.Source = new IniConfigSource();
143  m_config.Source.Merge(DefaultConfig());
144 
145  m_log.Info("[CONFIG]: Reading configuration settings");
146 
147  for (int i = 0 ; i < sources.Count ; i++)
148  {
149  if (ReadConfig(m_config, sources[i]))
150  {
151  iniFileExists = true;
152  AddIncludes(m_config, sources);
153  }
154  }
155 
156  // Override distro settings with contents of inidirectory
157  string iniDirName = startupConfig.GetString("inidirectory", "config");
158  string iniDirPath = Path.Combine(Util.configDir(), iniDirName);
159 
160  if (Directory.Exists(iniDirPath))
161  {
162  m_log.InfoFormat("[CONFIG]: Searching folder {0} for config ini files", iniDirPath);
163  List<string> overrideSources = new List<string>();
164 
165  string[] fileEntries = Directory.GetFiles(iniDirName);
166  foreach (string filePath in fileEntries)
167  {
168  if (Path.GetExtension(filePath).ToLower() == ".ini")
169  {
170  if (!sources.Contains(Path.GetFullPath(filePath)))
171  {
172  overrideSources.Add(Path.GetFullPath(filePath));
173  // put it in sources too, to avoid circularity
174  sources.Add(Path.GetFullPath(filePath));
175  }
176  }
177  }
178 
179 
180  if (overrideSources.Count > 0)
181  {
182  OpenSimConfigSource overrideConfig = new OpenSimConfigSource();
183  overrideConfig.Source = new IniConfigSource();
184 
185  for (int i = 0 ; i < overrideSources.Count ; i++)
186  {
187  if (ReadConfig(overrideConfig, overrideSources[i]))
188  {
189  iniFileExists = true;
190  AddIncludes(overrideConfig, overrideSources);
191  }
192  }
193  m_config.Source.Merge(overrideConfig.Source);
194  }
195  }
196 
197  if (sources.Count == 0)
198  {
199  m_log.FatalFormat("[CONFIG]: Could not load any configuration");
200  Environment.Exit(1);
201  }
202  else if (!iniFileExists)
203  {
204  m_log.FatalFormat("[CONFIG]: Could not load any configuration");
205  m_log.FatalFormat("[CONFIG]: Configuration exists, but there was an error loading it!");
206  Environment.Exit(1);
207  }
208 
209  // Merge OpSys env vars
210  m_log.Info("[CONFIG]: Loading environment variables for Config");
211  Util.MergeEnvironmentToConfig(m_config.Source);
212 
213  // Make sure command line options take precedence
214  m_config.Source.Merge(argvSource);
215 
216  m_config.Source.ReplaceKeyValues();
217 
219 
220  return m_config;
221  }
222 
227  private void AddIncludes(OpenSimConfigSource configSource, List<string> sources)
228  {
229  //loop over config sources
230  foreach (IConfig config in configSource.Source.Configs)
231  {
232  // Look for Include-* in the key name
233  string[] keys = config.GetKeys();
234  foreach (string k in keys)
235  {
236  if (k.StartsWith("Include-"))
237  {
238  // read the config file to be included.
239  string file = config.GetString(k);
240  if (IsUri(file))
241  {
242  if (!sources.Contains(file))
243  sources.Add(file);
244  }
245  else
246  {
247  string basepath = Path.GetFullPath(Util.configDir());
248  // Resolve relative paths with wildcards
249  string chunkWithoutWildcards = file;
250  string chunkWithWildcards = string.Empty;
251  int wildcardIndex = file.IndexOfAny(new char[] { '*', '?' });
252  if (wildcardIndex != -1)
253  {
254  chunkWithoutWildcards = file.Substring(0, wildcardIndex);
255  chunkWithWildcards = file.Substring(wildcardIndex);
256  }
257  string path = Path.Combine(basepath, chunkWithoutWildcards);
258  path = Path.GetFullPath(path) + chunkWithWildcards;
259  string[] paths = Util.Glob(path);
260 
261  // If the include path contains no wildcards, then warn the user that it wasn't found.
262  if (wildcardIndex == -1 && paths.Length == 0)
263  {
264  m_log.WarnFormat("[CONFIG]: Could not find include file {0}", path);
265  }
266  else
267  {
268  foreach (string p in paths)
269  {
270  if (!sources.Contains(p))
271  sources.Add(p);
272  }
273  }
274  }
275  }
276  }
277  }
278  }
284  bool IsUri(string file)
285  {
286  Uri configUri;
287 
288  return Uri.TryCreate(file, UriKind.Absolute,
289  out configUri) && configUri.Scheme == Uri.UriSchemeHttp;
290  }
291 
297  private bool ReadConfig(OpenSimConfigSource configSource, string iniPath)
298  {
299  bool success = false;
300 
301  if (!IsUri(iniPath))
302  {
303  m_log.InfoFormat("[CONFIG]: Reading configuration file {0}", Path.GetFullPath(iniPath));
304 
305  configSource.Source.Merge(new IniConfigSource(iniPath));
306  success = true;
307  }
308  else
309  {
310  m_log.InfoFormat("[CONFIG]: {0} is a http:// URI, fetching ...", iniPath);
311 
312  // The ini file path is a http URI
313  // Try to read it
314  try
315  {
316  XmlReader r = XmlReader.Create(iniPath);
317  XmlConfigSource cs = new XmlConfigSource(r);
318  configSource.Source.Merge(cs);
319 
320  success = true;
321  }
322  catch (Exception e)
323  {
324  m_log.FatalFormat("[CONFIG]: Exception reading config from URI {0}\n" + e.ToString(), iniPath);
325  Environment.Exit(1);
326  }
327  }
328  return success;
329  }
330 
335  private static IConfigSource DefaultConfig()
336  {
337  IConfigSource defaultConfig = new IniConfigSource();
338 
339  {
340  IConfig config = defaultConfig.Configs["Startup"];
341 
342  if (null == config)
343  config = defaultConfig.AddConfig("Startup");
344 
345  config.Set("region_info_source", "filesystem");
346 
347  config.Set("physics", "OpenDynamicsEngine");
348  config.Set("meshing", "Meshmerizer");
349  config.Set("physical_prim", true);
350  config.Set("serverside_object_permissions", true);
351  config.Set("storage_prim_inventories", true);
352  config.Set("startup_console_commands_file", String.Empty);
353  config.Set("shutdown_console_commands_file", String.Empty);
354  config.Set("DefaultScriptEngine", "XEngine");
355  config.Set("clientstack_plugin", "OpenSim.Region.ClientStack.LindenUDP.dll");
356  // life doesn't really work without this
357  config.Set("EventQueue", true);
358  }
359 
360  {
361  IConfig config = defaultConfig.Configs["Network"];
362 
363  if (null == config)
364  config = defaultConfig.AddConfig("Network");
365 
366  config.Set("http_listener_port", ConfigSettings.DefaultRegionHttpPort);
367  }
368 
369  return defaultConfig;
370  }
371 
375  protected virtual void ReadConfigSettings()
376  {
377  IConfig startupConfig = m_config.Source.Configs["Startup"];
378  if (startupConfig != null)
379  {
380  m_configSettings.PhysicsEngine = startupConfig.GetString("physics");
381  m_configSettings.MeshEngineName = startupConfig.GetString("meshing");
382 
383  m_configSettings.ClientstackDll
384  = startupConfig.GetString("clientstack_plugin", "OpenSim.Region.ClientStack.LindenUDP.dll");
385  }
386 
387  m_networkServersInfo.loadFromConfiguration(m_config.Source);
388  }
389  }
390 }
Loads the Configuration files into nIni
virtual void ReadConfigSettings()
Read initial region settings from the ConfigSource
ConfigSettings m_configSettings
Various Config settings the region needs to start Physics Engine, Mesh Engine, GridMode, PhysicsPrim allowed, Neighbor, StorageDLL, Storage Connection String, Estate connection String, Client Stack Standalone settings.
Starting class for the OpenSimulator Region
Definition: Application.cs:43
NetworkServersInfo m_networkServersInfo
Grid Service Information. This refers to classes and addresses of the grid service ...
OpenSimConfigSource LoadConfigSettings(IConfigSource argvSource, EnvConfigSource envConfigSource, out ConfigSettings configSettings, out NetworkServersInfo networkInfo)
Loads the region configuration
OpenSimConfigSource m_config
A source of Configuration data
static string iniFilePath
Path to the main ini Configuration file
Definition: Application.cs:53