1""" 

2Config access class 

3 

4@contact: Debian FTPMaster <ftpmaster@debian.org> 

5@copyright: 2008 Mark Hymers <mhy@debian.org> 

6@license: GNU General Public License version 2 or later 

7""" 

8 

9# This program is free software; you can redistribute it and/or modify 

10# it under the terms of the GNU General Public License as published by 

11# the Free Software Foundation; either version 2 of the License, or 

12# (at your option) any later version. 

13 

14# This program is distributed in the hope that it will be useful, 

15# but WITHOUT ANY WARRANTY; without even the implied warranty of 

16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 

17# GNU General Public License for more details. 

18 

19# You should have received a copy of the GNU General Public License 

20# along with this program; if not, write to the Free Software 

21# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 

22 

23################################################################################ 

24 

25# <NCommander> mhy, how about "Now with 20% more monty python references" 

26 

27################################################################################ 

28 

29import getpass 

30import grp 

31import os 

32import socket 

33 

34import apt_pkg 

35 

36################################################################################ 

37 

38default_config = "/etc/dak/dak.conf" #: default dak config, defines host properties 

39 

40# suppress some deprecation warnings in squeeze related to apt_pkg 

41# module 

42import warnings 

43 

44warnings.filterwarnings("ignore", ".*apt_pkg.* is deprecated.*", DeprecationWarning) 

45 

46################################################################################ 

47 

48 

49def which_conf_file() -> str: 

50 return os.getenv("DAK_CONFIG", default_config) 

51 

52 

53class Config: 

54 """ 

55 A Config object is a singleton containing 

56 information about the DAK configuration 

57 """ 

58 

59 __shared_state = {} 

60 

61 def __init__(self, *args, **kwargs): 

62 self.__dict__ = self.__shared_state 

63 

64 if not getattr(self, "initialised", False): 

65 self.initialised = True 

66 self._readconf() 

67 self._setup_routines() 

68 

69 def _readconf(self): 

70 apt_pkg.init() 

71 

72 self.Cnf = apt_pkg.Configuration() 

73 

74 apt_pkg.read_config_file_isc(self.Cnf, which_conf_file()) 

75 

76 # Check whether our dak.conf was the real one or 

77 # just a pointer to our main one 

78 fqdn = socket.getfqdn() 

79 conffile = self.Cnf.get("Config::" + fqdn + "::DakConfig") 

80 if conffile: 80 ↛ 81line 80 didn't jump to line 81, because the condition on line 80 was never true

81 apt_pkg.read_config_file_isc(self.Cnf, conffile) 

82 

83 # Read group-specific options 

84 if "ByGroup" in self.Cnf: 84 ↛ 85line 84 didn't jump to line 85, because the condition on line 84 was never true

85 bygroup = self.Cnf.subtree("ByGroup") 

86 groups = set([os.getgid()]) 

87 groups.update(os.getgroups()) 

88 

89 for group in bygroup.list(): 

90 gid = grp.getgrnam(group).gr_gid 

91 if gid in groups: 

92 if bygroup.get(group): 

93 apt_pkg.read_config_file_isc(self.Cnf, bygroup[group]) 

94 break 

95 

96 # Read user-specific options 

97 byuser_config_path = self.Cnf.get(f"ByUser::{getpass.getuser()}", "") 

98 if byuser_config_path: 98 ↛ 99line 98 didn't jump to line 99, because the condition on line 98 was never true

99 apt_pkg.read_config_file_isc(self.Cnf, byuser_config_path) 

100 

101 if "Include" in self.Cnf: 101 ↛ 102line 101 didn't jump to line 102, because the condition on line 101 was never true

102 for filename in self.Cnf.value_list("Include"): 

103 apt_pkg.read_config_file_isc(self.Cnf, filename) 

104 

105 # Rebind some functions 

106 # TODO: Clean this up 

107 self.get = self.Cnf.get 

108 self.subtree = self.Cnf.subtree 

109 self.value_list = self.Cnf.value_list 

110 self.find = self.Cnf.find 

111 self.find_b = self.Cnf.find_b 

112 self.find_i = self.Cnf.find_i 

113 

114 def __contains__(self, name): 

115 return name in self.Cnf 

116 

117 def __getitem__(self, name): 

118 return self.Cnf[name] 

119 

120 def __setitem__(self, name, value): 

121 self.Cnf[name] = value 

122 

123 @staticmethod 

124 def get_db_value(name, default=None, rettype=None): 

125 from daklib.dbconn import DBConfig, DBConn, NoResultFound 

126 

127 try: 

128 res = DBConn().session().query(DBConfig).filter(DBConfig.name == name).one() 

129 except NoResultFound: 

130 return default 

131 

132 if rettype: 132 ↛ 135line 132 didn't jump to line 135, because the condition on line 132 was never false

133 return rettype(res.value) 

134 else: 

135 return res.value 

136 

137 def _setup_routines(self): 

138 """ 

139 This routine is the canonical list of which fields need to exist in 

140 the config table. If your dak instance is to work, we suggest reading it 

141 

142 Of course, what the values do is another matter 

143 """ 

144 for field in [ 

145 ("db_revision", None, int), 

146 ("defaultsuitename", "unstable", str), 

147 ("use_extfiles", None, int), 

148 ]: 

149 setattr( 

150 self, 

151 "get_%s" % field[0], 

152 lambda s=None, x=field[0], y=field[1], z=field[2]: self.get_db_value( 

153 x, y, z 

154 ), 

155 ) 

156 setattr( 

157 Config, 

158 "%s" % field[0], 

159 property(fget=getattr(self, "get_%s" % field[0])), 

160 ) 

161 

162 def get_defaultsuite(self): 

163 from daklib.dbconn import get_suite 

164 

165 suitename = self.defaultsuitename 

166 if not suitename: 

167 return None 

168 else: 

169 return get_suite(suitename) 

170 

171 defaultsuite = property(get_defaultsuite)