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 os 
 31  import sys 
 32  import time 
 33  import apt_pkg 
 34  import errno 
 35  import fcntl 
 36  import subprocess 
 37   
 38  from daklib import daklog 
 39  from daklib import utils 
 40  from daklib.dbconn import * 
 41  from daklib.regexes import re_taint_free 
 42  from daklib.config import Config 
 43   
 44  Options = None 
 45  Logger = None 
 46  Queue = None 
 47  changes = [] 
 48   
 49   
50 -def usage():
51 print("""Usage: dak security-install [OPTIONS] changesfiles 52 Do whatever there is to do for a security release 53 54 -h, --help show this help and exit 55 -n, --no-action don't commit changes 56 -s, --sudo dont bother, used internally 57 58 """) 59 sys.exit()
60 61
62 -def spawn(command):
63 if not re_taint_free.match(command): 64 utils.fubar("Invalid character in \"%s\"." % (command)) 65 66 if Options["No-Action"]: 67 print("[%s]" % (command)) 68 else: 69 try: 70 subprocess.check_output(command.split(), stderr=subprocess.STDOUT) 71 except subprocess.CalledProcessError as e: 72 utils.fubar("Invocation of '%s' failed:\n%s\n" % (command, e.output.rstrip()), e.returncode)
73 74 ##################### ! ! ! N O T E ! ! ! ##################### 75 # 76 # These functions will be reinvoked by semi-priveleged users, be careful not 77 # to invoke external programs that will escalate privileges, etc. 78 # 79 ##################### ! ! ! N O T E ! ! ! ##################### 80 81
82 -def sudo(arg, fn, exit):
83 if Options["Sudo"]: 84 subprocess.check_call( 85 ["/usr/bin/sudo", "-u", "dak", "-H", 86 "/usr/local/bin/dak", "new-security-install", "-" + arg]) 87 else: 88 fn() 89 if exit: 90 quit()
91 92
93 -def do_Approve():
94 sudo("A", _do_Approve, True)
95 96
97 -def _do_Approve():
98 print("Locking unchecked") 99 with os.fdopen(os.open('/srv/security-master.debian.org/lock/unchecked.lock', os.O_CREAT | os.O_RDWR), 'r') as lock_fd: 100 while True: 101 try: 102 fcntl.flock(lock_fd, fcntl.LOCK_EX | fcntl.LOCK_NB) 103 break 104 except OSError as e: 105 if e.errno in (errno.EACCES, errno.EAGAIN): 106 print("Another process keeping the unchecked lock, waiting.") 107 time.sleep(10) 108 else: 109 raise 110 111 # 1. Install accepted packages 112 print("Installing accepted packages into security archive") 113 for queue_name in ("embargoed",): 114 spawn("dak process-policy {0}".format(queue_name)) 115 116 # 2. Run all the steps that are needed to publish the changed archive 117 print("Doing loadsa stuff in the archive, will take time, please be patient") 118 os.environ['configdir'] = '/srv/security-master.debian.org/dak/config/debian-security' 119 spawn("/srv/security-master.debian.org/dak/config/debian-security/cronscript unchecked-dinstall") 120 121 print("Triggering metadata export for packages.d.o and other consumers") 122 spawn("/srv/security-master.debian.org/dak/config/debian-security/export.sh")
123 124 ######################################################################## 125 ######################################################################## 126 127
128 -def main():
129 global Options, Logger, Queue, changes 130 cnf = Config() 131 132 Arguments = [('h', "Help", "Security::Options::Help"), 133 ('n', "No-Action", "Security::Options::No-Action"), 134 ('c', 'Changesfile', "Security::Options::Changesfile"), 135 ('s', "Sudo", "Security::Options::Sudo"), 136 ('A', "Approve", "Security::Options::Approve") 137 ] 138 139 for i in ["Help", "No-Action", "Changesfile", "Sudo", "Approve"]: 140 key = "Security::Options::%s" % i 141 if key not in cnf: 142 cnf[key] = "" 143 144 changes_files = apt_pkg.parse_commandline(cnf.Cnf, Arguments, sys.argv) 145 146 Options = cnf.subtree("Security::Options") 147 if Options['Help']: 148 usage() 149 150 changesfiles = {} 151 for a in changes_files: 152 if not a.endswith(".changes"): 153 utils.fubar("not a .changes file: %s" % (a)) 154 changesfiles[a] = 1 155 changes = list(changesfiles.keys()) 156 157 username = utils.getusername() 158 if username != "dak": 159 print("Non-dak user: %s" % username) 160 Options["Sudo"] = "y" 161 162 if Options["No-Action"]: 163 Options["Sudo"] = "" 164 165 if not Options["Sudo"] and not Options["No-Action"]: 166 Logger = daklog.Logger("security-install") 167 168 session = DBConn().session() 169 170 # If we call ourselve to approve, we do just that and exit 171 if Options["Approve"]: 172 do_Approve() 173 sys.exit() 174 175 if len(changes) == 0: 176 utils.fubar("Need changes files as arguments") 177 178 # Yes, we could do this inside do_Approve too. But this way we see who exactly 179 # called it (ownership of the file) 180 181 acceptfiles = {} 182 for change in changes: 183 dbchange = get_dbchange(os.path.basename(change), session) 184 # strip epoch from version 185 version = dbchange.version 186 version = version[(version.find(':') + 1):] 187 # strip possible version from source (binNMUs) 188 source = dbchange.source.split(None, 1)[0] 189 acceptfilename = "%s/COMMENTS/ACCEPT.%s_%s" % (os.path.dirname(os.path.abspath(changes[0])), source, version) 190 acceptfiles[acceptfilename] = 1 191 192 print("Would create %s now and then go on to accept this package, if you allow me to." % (list(acceptfiles.keys()))) 193 if Options["No-Action"]: 194 sys.exit(0) 195 else: 196 input("Press Enter to continue") 197 198 for acceptfilename in acceptfiles: 199 with open(acceptfilename, "w") as accept_file: 200 accept_file.write("OK\n") 201 202 do_Approve()
203 204 205 if __name__ == '__main__': 206 main() 207