Package dak :: Package dakdb :: Module update83
[hide private]
[frames] | no frames]

Source Code for Module dak.dakdb.update83

  1  """ 
  2  switch to new ACL implementation and add pre-suite NEW 
  3   
  4  @contact: Debian FTP Master <ftpmaster@debian.org> 
  5  @copyright: 2012 Ansgar Burchardt <ansgar@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  import psycopg2 
 26  from daklib.dak_exceptions import DBUpdateError 
 27  from daklib.config import Config 
 28   
 29  statements = [ 
 30  """ALTER TABLE suite ADD COLUMN new_queue_id INT REFERENCES policy_queue(id)""", 
 31   
 32  """CREATE TABLE acl ( 
 33      id SERIAL PRIMARY KEY NOT NULL, 
 34      name TEXT NOT NULL, 
 35      is_global BOOLEAN NOT NULL DEFAULT 'f', 
 36   
 37      match_fingerprint BOOLEAN NOT NULL DEFAULT 'f', 
 38      match_keyring_id INTEGER REFERENCES keyrings(id), 
 39   
 40      allow_new BOOLEAN NOT NULL DEFAULT 'f', 
 41      allow_source BOOLEAN NOT NULL DEFAULT 'f', 
 42      allow_binary BOOLEAN NOT NULL DEFAULT 'f', 
 43      allow_binary_all BOOLEAN NOT NULL DEFAULT 'f', 
 44      allow_binary_only BOOLEAN NOT NULL DEFAULT 'f', 
 45      allow_hijack BOOLEAN NOT NULL DEFAULT 'f', 
 46      allow_per_source BOOLEAN NOT NULL DEFAULT 'f', 
 47      deny_per_source BOOLEAN NOT NULL DEFAULT 'f' 
 48      )""", 
 49   
 50  """CREATE TABLE acl_architecture_map ( 
 51      acl_id INTEGER NOT NULL REFERENCES acl(id) ON DELETE CASCADE, 
 52      architecture_id INTEGER NOT NULL REFERENCES architecture(id) ON DELETE CASCADE, 
 53      PRIMARY KEY (acl_id, architecture_id) 
 54      )""", 
 55   
 56  """CREATE TABLE acl_fingerprint_map ( 
 57      acl_id INTEGER NOT NULL REFERENCES acl(id) ON DELETE CASCADE, 
 58      fingerprint_id INTEGER NOT NULL REFERENCES fingerprint(id) ON DELETE CASCADE, 
 59      PRIMARY KEY (acl_id, fingerprint_id) 
 60      )""", 
 61   
 62  """CREATE TABLE acl_per_source ( 
 63      acl_id INTEGER NOT NULL REFERENCES acl(id) ON DELETE CASCADE, 
 64      fingerprint_id INTEGER NOT NULL REFERENCES fingerprint(id) ON DELETE CASCADE, 
 65      source TEXT NOT NULL, 
 66      reason TEXT, 
 67      PRIMARY KEY (acl_id, fingerprint_id, source) 
 68      )""", 
 69   
 70  """CREATE TABLE suite_acl_map ( 
 71      suite_id INTEGER NOT NULL REFERENCES suite(id) ON DELETE CASCADE, 
 72      acl_id INTEGER NOT NULL REFERENCES acl(id), 
 73      PRIMARY KEY (suite_id, acl_id) 
 74      )""", 
 75  ] 
 76   
 77  ################################################################################ 
 78   
 79   
80 -def get_buildd_acl_id(c, keyring_id):
81 c.execute(""" 82 SELECT 'buildd-' || STRING_AGG(a.arch_string, '+' ORDER BY a.arch_string) 83 FROM keyring_acl_map kam 84 JOIN architecture a ON kam.architecture_id = a.id 85 WHERE kam.keyring_id = %(keyring_id)s 86 """, {'keyring_id': keyring_id}) 87 acl_name, = c.fetchone() 88 89 c.execute('SELECT id FROM acl WHERE name = %(acl_name)s', {'acl_name': acl_name}) 90 row = c.fetchone() 91 if row is not None: 92 return row[0] 93 94 c.execute(""" 95 INSERT INTO acl 96 ( name, allow_new, allow_source, allow_binary, allow_binary_all, allow_binary_only, allow_hijack) 97 VALUES (%(acl_name)s, 't', 'f', 't', 'f', 't', 't') 98 RETURNING id""", {'acl_name': acl_name}) 99 acl_id, = c.fetchone() 100 101 c.execute("""INSERT INTO acl_architecture_map (acl_id, architecture_id) 102 SELECT %(acl_id)s, architecture_id 103 FROM keyring_acl_map 104 WHERE keyring_id = %(keyring_id)s""", 105 {'acl_id': acl_id, 'keyring_id': keyring_id}) 106 107 return acl_id
108 109
110 -def get_acl_id(c, acl_dd, acl_dm, keyring_id, source_acl_id, binary_acl_id):
111 c.execute('SELECT access_level FROM source_acl WHERE id = %(source_acl_id)s', {'source_acl_id': source_acl_id}) 112 row = c.fetchone() 113 if row is not None: 114 source_acl = row[0] 115 else: 116 source_acl = None 117 118 c.execute('SELECT access_level FROM binary_acl WHERE id = %(binary_acl_id)s', {'binary_acl_id': binary_acl_id}) 119 row = c.fetchone() 120 if row is not None: 121 binary_acl = row[0] 122 else: 123 binary_acl = None 124 125 if source_acl == 'full' and binary_acl == 'full': 126 return acl_dd 127 elif source_acl == 'dm' and binary_acl == 'full': 128 return acl_dm 129 elif source_acl is None and binary_acl == 'map': 130 return get_buildd_acl_id(c, keyring_id) 131 132 raise Exception('Cannot convert ACL combination automatically: binary_acl={0}, source_acl={1}'.format(binary_acl, source_acl))
133 134
135 -def do_update(self):
136 print(__doc__) 137 try: 138 cnf = Config() 139 140 c = self.db.cursor() 141 142 for stmt in statements: 143 c.execute(stmt) 144 145 c.execute(""" 146 INSERT INTO acl 147 (name, allow_new, allow_source, allow_binary, allow_binary_all, allow_binary_only, allow_hijack) 148 VALUES ('dd', 't', 't', 't', 't', 't', 't') 149 RETURNING id""") 150 acl_dd, = c.fetchone() 151 152 c.execute(""" 153 INSERT INTO acl 154 (name, allow_new, allow_source, allow_binary, allow_binary_all, allow_binary_only, allow_per_source, allow_hijack) 155 VALUES ('dm', 'f', 't', 't', 't', 'f', 't', 'f') 156 RETURNING id""") 157 acl_dm, = c.fetchone() 158 159 # convert per-fingerprint ACLs 160 161 c.execute('ALTER TABLE fingerprint ADD COLUMN acl_id INTEGER REFERENCES acl(id)') 162 c.execute("""SELECT id, keyring, source_acl_id, binary_acl_id 163 FROM fingerprint 164 WHERE source_acl_id IS NOT NULL OR binary_acl_id IS NOT NULL""") 165 for fingerprint_id, keyring_id, source_acl_id, binary_acl_id in c.fetchall(): 166 acl_id = get_acl_id(c, acl_dd, acl_dm, keyring_id, source_acl_id, binary_acl_id) 167 c.execute('UPDATE fingerprint SET acl_id = %(acl_id)s WHERE id = %(fingerprint_id)s', 168 {'acl_id': acl_id, 'fingerprint_id': fingerprint_id}) 169 c.execute("""ALTER TABLE fingerprint 170 DROP COLUMN source_acl_id, 171 DROP COLUMN binary_acl_id, 172 DROP COLUMN binary_reject""") 173 174 # convert per-keyring ACLs 175 c.execute('ALTER TABLE keyrings ADD COLUMN acl_id INTEGER REFERENCES acl(id)') 176 c.execute('SELECT id, default_source_acl_id, default_binary_acl_id FROM keyrings') 177 for keyring_id, source_acl_id, binary_acl_id in c.fetchall(): 178 acl_id = get_acl_id(c, acl_dd, acl_dm, keyring_id, source_acl_id, binary_acl_id) 179 c.execute('UPDATE keyrings SET acl_id = %(acl_id)s WHERE id = %(keyring_id)s', 180 {'acl_id': acl_id, 'keyring_id': keyring_id}) 181 c.execute("""ALTER TABLE keyrings 182 DROP COLUMN default_source_acl_id, 183 DROP COLUMN default_binary_acl_id, 184 DROP COLUMN default_binary_reject""") 185 186 c.execute("DROP TABLE keyring_acl_map") 187 c.execute("DROP TABLE binary_acl_map") 188 c.execute("DROP TABLE binary_acl") 189 c.execute("DROP TABLE source_acl") 190 191 # convert upload blocks 192 c.execute(""" 193 INSERT INTO acl 194 ( name, is_global, allow_new, allow_source, allow_binary, allow_binary_all, allow_hijack, allow_binary_only, deny_per_source) 195 VALUES ('blocks', 't', 't', 't', 't', 't', 't', 't', 't') 196 RETURNING id""") 197 acl_block, = c.fetchone() 198 c.execute("SELECT source, fingerprint_id, reason FROM upload_blocks") 199 for source, fingerprint_id, reason in c.fetchall(): 200 if fingerprint_id is None: 201 raise Exception( 202 "ERROR: upload blocks based on uid are no longer supported\n" 203 "=========================================================\n" 204 "\n" 205 "dak now only supports upload blocks based on fingerprints. Please remove\n" 206 "any uid-specific block by running\n" 207 " DELETE FROM upload_blocks WHERE fingerprint_id IS NULL\n" 208 "and try again.") 209 210 c.execute('INSERT INTO acl_match_source_map (acl_id, fingerprint_id, source, reason) VALUES (%(acl_id)s, %(fingerprint_id)s, %(source)s, %(reason)s)', 211 {'acl_id': acl_block, 'fingerprint_id': fingerprint_id, 'source': source, 'reason': reason}) 212 c.execute("DROP TABLE upload_blocks") 213 214 c.execute("UPDATE config SET value = '83' WHERE name = 'db_revision'") 215 self.db.commit() 216 217 except psycopg2.ProgrammingError as msg: 218 self.db.rollback() 219 raise DBUpdateError('Unable to apply sick update 83, rollback issued. Error message: {0}'.format(msg))
220