Package dak :: Module new_security_install
[hide private]
[frames] | no frames]

Source Code for Module dak.new_security_install

  1  #! /usr/bin/env python3 
  2   
  3  """ 
  4  Do whatever is needed to get a security upload released 
  5   
  6  @contact: Debian FTP Master <ftpmaster@debian.org> 
  7  @copyright: 2010 Joerg Jaspert <joerg@debian.org> 
  8  @license: GNU General Public License version 2 or later 
  9  """ 
 10   
 11  # This program is free software; you can redistribute it and/or modify 
 12  # it under the terms of the GNU General Public License as published by 
 13  # the Free Software Foundation; either version 2 of the License, or 
 14  # (at your option) any later version. 
 15   
 16  # This program is distributed in the hope that it will be useful, 
 17  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
 18  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 19  # GNU General Public License for more details. 
 20   
 21  # You should have received a copy of the GNU General Public License 
 22  # along with this program; if not, write to the Free Software 
 23  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
 24   
 25  ################################################################################ 
 26   
 27   
 28  ################################################################################ 
 29   
 30  import errno 
 31  import fcntl 
 32  import os 
 33  import subprocess 
 34  import sys 
 35  import time 
 36   
 37  import apt_pkg 
 38   
 39  from daklib import daklog, utils 
 40  from daklib.config import Config 
 41  from daklib.dbconn import DBConn, get_dbchange 
 42  from daklib.regexes import re_taint_free 
 43   
 44  Options = None 
 45  Logger = None 
 46  Queue = None 
 47  changes = [] 
 48   
 49   
50 -def usage():
51 print( 52 """Usage: dak security-install [OPTIONS] changesfiles 53 Do whatever there is to do for a security release 54 55 -h, --help show this help and exit 56 -n, --no-action don't commit changes 57 -s, --sudo dont bother, used internally 58 59 """ 60 ) 61 sys.exit()
62 63
64 -def spawn(command):
65 if not re_taint_free.match(command): 66 utils.fubar('Invalid character in "%s".' % (command)) 67 68 if Options["No-Action"]: 69 print("[%s]" % (command)) 70 else: 71 try: 72 subprocess.check_output(command.split(), stderr=subprocess.STDOUT) 73 except subprocess.CalledProcessError as e: 74 utils.fubar( 75 "Invocation of '%s' failed:\n%s\n" % (command, e.output.rstrip()), 76 e.returncode, 77 )
78 79 80 ##################### ! ! ! N O T E ! ! ! ##################### 81 # 82 # These functions will be reinvoked by semi-priveleged users, be careful not 83 # to invoke external programs that will escalate privileges, etc. 84 # 85 ##################### ! ! ! N O T E ! ! ! ##################### 86 87
88 -def sudo(arg, fn, exit):
89 if Options["Sudo"]: 90 subprocess.check_call( 91 [ 92 "/usr/bin/sudo", 93 "-u", 94 "dak", 95 "-H", 96 "/usr/local/bin/dak", 97 "new-security-install", 98 "-" + arg, 99 ] 100 ) 101 else: 102 fn() 103 if exit: 104 quit()
105 106
107 -def do_Approve():
108 sudo("A", _do_Approve, True)
109 110
111 -def _do_Approve():
112 print("Locking unchecked") 113 with os.fdopen( 114 os.open( 115 "/srv/security-master.debian.org/lock/unchecked.lock", 116 os.O_CREAT | os.O_RDWR, 117 ), 118 "r", 119 ) as lock_fd: 120 while True: 121 try: 122 fcntl.flock(lock_fd, fcntl.LOCK_EX | fcntl.LOCK_NB) 123 break 124 except OSError as e: 125 if e.errno in (errno.EACCES, errno.EAGAIN): 126 print("Another process keeping the unchecked lock, waiting.") 127 time.sleep(10) 128 else: 129 raise 130 131 # 1. Install accepted packages 132 print("Installing accepted packages into security archive") 133 for queue_name in ("embargoed",): 134 spawn("dak process-policy {0}".format(queue_name)) 135 136 # 2. Run all the steps that are needed to publish the changed archive 137 print("Doing loadsa stuff in the archive, will take time, please be patient") 138 os.environ["configdir"] = ( 139 "/srv/security-master.debian.org/dak/config/debian-security" 140 ) 141 spawn( 142 "/srv/security-master.debian.org/dak/config/debian-security/cronscript unchecked-dinstall" 143 ) 144 145 print("Triggering metadata export for packages.d.o and other consumers") 146 spawn("/srv/security-master.debian.org/dak/config/debian-security/export.sh")
147 148 149 ######################################################################## 150 ######################################################################## 151 152
153 -def main():
154 global Options, Logger, Queue, changes 155 cnf = Config() 156 157 Arguments = [ 158 ("h", "Help", "Security::Options::Help"), 159 ("n", "No-Action", "Security::Options::No-Action"), 160 ("c", "Changesfile", "Security::Options::Changesfile"), 161 ("s", "Sudo", "Security::Options::Sudo"), 162 ("A", "Approve", "Security::Options::Approve"), 163 ] 164 165 for i in ["Help", "No-Action", "Changesfile", "Sudo", "Approve"]: 166 key = "Security::Options::%s" % i 167 if key not in cnf: 168 cnf[key] = "" 169 170 changes_files = apt_pkg.parse_commandline(cnf.Cnf, Arguments, sys.argv) 171 172 Options = cnf.subtree("Security::Options") 173 if Options["Help"]: 174 usage() 175 176 changesfiles = {} 177 for a in changes_files: 178 if not a.endswith(".changes"): 179 utils.fubar("not a .changes file: %s" % (a)) 180 changesfiles[a] = 1 181 changes = list(changesfiles.keys()) 182 183 username = utils.getusername() 184 if username != "dak": 185 print("Non-dak user: %s" % username) 186 Options["Sudo"] = "y" 187 188 if Options["No-Action"]: 189 Options["Sudo"] = "" 190 191 if not Options["Sudo"] and not Options["No-Action"]: 192 Logger = daklog.Logger("security-install") 193 194 session = DBConn().session() 195 196 # If we call ourselve to approve, we do just that and exit 197 if Options["Approve"]: 198 do_Approve() 199 sys.exit() 200 201 if len(changes) == 0: 202 utils.fubar("Need changes files as arguments") 203 204 # Yes, we could do this inside do_Approve too. But this way we see who exactly 205 # called it (ownership of the file) 206 207 acceptfiles = {} 208 for change in changes: 209 dbchange = get_dbchange(os.path.basename(change), session) 210 # strip epoch from version 211 version = dbchange.version 212 version = version[(version.find(":") + 1) :] 213 # strip possible version from source (binNMUs) 214 source = dbchange.source.split(None, 1)[0] 215 acceptfilename = "%s/COMMENTS/ACCEPT.%s_%s" % ( 216 os.path.dirname(os.path.abspath(changes[0])), 217 source, 218 version, 219 ) 220 acceptfiles[acceptfilename] = 1 221 222 print( 223 "Would create %s now and then go on to accept this package, if you allow me to." 224 % (list(acceptfiles.keys())) 225 ) 226 if Options["No-Action"]: 227 sys.exit(0) 228 else: 229 input("Press Enter to continue") 230 231 for acceptfilename in acceptfiles: 232 with open(acceptfilename, "w") as accept_file: 233 accept_file.write("OK\n") 234 235 do_Approve()
236 237 238 if __name__ == "__main__": 239 main() 240