config.py 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. """
  2. Config access class
  3. @contact: Debian FTPMaster <ftpmaster@debian.org>
  4. @copyright: 2008 Mark Hymers <mhy@debian.org>
  5. @license: GNU General Public License version 2 or later
  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 2 of the License, or
  10. # (at your option) any later version.
  11. # This program is distributed in the hope that it will be useful,
  12. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. # GNU General Public License for more details.
  15. # You should have received a copy of the GNU General Public License
  16. # along with this program; if not, write to the Free Software
  17. # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  18. ################################################################################
  19. # <NCommander> mhy, how about "Now with 20% more monty python references"
  20. ################################################################################
  21. import getpass
  22. import grp
  23. import os
  24. import apt_pkg
  25. import socket
  26. ################################################################################
  27. default_config = "/etc/dak/dak.conf" #: default dak config, defines host properties
  28. # suppress some deprecation warnings in squeeze related to apt_pkg
  29. # module
  30. import warnings
  31. warnings.filterwarnings('ignore', ".*apt_pkg.* is deprecated.*", DeprecationWarning)
  32. ################################################################################
  33. def which_conf_file() -> str:
  34. return os.getenv("DAK_CONFIG", default_config)
  35. class Config:
  36. """
  37. A Config object is a singleton containing
  38. information about the DAK configuration
  39. """
  40. __shared_state = {}
  41. def __init__(self, *args, **kwargs):
  42. self.__dict__ = self.__shared_state
  43. if not getattr(self, 'initialised', False):
  44. self.initialised = True
  45. self._readconf()
  46. self._setup_routines()
  47. def _readconf(self):
  48. apt_pkg.init()
  49. self.Cnf = apt_pkg.Configuration()
  50. apt_pkg.read_config_file_isc(self.Cnf, which_conf_file())
  51. # Check whether our dak.conf was the real one or
  52. # just a pointer to our main one
  53. fqdn = socket.getfqdn()
  54. conffile = self.Cnf.get("Config::" + fqdn + "::DakConfig")
  55. if conffile:
  56. apt_pkg.read_config_file_isc(self.Cnf, conffile)
  57. # Read group-specific options
  58. if 'ByGroup' in self.Cnf:
  59. bygroup = self.Cnf.subtree('ByGroup')
  60. groups = set([os.getgid()])
  61. groups.update(os.getgroups())
  62. for group in bygroup.list():
  63. gid = grp.getgrnam(group).gr_gid
  64. if gid in groups:
  65. if bygroup.get(group):
  66. apt_pkg.read_config_file_isc(self.Cnf, bygroup[group])
  67. break
  68. # Read user-specific options
  69. byuser_config_path = self.Cnf.get(f"ByUser::{getpass.getuser()}", "")
  70. if byuser_config_path:
  71. apt_pkg.read_config_file_isc(self.Cnf, byuser_config_path)
  72. if 'Include' in self.Cnf:
  73. for filename in self.Cnf.value_list('Include'):
  74. apt_pkg.read_config_file_isc(self.Cnf, filename)
  75. # Rebind some functions
  76. # TODO: Clean this up
  77. self.get = self.Cnf.get
  78. self.subtree = self.Cnf.subtree
  79. self.value_list = self.Cnf.value_list
  80. self.find = self.Cnf.find
  81. self.find_b = self.Cnf.find_b
  82. self.find_i = self.Cnf.find_i
  83. def __contains__(self, name):
  84. return name in self.Cnf
  85. def __getitem__(self, name):
  86. return self.Cnf[name]
  87. def __setitem__(self, name, value):
  88. self.Cnf[name] = value
  89. @staticmethod
  90. def get_db_value(name, default=None, rettype=None):
  91. from daklib.dbconn import DBConfig, DBConn, NoResultFound
  92. try:
  93. res = DBConn().session().query(DBConfig).filter(DBConfig.name == name).one()
  94. except NoResultFound:
  95. return default
  96. if rettype:
  97. return rettype(res.value)
  98. else:
  99. return res.value
  100. def _setup_routines(self):
  101. """
  102. This routine is the canonical list of which fields need to exist in
  103. the config table. If your dak instance is to work, we suggest reading it
  104. Of course, what the values do is another matter
  105. """
  106. for field in [('db_revision', None, int),
  107. ('defaultsuitename', 'unstable', str),
  108. ('use_extfiles', None, int)
  109. ]:
  110. setattr(self, 'get_%s' % field[0], lambda s=None, x=field[0], y=field[1], z=field[2]: self.get_db_value(x, y, z))
  111. setattr(Config, '%s' % field[0], property(fget=getattr(self, 'get_%s' % field[0])))
  112. def get_defaultsuite(self):
  113. from daklib.dbconn import get_suite
  114. suitename = self.defaultsuitename
  115. if not suitename:
  116. return None
  117. else:
  118. return get_suite(suitename)
  119. defaultsuite = property(get_defaultsuite)