# Sync the ISC configuartion file and the SQL database
# Copyright (C) 2000, 2001, 2002 James Troup <james@nocrew.org>
-# $Id: alyson,v 1.9 2002-05-14 15:28:53 troup Exp $
+# $Id: alyson,v 1.10 2002-10-16 02:47:32 troup Exp $
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
################################################################################
-import pg, sys, string
-import utils, db_access
+import pg, sys;
+import utils, db_access;
import apt_pkg;
################################################################################
for name in Cnf.SubTree("Component").List():
Component = Cnf.SubTree("Component::%s" % (name));
description = get(Component, "Description");
- if string.lower(Component.get("MeetsDFSG")) == "true":
+ if Component.get("MeetsDFSG").lower() == "true":
meets_dfsg = "true";
else:
meets_dfsg = "false";
origin = get(Suite, "Origin");
description = get(Suite, "Description");
projectB.query("INSERT INTO suite (suite_name, version, origin, description) VALUES ('%s', %s, %s, %s)"
- % (string.lower(suite), version, origin, description));
+ % (suite.lower(), version, origin, description));
for architecture in Cnf.ValueList("Suite::%s::Architectures" % (suite)):
architecture_id = db_access.get_architecture_id (architecture);
if architecture_id < 0:
prefix = "";
else:
prefix = "";
- component = string.replace(component, "non-US/", "");
+ component = component.replace("non-US/", "");
if component != 'main':
suffix = '/' + component;
else:
# Wrapper for Debian Security team
# Copyright (C) 2002 James Troup <james@nocrew.org>
-# $Id: amber,v 1.5 2002-07-14 15:03:26 troup Exp $
+# $Id: amber,v 1.6 2002-10-16 02:47:32 troup Exp $
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
################################################################################
-import commands, os, pwd, re, string, sys, time;
+import commands, os, pwd, re, sys, time;
import apt_pkg;
import katie, utils;
num_upload_uris = len(upload_uris.keys());
if num_upload_uris == 0:
utils.fubar("%s: No valid upload URI found from components (%s)."
- % (changes_file, string.join(components.keys(), ", ")));
+ % (changes_file, ", ".join(components.keys())));
elif num_upload_uris > 1:
utils.fubar("%s: more than one upload URI (%s) from components (%s)."
- % (changes_file, string.join(upload_uris.keys(), ", "),
- string.join(components.keys(), ", ")));
+ % (changes_file, ", ".join(upload_uris.keys()),
+ ", ".join(components.keys())));
upload_uri = upload_uris.keys()[0];
# Update the file list for the upload uri
if not uploads.has_key(upload_uri):
return;
for uri in uploads.keys():
- (host, path) = string.split(uri, ":");
- file_list = string.join(uploads[uri]);
+ (host, path) = uri.split(":");
+ file_list = " ".join(uploads[uri]);
print "Uploading files to %s..." % (host);
spawn("lftp -c 'open %s; cd %s; put %s'" % (host, path, file_list));
file = utils.open_file(filename, 'a');
for source in package_list.keys():
for version in package_list[source].keys():
- file.write(string.join([source, version])+'\n');
+ file.write(" ".join([source, version])+'\n');
file.close();
######################################################################
src = Katie.pkg.changes["source"];
if src not in adv_packages:
- adv_packages = adv_packages + [src];
+ adv_packages += [src];
suites = Katie.pkg.changes["distribution"].keys();
for suite in suites:
size = files[file]["size"];
poolname = Cnf["Dir::PoolRoot"] + \
utils.poolify(src, files[file]["component"]);
- if arch == "source" and file[-4:] == ".dsc":
+ if arch == "source" and file.endswith(".dsc"):
dscpoolname = poolname;
for suite in suites:
if not updated_pkgs[suite].has_key(arch):
"poolname": dscpoolname };
if os.environ.has_key("SUDO_UID"):
- whoami = string.atol(os.environ["SUDO_UID"]);
+ whoami = os.environ["SUDO_UID"].atol();
else:
whoami = os.getuid();
whoamifull = pwd.getpwuid(whoami);
- username = string.split(whoamifull[4], ",")[0];
+ username = whoamifull[4].split(",")[0];
Subst = {
"__ADVISORY__": advisory_nr,
"__WHOAMI__": username,
"__DATE__": time.strftime("%B %d, %Y", time.gmtime(time.time())),
- "__PACKAGE__": string.join(adv_packages,", "),
+ "__PACKAGE__": ", ".join(adv_packages),
"__KATIE_ADDRESS__": Cnf["Dinstall::MyEmailAddress"]
};
for suite in updated_pkgs.keys():
suite_header = "%s %s (%s)" % (Cnf["Dinstall::MyDistribution"],
Cnf["Suite::%s::Version" % suite], suite);
- adv = adv + "%s\n%s\n\n" % (suite_header, "-"*len(suite_header));
+ adv += "%s\n%s\n\n" % (suite_header, "-"*len(suite_header));
arches = Cnf.ValueList("Suite::%s::Architectures" % suite);
if "source" in arches:
arches.remove("all");
arches.sort();
- adv = adv + " %s was released for %s.\n\n" % (
- string.capitalize(suite), utils.join_with_commas_and(arches));
+ adv += " %s was released for %s.\n\n" % (
+ suite.capitalize(), utils.join_with_commas_and(arches));
for a in ["source", "all"] + arches:
if not updated_pkgs[suite].has_key(a):
continue;
if a == "source":
- adv = adv + " Source archives:\n\n";
+ adv += " Source archives:\n\n";
elif a == "all":
- adv = adv + " Architecture independent packages:\n\n";
+ adv += " Architecture independent packages:\n\n";
else:
- adv = adv + " %s architecture (%s)\n\n" % (a,
+ adv += " %s architecture (%s)\n\n" % (a,
Cnf["Architectures::%s" % a]);
for file in updated_pkgs[suite][a].keys():
- adv = adv + " http://%s/%s%s\n" % (
+ adv += " http://%s/%s%s\n" % (
archive, updated_pkgs[suite][a][file]["poolname"], file);
- adv = adv + " Size/MD5 checksum: %8s %s\n" % (
+ adv += " Size/MD5 checksum: %8s %s\n" % (
updated_pkgs[suite][a][file]["size"],
updated_pkgs[suite][a][file]["md5"]);
- adv = adv + "\n";
- adv = string.rstrip(adv);
+ adv += "\n";
+ adv = adv.rstrip();
Subst["__ADVISORY_TEXT__"] = adv;
advisory_number = arguments[0];
changes_files = arguments[1:];
- if advisory_number[-8:] == ".changes":
+ if advisory_number.endswith(".changes"):
utils.warn("first argument must be the advisory number.");
usage(1);
for file in changes_files:
def yes_no(prompt):
while 1:
- answer = string.lower(utils.our_raw_input(prompt+" "));
+ answer = utils.our_raw_input(prompt+" ").lower();
if answer == "y" or answer == "n":
break;
else:
os.chdir(Cnf["Dir::Queue::Accepted"]);
print "Installing packages into the archive...";
- spawn("%s/katie -pa %s" % (Cnf["Dir::Katie"], string.join(changes_files)));
+ spawn("%s/kelly -pa %s" % (Cnf["Dir::Katie"], " ".join(changes_files)));
os.chdir(Cnf["Dir::Katie"]);
print "Updating file lists for apt-ftparchive...";
spawn("./jenna");
# Check for fixable discrepancies between stable and unstable
# Copyright (C) 2000, 2001, 2002 James Troup <james@nocrew.org>
-# $Id: andrea,v 1.7 2002-05-14 15:28:53 troup Exp $
+# $Id: andrea,v 1.8 2002-10-16 02:47:32 troup Exp $
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
################################################################################
-import pg, string, sys;
+import pg, sys;
import utils, db_access;
import apt_pkg;
ORDER BY b_src.package;"""
% (src_suite_id, arch_id, dst_suite_id, dsc_type_id, arch_id, arch_all_id, dst_suite_id, dst_suite_id));
for i in q.getresult():
- print string.join(i, ' ');
+ print " ".join(i);
#######################################################################################
# Dump variables from a .katie file to stdout
# Copyright (C) 2001, 2002 James Troup <james@nocrew.org>
-# $Id: ashley,v 1.6 2002-08-07 17:19:29 troup Exp $
+# $Id: ashley,v 1.7 2002-10-16 02:47:32 troup Exp $
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
################################################################################
-import string, sys;
+import sys;
import katie, utils;
def main():
print " Changes:";
# Mandatory changes fields
for i in [ "source", "version", "maintainer", "urgency", "changedby822", "changedbyname", "maintainername", "maintaineremail", "fingerprint" ]:
- print " %s: %s" % (string.capitalize(i), changes[i]);
+ print " %s: %s" % (i.capitalize(), changes[i]);
del changes[i];
# Mandatory changes lists
for i in [ "distribution", "architecture", "closes" ]:
- print " %s: %s" % (string.capitalize(i), string.join(changes[i].keys()));
+ print " %s: %s" % (i.capitalize(), " ".join(changes[i].keys()));
del changes[i];
# Optional changes fields
for i in [ "changed-by", "maintainer822", "filecontents", "format" ]:
if changes.has_key(i):
- print " %s: %s" % (string.capitalize(i), changes[i]);
+ print " %s: %s" % (i.capitalize(), changes[i]);
del changes[i];
print;
if changes:
print " Dsc:";
for i in [ "source", "version", "maintainer", "fingerprint", "uploaders" ]:
if dsc.has_key(i):
- print " %s: %s" % (string.capitalize(i), dsc[i]);
+ print " %s: %s" % (i.capitalize(), dsc[i]);
del dsc[i];
print;
if dsc:
"source version", "maintainer", "dbtype", "files id",
"new", "section", "priority" ]:
if files[file].has_key(i):
- print " %s: %s" % (string.capitalize(i), files[file][i]);
+ print " %s: %s" % (i.capitalize(), files[file][i]);
del files[file][i];
if files[file]:
utils.warn("files[%s] still has following unrecognised keys: %s" % (file, files[file].keys()));
print " %s:" % (file);
# Mandatory fields
for i in [ "size", "md5sum" ]:
- print " %s: %s" % (string.capitalize(i), dsc_files[file][i]);
+ print " %s: %s" % (i.capitalize(), dsc_files[file][i]);
del dsc_files[file][i];
# Optional fields
for i in [ "files id" ]:
if dsc_files[file].has_key(i):
- print " %s: %s" % (string.capitalize(i), dsc_files[file][i]);
+ print " %s: %s" % (i.capitalize(), dsc_files[file][i]);
del dsc_files[file][i];
if dsc_files[file]:
utils.warn("dsc_files[%s] still has following unrecognised keys: %s" % (file, dsc_files[file].keys()));
# Poolify (move packages from "legacy" type locations to pool locations)
# Copyright (C) 2000, 2001, 2002 James Troup <james@nocrew.org>
-# $Id: catherine,v 1.16 2002-05-08 11:13:02 troup Exp $
+# $Id: catherine,v 1.17 2002-10-16 02:47:32 troup Exp $
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
################################################################################
-import os, pg, stat, string, sys
-import utils, db_access
+import os, pg, stat, sys;
+import utils, db_access;
import apt_pkg, apt_inst;
################################################################################
if (poolized_size + size) > limit and limit >= 0:
utils.warn("Hit %s limit." % (utils.size_type(limit)));
break;
- poolized_size = poolized_size + size;
- poolized_count = poolized_count + 1;
+ poolized_size += size;
+ poolized_count += 1;
base_filename = os.path.basename(legacy_filename);
destination_filename = base_filename;
# Work out the source package name
control = apt_pkg.ParseSection(apt_inst.debExtractControl(utils.open_file(legacy_filename)))
package = control.Find("Package", "");
source = control.Find("Source", package);
- if string.find(source, "(") != -1:
+ if source.find("(") != -1:
m = utils.re_extract_src_version.match(source)
source = m.group(1)
# If it's a binary, we need to also rename the file to include the architecture
# Generate Maintainers file used by e.g. the Debian Bug Tracking System
# Copyright (C) 2000, 2001, 2002 James Troup <james@nocrew.org>
-# $Id: charisma,v 1.14 2002-05-03 16:06:45 troup Exp $
+# $Id: charisma,v 1.15 2002-10-16 02:47:32 troup Exp $
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
################################################################################
-import pg, string, sys;
+import pg, sys;
import db_access, utils;
import apt_pkg;
db_access.init(Cnf, projectB);
for suite in Cnf.SubTree("Suite").List():
- suite = string.lower(suite);
+ suite = suite.lower();
suite_priority = int(Cnf["Suite::%s::Priority" % (suite)]);
# Source packages
for filename in extra_files:
file = utils.open_file(filename);
for line in file.readlines():
- line = string.strip(utils.re_comments.sub('', line[:-1]))
+ line = utils.re_comments.sub('', line[:-1]).strip();
if line == "":
continue;
- split = string.split(line);
+ split = line.split();
lhs = split[0];
- maintainer = fix_maintainer(string.join(split[1:]));
- if string.find(lhs,'~') != -1:
- lhs_split = string.split(lhs, '~');
- package = lhs_split[0];
- version = lhs_split[1];
+ maintainer = fix_maintainer(" ".join(split[1:]));
+ if lhs.find('~') != -1:
+ (package, version) = lhs.split('~');
else:
package = lhs;
version = '*';
package_keys = packages.keys()
package_keys.sort()
for package in package_keys:
- lhs = string.join([package, packages[package]["version"]], '~');
+ lhs = "~".join([package, packages[package]["version"]]);
print "%-30s %s" % (lhs, packages[package]["maintainer"]);
################################################################################
# 'Fix' stable to make debian-cd and dpkg -BORGiE users happy
# Copyright (C) 2000, 2001, 2002 James Troup <james@nocrew.org>
-# $Id: claire.py,v 1.17 2002-06-08 00:15:57 troup Exp $
+# $Id: claire.py,v 1.18 2002-10-16 02:47:32 troup Exp $
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
################################################################################
-import os, pg, re, string, sys
-import utils, db_access
+import os, pg, re, sys;
+import utils, db_access;
import apt_pkg;
################################################################################
# Relativize an absolute symlink from 'src' -> 'dest' relative to 'root'.
# Returns fixed 'src'
def clean_symlink (src, dest, root):
- src = string.replace(src, root, '', 1);
- dest = string.replace(dest, root, '', 1);
+ src = src.replace(root, '', 1);
+ dest = dest.replace(root, '', 1);
dest = os.path.dirname(dest);
- new_src = '../' * len(string.split(dest, '/'));
+ new_src = '../' * len(dest.split('/'));
return new_src + src;
################################################################################
# FIXME: ugly hacks to work around override brain damage
section = re_strip_section_prefix.sub('', section);
- section = string.replace(string.lower(section), 'non-us', '');
+ section = section.lower().replace('non-us', '');
if section == "main" or section == "contrib" or section == "non-free":
section = '';
if section != '':
- section = section + '/';
+ section += '/';
return (component, section);
+#!/usr/bin/env python
+
# DB access fucntions
# Copyright (C) 2000, 2001, 2002 James Troup <james@nocrew.org>
-# $Id: db_access.py,v 1.13 2002-05-03 16:06:45 troup Exp $
+# $Id: db_access.py,v 1.14 2002-10-16 02:47:32 troup Exp $
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
############################################################################################
-import string, sys, time;
+import sys, time;
############################################################################################
def get_archive_id (archive):
global archive_id_cache
- archive = string.lower(archive);
+ archive = archive.lower();
if archive_id_cache.has_key(archive):
return archive_id_cache[archive]
def get_component_id (component):
global component_id_cache
- component = string.lower(component);
+ component = component.lower();
if component_id_cache.has_key(component):
return component_id_cache[component]
# Output override files for apt-ftparchive and indices/
# Copyright (C) 2000, 2001, 2002 James Troup <james@nocrew.org>
-# $Id: denise,v 1.13 2002-07-30 19:02:06 troup Exp $
+# $Id: denise,v 1.14 2002-10-16 02:47:32 troup Exp $
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
################################################################################
-import pg, sys, string
-import utils, db_access
+import pg, sys;
+import utils, db_access;
import apt_pkg;
################################################################################
override_type = ".debian-installer";
elif type == "dsc":
override_type = ".src";
- filename = "%s/override.%s.%s%s" % (Cnf["Dir::Override"], override_suite, string.replace(component, "non-US/", ""), override_type);
+ filename = "%s/override.%s.%s%s" % (Cnf["Dir::Override"], override_suite, component.replace("non-US/", ""), override_type);
file = utils.open_file(filename, 'w');
list(file, suite, component, type);
file.close();
override_type = ".src";
elif type == "udeb":
continue;
- filename = "%s/override.%s.%s%s" % (Cnf["Dir::Override"], override_suite, string.replace(component, "non-US/", ""), override_type);
+ filename = "%s/override.%s.%s%s" % (Cnf["Dir::Override"], override_suite, component.replace("non-US/", ""), override_type);
file = utils.open_file(filename, 'w');
for i in q.getresult():
package = i[0];
# Script to automate some parts of checking NEW packages
# Copyright (C) 2000, 2001, 2002 James Troup <james@nocrew.org>
-# $Id: fernanda.py,v 1.3 2002-05-18 23:54:51 troup Exp $
+# $Id: fernanda.py,v 1.4 2002-10-16 02:47:32 troup Exp $
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
def check_deb (deb_filename):
filename = os.path.basename(deb_filename);
- if filename[-5:] == ".udeb":
+ if filename.endswith(".udeb"):
is_a_udeb = 1;
else:
is_a_udeb = 0;
changes = utils.parse_changes (changes_filename);
files = utils.build_file_list(changes);
for file in files.keys():
- if file[-4:] == ".deb" or file[-5:] == ".udeb":
+ if file.endswith(".deb") or file.endswith(".udeb"):
check_deb(file);
- if file[-4:] == ".dsc":
+ if file.endswith(".dsc"):
check_dsc(file);
# else: => byhand
sys.stdout = less_fd;
try:
- if file[-8:] == ".changes":
+ if file.endswith(".changes"):
check_changes(file);
- elif file[-4:] == ".deb" or file[-5:] == ".udeb":
+ elif file.endswith(".deb") or file.endswith(".udeb"):
check_deb(file);
- elif file[-4:] == ".dsc":
+ elif file.endswith(".dsc"):
check_dsc(file);
else:
utils.fubar("Unrecognised file type: '%s'." % (file));
# Remove obsolete .changes files from proposed-updates
# Copyright (C) 2001, 2002 James Troup <james@nocrew.org>
-# $Id: halle,v 1.8 2002-06-08 00:17:53 troup Exp $
+# $Id: halle,v 1.9 2002-10-16 02:47:32 troup Exp $
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
################################################################################
-import os, pg, re, sys, string;
+import os, pg, re, sys;
import utils, db_access;
import apt_pkg;
type = m.group(3);
if type != "dsc":
del files[file];
- num_files = num_files - 1;
+ num_files -= 1;
continue;
arch = "source";
if Options["debug"]:
os.chdir("%s/dists/proposed-updates" % (Cnf["Dir::Root"]));
for line in file.readlines():
- line = string.rstrip(line)
- if string.find(line, 'install') != -1:
- split_line = string.split(line);
+ line = line.rstrip();
+ if line.find('install') != -1:
+ split_line = line.split();
if len(split_line) != 2:
utils.fubar("Parse error (not exactly 2 elements): %s" % (line));
install_type = split_line[0];
init_pu();
for file in arguments:
- if file[-8:] == ".changes":
+ if file.endswith(".changes"):
check_changes(file);
- elif file[-5:] == ".joey":
+ elif file.endswith(".joey"):
check_joey(file);
else:
utils.fubar("Unrecognised file type: '%s'." % (file));
# Manipulate suite tags
# Copyright (C) 2000, 2001, 2002 James Troup <james@nocrew.org>
-# $Id: heidi,v 1.14 2002-05-14 15:29:18 troup Exp $
+# $Id: heidi,v 1.15 2002-10-16 02:47:32 troup Exp $
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
#######################################################################################
-import pg, string, sys;
+import pg, sys;
import apt_pkg;
import utils, db_access, logging;
q = projectB.query("SELECT b.package, b.version, a.arch_string, ba.id FROM binaries b, bin_associations ba, architecture a WHERE ba.suite = %s AND ba.bin = b.id AND b.architecture = a.id" % (suite_id));
ql = q.getresult();
for i in ql:
- key = string.join(i[:3]);
+ key = " ".join(i[:3]);
current[key] = i[3];
q = projectB.query("SELECT s.source, s.version, sa.id FROM source s, src_associations sa WHERE sa.suite = %s AND sa.source = s.id" % (suite_id));
ql = q.getresult();
for i in ql:
- key = string.join(i[:2]) + " source";
+ key = " ".join(i[:2]) + " source";
current[key] = i[2];
# Build up a dictionary of what should be in the suite
desired = {};
for line in lines:
- split_line = string.split(string.strip(line[:-1]));
+ split_line = line[:-1].strip().split();
if len(split_line) != 3:
utils.warn("'%s' does not break into 'package version architecture'." % (line[:-1]));
continue;
- key = string.join(split_line);
+ key = " ".join(split_line);
desired[key] = "";
# Check to see which packages need removed and remove them
for key in current.keys():
if not desired.has_key(key):
- (package, version, architecture) = string.split(key);
+ (package, version, architecture) = key.split();
id = current[key];
if architecture == "source":
q = projectB.query("DELETE FROM src_associations WHERE id = %s" % (id));
# Check to see which packages need added and add them
for key in desired.keys():
if not current.has_key(key):
- (package, version, architecture) = string.split(key);
+ (package, version, architecture) = key.split();
id = get_id (package, version, architecture);
if not id:
continue;
projectB.query("BEGIN WORK");
for line in lines:
- split_line = string.split(string.strip(line[:-1]));
+ split_line = line[:-1].strip().split();
if len(split_line) != 3:
utils.warn("'%s' does not break into 'package version architecture'." % (line[:-1]));
continue;
q = projectB.query("SELECT b.package, b.version, a.arch_string FROM binaries b, bin_associations ba, architecture a WHERE ba.suite = %s AND ba.bin = b.id AND b.architecture = a.id" % (suite_id));
ql = q.getresult();
for i in ql:
- print string.join(i);
+ print " ".join(i);
# List source
q = projectB.query("SELECT s.source, s.version FROM source s, src_associations sa WHERE sa.suite = %s AND sa.source = s.id" % (suite_id));
ql = q.getresult();
for i in ql:
- print string.join(i) + " source";
+ print " ".join(i) + " source";
#######################################################################################
# Produces a report on NEW and BYHAND packages
# Copyright (C) 2001, 2002 James Troup <james@nocrew.org>
-# $Id: helena,v 1.1 2002-06-05 00:17:22 troup Exp $
+# $Id: helena,v 1.2 2002-10-16 02:47:32 troup Exp $
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
################################################################################
-import copy, glob, os, stat, string, sys, time;
+import copy, glob, os, stat, sys, time;
import apt_pkg;
import katie, utils;
if x < 60:
unit="second";
elif x < 3600:
- x = x / 60;
+ x /= 60;
unit="minute";
elif x < 86400:
- x = x / 3600;
+ x /= 3600;
unit="hour";
elif x < 604800:
- x = x / 86400;
+ x /= 86400;
unit="day";
elif x < 2419200:
- x = x / 604800;
+ x /= 604800;
unit="week";
elif x < 29030400:
- x = x / 2419200;
+ x /= 2419200;
unit="month";
else:
- x = x / 29030400;
+ x /= 29030400;
unit="years";
x = int(x);
return "%s %s%s" % (x, unit, plural(x));
ctime = os.stat(d["filename"])[stat.ST_CTIME];
if ctime < oldest:
oldest = ctime;
- have_note = have_note + (d.has_key("lisa note"));
+ have_note += (d.has_key("lisa note"));
per_source[source]["oldest"] = oldest;
if not have_note:
per_source[source]["note_state"] = 0; # none
for arch in j["architecture"].keys():
arches[arch] = "";
versions[j["version"]] = "";
- arch_list = string.join(arches.keys(), ", ");
- version_list = string.join(versions.keys(), ", ");
+ arch_list = ", ".join(arches.keys());
+ version_list = ", ".join(versions.keys());
if i[1]["note_state"]:
note = " | [note]";
else:
note = "";
- msg = msg + "%10s | %10s | %10s%s | %s old\n" % (source, version_list, arch_list, note, time_pp(last_modified));
+ msg += "%10s | %10s | %10s%s | %s old\n" % (source, version_list, arch_list, note, time_pp(last_modified));
if msg:
total_count = len(changes_files);
source_count = len(per_source_items);
- print string.upper(type)
- print "-"*len(type)
+ print type.upper();
+ print "-"*len(type);
print
- print msg
+ print msg;
print "%s %s source package%s / %s %s package%s in total." % (source_count, type, plural(source_count), total_count, type, plural(total_count));
print
# Generate file lists used by apt-ftparchive to generate Packages and Sources files
# Copyright (C) 2000, 2001, 2002 James Troup <james@nocrew.org>
-# $Id: jenna,v 1.20 2002-07-14 15:02:07 troup Exp $
+# $Id: jenna,v 1.21 2002-10-16 02:47:32 troup Exp $
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# Check to see if we have arch: all and arch: !all (ignoring source)
num_arches = len(arches.keys());
if arches.has_key("source"):
- num_arches = num_arches - 1;
+ num_arches -= 1;
# If we do, remove the duplicates
if num_arches > 1:
versions = [];
if not Options["Suite"]:
suites = Cnf.SubTree("Suite").List();
else:
- suites = string.split(Options["Suite"]);
+ suites = Options["Suite"].split();
for suite in map(string.lower, suites):
if not d.has_key(suite):
d[suite] = {};
if not Options["Component"]:
components = Cnf.ValueList("Suite::%s::Components" % (suite));
else:
- components = string.split(Options["Components"]);
+ components = Options["Components"].split();
udeb_components = Cnf.ValueList("Suite::%s::UdebComponents" % (suite));
udeb_components = udeb_components;
for component in components:
if not Options["Architecture"]:
architectures = Cnf.ValueList("Suite::%s::Architectures" % (suite));
else:
- architectures = string.split(Options["Architectures"]);
+ architectures = Options["Architectures"].split();
for arch in map(string.lower, architectures):
if not d[suite][component].has_key(arch):
d[suite][component][arch] = {};
if not Options["Suite"]:
return 1;
# Otherwise, look in what suites the user specified
- suites = string.split(Options["Suite"]);
+ suites = Options["Suite"].split();
return suites.count("stable");
################################################################################
AND f.location = l.id AND l.component = c.id AND ba.suite = su.id
%s %s %s""" % (con_suites, con_architectures, con_components);
if check_source:
- query = query + """
+ query += """
UNION
SELECT s.id, s.source, 'source', s.version, l.path, f.filename, c.name, f.id,
su.suite_name, 'dsc'
for i in ql:
(id, pkg, arch, version, path, filename, component, file_id, suite, type) = i;
# 'id' comes from either 'binaries' or 'source', so it's not unique
- unique_id = unique_id + 1;
+ unique_id += 1;
packages[unique_id] = Dict(id=id, pkg=pkg, arch=arch, version=version,
path=path, filename=filename,
component=component, file_id=file_id,
# Checks Debian packages from Incoming
# Copyright (C) 2000, 2001, 2002 James Troup <james@nocrew.org>
-# $Id: jennifer,v 1.26 2002-07-14 18:19:25 troup Exp $
+# $Id: jennifer,v 1.27 2002-10-16 02:47:32 troup Exp $
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
################################################################################
-import FCNTL, errno, fcntl, gzip, os, re, select, shutil, stat, string, sys, time, traceback;
+import FCNTL, errno, fcntl, gzip, os, re, select, shutil, stat, sys, time, traceback;
import apt_inst, apt_pkg;
import db_access, katie, logging, utils;
################################################################################
# Globals
-jennifer_version = "$Revision: 1.26 $";
+jennifer_version = "$Revision: 1.27 $";
Cnf = None;
Options = None;
if len(r) > 0:
more_data.append(fd);
if fd == c2pwrite or fd == errin:
- output = output + r;
+ output += r;
elif fd == status_read:
- status = status + r;
+ status += r;
else:
utils.fubar("Unexpected file descriptor [%s] returned from select\n" % (fd));
if not more_data:
def reject (str, prefix="Rejected: "):
global reject_message;
if str:
- reject_message = reject_message + prefix + str + "\n";
+ reject_message += prefix + str + "\n";
#########################################################################################
# Process the status-fd output
keywords = {};
bad = internal_error = "";
- for line in string.split(status, '\n'):
- line = string.strip(line);
+ for line in status.split('\n'):
+ line = line.strip();
if line == "":
continue;
- split = string.split(line);
+ split = line.split();
if len(split) < 2:
- internal_error = internal_error + "gpgv status line is malformed (< 2 atoms) ['%s'].\n" % (line);
+ internal_error += "gpgv status line is malformed (< 2 atoms) ['%s'].\n" % (line);
continue;
(gnupg, keyword) = split[:2];
if gnupg != "[GNUPG:]":
- internal_error = internal_error + "gpgv status line is malformed (incorrect prefix '%s').\n" % (gnupg);
+ internal_error += "gpgv status line is malformed (incorrect prefix '%s').\n" % (gnupg);
continue;
args = split[2:];
if keywords.has_key(keyword) and keyword != "NODATA":
- internal_error = internal_error + "found duplicate status token ('%s').\n" % (keyword);
+ internal_error += "found duplicate status token ('%s').\n" % (keyword);
continue;
else:
keywords[keyword] = args;
# Next check gpgv exited with a zero return code
if exit_status:
reject("gpgv failed while checking %s." % (filename));
- if string.strip(status):
+ if status.strip():
reject(utils.prefix_multi_line_string(status, " [GPG status-fd output:] "), "");
else:
reject(utils.prefix_multi_line_string(output, " [GPG output:] "), "");
for keyword in keywords.keys():
if not known_keywords.has_key(keyword):
- reject("found unknown status token '%s' from gpgv with args '%s' in %s." % (keyword, repr(keywords[keyword]), filename));
+ reject("found unknown status token '%s' from gpgv with args '%r' in %s." % (keyword, keywords[keyword], filename));
bad = 1;
if bad:
raise;
in_holding[base_filename] = "";
- return dest;
################################################################################
os.chdir(Cnf["Dir::Queue::Holding"]);
for file in in_holding.keys():
if os.path.exists(file):
- if string.find(file, '/') != -1:
+ if file.find(file, '/') != -1:
utils.fubar("WTF? clean_holding() got a file ('%s') with / in it!" % (file));
else:
os.unlink(file);
if o != "":
del changes[i]
changes[i] = {}
- for j in string.split(o):
+ for j in o.split():
changes[i][j] = 1
# Fix the Maintainer: field to be RFC822 compatible
# Handle suite mappings
for map in Cnf.ValueList("SuiteMappings"):
- args = string.split(map);
+ args = map.split();
type = args[0];
if type == "map" or type == "silent-map":
(source, dest) = args[1:3];
files[file]["architecture"] = architecture;
files[file]["version"] = version;
files[file]["maintainer"] = control.Find("Maintainer", "");
- if file[-5:] == ".udeb":
+ if file.endswith(".udeb"):
files[file]["dbtype"] = "udeb";
- elif file[-4:] == ".deb":
+ elif file.endswith(".deb"):
files[file]["dbtype"] = "deb";
else:
reject("%s is neither a .deb or a .udeb." % (file));
# Get the source version
source = files[file]["source"];
source_version = ""
- if string.find(source, "(") != -1:
+ if source.find("(") != -1:
m = utils.re_extract_src_version.match(source)
source = m.group(1)
source_version = m.group(2)
# Handle component mappings
for map in Cnf.ValueList("ComponentMappings"):
- (source, dest) = string.split(map);
+ (source, dest) = map.split();
if files[file]["component"] == source:
files[file]["original component"] = source;
files[file]["component"] = dest;
continue;
# Validate the priority
- if string.find(files[file]["priority"],'/') != -1:
+ if files[file]["priority"].find('/') != -1:
reject("file '%s' has invalid priority '%s' [contains '/']." % (file, files[file]["priority"]));
# Determine the location
if changes["urgency"] not in Cnf.ValueList("Urgency::Valid"):
reject("%s is not a valid urgency; it will be treated as %s by testing." % (changes["urgency"], Cnf["Urgency::Default"]), "Warning: ");
changes["urgency"] = Cnf["Urgency::Default"];
- changes["urgency"] = string.lower(changes["urgency"]);
+ changes["urgency"] = changes["urgency"].lower();
################################################################################
if Options["No-Action"] or Options["Automatic"]:
answer = 'S'
- if string.find(reject_message, "Rejected") != -1:
+ if reject_message.find("Rejected") != -1:
if upload_too_new():
print "SKIP (too new)\n" + reject_message,;
prompt = "[S]kip, Quit ?";
if Options["Automatic"]:
answer = 'R';
elif new:
- print "NEW to %s\n%s%s" % (string.join(changes["distribution"].keys(), ", "), reject_message, summary),;
+ print "NEW to %s\n%s%s" % (", ".join(changes["distribution"].keys()), reject_message, summary),;
prompt = "[N]ew, Skip, Quit ?";
if Options["Automatic"]:
answer = 'N';
if Options["Automatic"]:
answer = 'A';
- while string.find(prompt, answer) == -1:
+ while prompt.find(answer) == -1:
answer = utils.our_raw_input(prompt);
m = katie.re_default_answer.match(prompt);
if answer == "":
answer = m.group(1);
- answer = string.upper(answer[:1]);
+ answer = answer[:1].upper();
if answer == 'R':
os.chdir (pkg.directory);
# Ensure all the arguments we were given are .changes files
for file in changes_files:
- if file[-8:] != ".changes":
+ if not file.endswith(".changes"):
utils.warn("Ignoring '%s' because it's not a .changes file." % (file));
changes_files.remove(file);
# Dependency check proposed-updates
# Copyright (C) 2001, 2002 James Troup <james@nocrew.org>
-# $Id: jeri,v 1.9 2002-06-08 00:17:59 troup Exp $
+# $Id: jeri,v 1.10 2002-10-16 02:47:32 troup Exp $
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
################################################################################
-import pg, sys, os, string
+import pg, sys, os;
import utils, db_access
import apt_pkg, apt_inst;
else:
pp_dep = pkg;
pp_deps.append(pp_dep);
- return string.join(pp_deps, " |");
+ return " |".join(pp_deps);
################################################################################
error = "%s not found. [Real: " % (pp_dep(parsed_dep))
if stable.has_key(dep):
if stable[dep].has_key(arch):
- error = error + "%s:%s:%s" % (dep, arch, stable[dep][arch]);
+ error += "%s:%s:%s" % (dep, arch, stable[dep][arch]);
else:
- error = error + "%s:-:-" % (dep);
+ error += "%s:-:-" % (dep);
else:
- error = error + "-:-:-";
- error = error + ", Virtual: ";
+ error += "-:-:-";
+ error += ", Virtual: ";
if stable_virtual.has_key(dep):
if stable_virtual[dep].has_key(arch):
- error = error + "%s:%s" % (dep, arch);
+ error += "%s:%s" % (dep, arch);
else:
- error = error + "%s:-";
+ error += "%s:-";
else:
- error = error + "-:-";
- error = error + ", Upload: ";
+ error += "-:-";
+ error += ", Upload: ";
if files.has_key(dep_filename):
- error = error + "yes";
+ error += "yes";
else:
- error = error + "no";
- error = error + "]";
+ error += "no";
+ error += "]";
unsat.append(error);
if unsat:
pkg_unsat = 0;
if Pre_Depends:
- pkg_unsat = pkg_unsat + check_dep(Pre_Depends, "pre-dependency", check_archs, base_file, files);
+ pkg_unsat += check_dep(Pre_Depends, "pre-dependency", check_archs, base_file, files);
if Depends:
- pkg_unsat = pkg_unsat + check_dep(Depends, "dependency", check_archs, base_file, files);
+ pkg_unsat += check_dep(Depends, "dependency", check_archs, base_file, files);
#if Recommends:
- #pkg_unsat = pkg_unsat + check_dep(Recommends, "recommendation", check_archs, base_file, files);
+ #pkg_unsat += check_dep(Recommends, "recommendation", check_archs, base_file, files);
return pkg_unsat;
changes_result = 0;
for file in files.keys():
- if file[-4:] == ".deb":
+ if file.endswith(".deb"):
result = check_package(file, files);
if Options["verbose"]:
pass_fail(file, result);
- changes_result = changes_result + result;
+ changes_result += result;
pass_fail (filename, changes_result);
os.chdir("%s/dists/proposed-updates" % (Cnf["Dir::Root"]));
for line in file.readlines():
- line = string.rstrip(line);
- if string.find(line, 'install') != -1:
- split_line = string.split(line);
+ line = line.rstrip();
+ if line.find('install') != -1:
+ split_line = line.split();
if len(split_line) != 2:
utils.fubar("Parse error (not exactly 2 elements): %s" % (line));
install_type = split_line[0];
stable[package] = {};
stable[package][architecture] = version;
if provides:
- for virtual_pkg in string.split(provides,","):
- virtual_pkg = string.strip(virtual_pkg);
+ for virtual_pkg in provides.split(","):
+ virtual_pkg = virtual_pkg.strip();
if not stable_virtual.has_key(virtual_pkg):
stable_virtual[virtual_pkg] = {};
stable_virtual[virtual_pkg][architecture] = "NA";
print "done.";
for file in arguments:
- if file[-8:] == ".changes":
+ if file.endswith(".changes"):
check_changes(file);
- elif file[-4:] == ".deb":
+ elif file.endswith(".deb"):
check_deb(file);
- elif file[-5:] == ".joey":
+ elif file.endswith(".joey"):
check_joey(file);
else:
utils.fubar("Unrecognised file type: '%s'." % (file));
# Sync PostgreSQL users with system users
# Copyright (C) 2001, 2002 James Troup <james@nocrew.org>
-# $Id: julia,v 1.7 2002-08-14 00:40:19 troup Exp $
+# $Id: julia,v 1.8 2002-10-16 02:47:32 troup Exp $
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
################################################################################
-import pg, pwd, string, sys;
+import pg, pwd, sys;
import utils;
import apt_pkg;
postgres_unames[uname] = "";
known_postgres_unames = {};
- for i in string.split(Cnf.get("Julia::KnownPostgres",""),","):
- uname = string.strip(i);
+ for i in Cnf.get("Julia::KnownPostgres","").split(","):
+ uname = i.strip();
known_postgres_unames[uname] = "";
keys = postgres_unames.keys()
+++ /dev/null
-#!/usr/bin/env python
-
-# Installs Debian packages
-# Copyright (C) 2000, 2001, 2002 James Troup <james@nocrew.org>
-# $Id: katie,v 1.85 2002-08-07 17:19:25 troup Exp $
-
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-# Originally based on dinstall by Guy Maor <maor@debian.org>
-
-###############################################################################
-
-# Cartman: "I'm trying to make the best of a bad situation, I don't
-# need to hear crap from a bunch of hippy freaks living in
-# denial. Screw you guys, I'm going home."
-#
-# Kyle: "But Cartman, we're trying to..."
-#
-# Cartman: "uhh.. screw you guys... home."
-
-###############################################################################
-
-import FCNTL, fcntl, os, string, sys, time;
-import apt_pkg;
-import db_access, katie, logging, utils;
-
-###############################################################################
-
-# Globals
-katie_version = "$Revision: 1.85 $";
-
-Cnf = None;
-Options = None;
-Logger = None;
-Urgency_Logger = None;
-projectB = None;
-Katie = None;
-pkg = None;
-
-reject_message = "";
-changes = None;
-dsc = None;
-dsc_files = None;
-files = None;
-Subst = None;
-
-install_count = 0;
-install_bytes = 0.0;
-
-installing_to_stable = 0;
-
-###############################################################################
-
-# FIXME: this should go away to some Debian specific file
-# FIXME: should die if file already exists
-
-class Urgency_Log:
- "Urgency Logger object"
- def __init__ (self, Cnf):
- "Initialize a new Urgency Logger object"
- self.Cnf = Cnf;
- self.timestamp = time.strftime("%Y%m%d%H%M%S", time.localtime(time.time()));
- # Create the log directory if it doesn't exist
- self.log_dir = Cnf["Dir::UrgencyLog"];
- if not os.path.exists(self.log_dir):
- umask = os.umask(00000);
- os.makedirs(self.log_dir, 02775);
- # Open the logfile
- self.log_filename = "%s/.install-urgencies-%s.new" % (self.log_dir, self.timestamp);
- self.log_file = utils.open_file(self.log_filename, 'w');
- self.writes = 0;
-
- def log (self, source, version, urgency):
- "Log an event"
- self.log_file.write(string.join([source, version, urgency])+'\n');
- self.log_file.flush();
- self.writes = self.writes + 1;
-
- def close (self):
- "Close a Logger object"
- self.log_file.flush();
- self.log_file.close();
- if self.writes:
- new_filename = "%s/install-urgencies-%s" % (self.log_dir, self.timestamp);
- utils.move(self.log_filename, new_filename);
- else:
- os.unlink(self.log_filename);
-
-###############################################################################
-
-def reject (str, prefix="Rejected: "):
- global reject_message;
- if str:
- reject_message = reject_message + prefix + str + "\n";
-
-# Recheck anything that relies on the database; since that's not
-# frozen between accept and katie's run time.
-
-def check():
- for file in files.keys():
- # Check that the source still exists
- if files[file]["type"] == "deb":
- source_version = files[file]["source version"];
- source_package = files[file]["source package"];
- if not changes["architecture"].has_key("source") \
- and not Katie.source_exists(source_package, source_version):
- reject("no source found for %s %s (%s)." % (source_package, source_version, file));
-
- # Version and file overwrite checks
- if not installing_to_stable:
- if files[file]["type"] == "deb":
- reject(Katie.check_binary_against_db(file));
- elif files[file]["type"] == "dsc":
- reject(Katie.check_source_against_db(file));
- (reject_msg, is_in_incoming) = Katie.check_dsc_against_db(file);
- reject(reject_msg);
-
- # Check the package is still in the override tables
- for suite in changes["distribution"].keys():
- if not Katie.in_override_p(files[file]["package"], files[file]["component"], suite, files[file].get("dbtype",""), file):
- reject("%s is NEW for %s." % (file, suite));
-
-###############################################################################
-
-def init():
- global Cnf, Options, Katie, projectB, changes, dsc, dsc_files, files, pkg, Subst;
-
- Cnf = utils.get_conf()
-
- Arguments = [('a',"automatic","Dinstall::Options::Automatic"),
- ('h',"help","Dinstall::Options::Help"),
- ('m',"manual-reject","Dinstall::Options::Manual-Reject", "HasArg"),
- ('n',"no-action","Dinstall::Options::No-Action"),
- ('p',"no-lock", "Dinstall::Options::No-Lock"),
- ('s',"no-mail", "Dinstall::Options::No-Mail"),
- ('V',"version","Dinstall::Options::Version")];
-
- for i in ["automatic", "help", "manual-reject", "no-action",
- "no-lock", "no-mail", "version"]:
- if not Cnf.has_key("Dinstall::Options::%s" % (i)):
- Cnf["Dinstall::Options::%s" % (i)] = "";
-
- changes_files = apt_pkg.ParseCommandLine(Cnf,Arguments,sys.argv);
- Options = Cnf.SubTree("Dinstall::Options")
-
- Katie = katie.Katie(Cnf);
- projectB = Katie.projectB;
-
- changes = Katie.pkg.changes;
- dsc = Katie.pkg.dsc;
- dsc_files = Katie.pkg.dsc_files;
- files = Katie.pkg.files;
- pkg = Katie.pkg;
- Subst = Katie.Subst;
-
- return changes_files;
-
-###############################################################################
-
-def usage (exit_code=0):
- print """Usage: dinstall [OPTION]... [CHANGES]...
- -a, --automatic automatic run
- -h, --help show this help and exit.
- -n, --no-action don't do anything
- -p, --no-lock don't check lockfile !! for cron.daily only !!
- -s, --no-mail don't send any mail
- -V, --version display the version number and exit"""
- sys.exit(exit_code)
-
-###############################################################################
-
-def action ():
- (summary, short_summary) = Katie.build_summaries();
-
- (prompt, answer) = ("", "XXX")
- if Options["No-Action"] or Options["Automatic"]:
- answer = 'S'
-
- if string.find(reject_message, "Rejected") != -1:
- print "REJECT\n" + reject_message,;
- prompt = "[R]eject, Skip, Quit ?";
- if Options["Automatic"]:
- answer = 'R';
- else:
- print "INSTALL\n" + reject_message + summary,;
- prompt = "[I]nstall, Skip, Quit ?";
- if Options["Automatic"]:
- answer = 'I';
-
- while string.find(prompt, answer) == -1:
- answer = utils.our_raw_input(prompt);
- m = katie.re_default_answer.match(prompt);
- if answer == "":
- answer = m.group(1);
- answer = string.upper(answer[:1]);
-
- if answer == 'R':
- do_reject ();
- elif answer == 'I':
- if not installing_to_stable:
- install();
- else:
- stable_install(summary, short_summary);
- elif answer == 'Q':
- sys.exit(0)
-
-###############################################################################
-
-# Our reject is not really a reject, but an unaccept, but since a) the
-# code for that is non-trivial (reopen bugs, unannounce etc.), b) this
-# should be exteremly rare, for now we'll go with whining at our admin
-# folks...
-
-def do_reject ():
- Subst["__REJECTOR_ADDRESS__"] = Cnf["Dinstall::MyEmailAddress"];
- Subst["__REJECT_MESSAGE__"] = reject_message;
- Subst["__CC__"] = "Cc: " + Cnf["Dinstall::MyEmailAddress"];
- reject_mail_message = utils.TemplateSubst(Subst,Cnf["Dir::Templates"]+"/katie.unaccept");
-
- # Write the rejection email out as the <foo>.reason file
- reason_filename = os.path.basename(pkg.changes_file[:-8]) + ".reason";
- reject_filename = Cnf["Dir::Queue::Reject"] + '/' + reason_filename;
- # If we fail here someone is probably trying to exploit the race
- # so let's just raise an exception ...
- if os.path.exists(reject_filename):
- os.unlink(reject_filename);
- fd = os.open(reject_filename, os.O_RDWR|os.O_CREAT|os.O_EXCL, 0644);
- os.write(fd, reject_mail_message);
- os.close(fd);
-
- utils.send_mail (reject_mail_message, "");
- Logger.log(["unaccepted", pkg.changes_file]);
-
-###############################################################################
-
-def install ():
- global install_count, install_bytes;
-
- print "Installing."
-
- Logger.log(["installing changes",pkg.changes_file]);
-
- # Begin a transaction; if we bomb out anywhere between here and the COMMIT WORK below, the DB will not be changed.
- projectB.query("BEGIN WORK");
-
- # Add the .dsc file to the DB
- for file in files.keys():
- if files[file]["type"] == "dsc":
- package = dsc["source"]
- version = dsc["version"] # NB: not files[file]["version"], that has no epoch
- maintainer = dsc["maintainer"]
- maintainer = string.replace(maintainer, "'", "\\'")
- maintainer_id = db_access.get_or_set_maintainer_id(maintainer);
- fingerprint_id = db_access.get_or_set_fingerprint_id(dsc["fingerprint"]);
- install_date = time.strftime("%Y-%m-%d", time.localtime(time.time()));
- filename = files[file]["pool name"] + file;
- dsc_location_id = files[file]["location id"];
- if not files[file].has_key("files id") or not files[file]["files id"]:
- files[file]["files id"] = db_access.set_files_id (filename, files[file]["size"], files[file]["md5sum"], dsc_location_id)
- projectB.query("INSERT INTO source (source, version, maintainer, file, install_date, sig_fpr) VALUES ('%s', '%s', %d, %d, '%s', %s)"
- % (package, version, maintainer_id, files[file]["files id"], install_date, fingerprint_id));
-
- for suite in changes["distribution"].keys():
- suite_id = db_access.get_suite_id(suite);
- projectB.query("INSERT INTO src_associations (suite, source) VALUES (%d, currval('source_id_seq'))" % (suite_id))
-
- # Add the source files to the DB (files and dsc_files)
- projectB.query("INSERT INTO dsc_files (source, file) VALUES (currval('source_id_seq'), %d)" % (files[file]["files id"]));
- for dsc_file in dsc_files.keys():
- filename = files[file]["pool name"] + dsc_file;
- # If the .orig.tar.gz is already in the pool, it's
- # files id is stored in dsc_files by check_dsc().
- files_id = dsc_files[dsc_file].get("files id", None);
- if files_id == None:
- files_id = db_access.get_files_id(filename, dsc_files[dsc_file]["size"], dsc_files[dsc_file]["md5sum"], dsc_location_id);
- # FIXME: needs to check for -1/-2 and or handle exception
- if files_id == None:
- files_id = db_access.set_files_id (filename, dsc_files[dsc_file]["size"], dsc_files[dsc_file]["md5sum"], dsc_location_id);
- projectB.query("INSERT INTO dsc_files (source, file) VALUES (currval('source_id_seq'), %d)" % (files_id));
-
- # Add the .deb files to the DB
- for file in files.keys():
- if files[file]["type"] == "deb":
- package = files[file]["package"]
- version = files[file]["version"]
- maintainer = files[file]["maintainer"]
- maintainer = string.replace(maintainer, "'", "\\'")
- maintainer_id = db_access.get_or_set_maintainer_id(maintainer);
- fingerprint_id = db_access.get_or_set_fingerprint_id(changes["fingerprint"]);
- architecture = files[file]["architecture"]
- architecture_id = db_access.get_architecture_id (architecture);
- type = files[file]["dbtype"];
- dsc_component = files[file]["component"]
- source = files[file]["source package"]
- source_version = files[file]["source version"];
- filename = files[file]["pool name"] + file;
- if not files[file].has_key("location id") or not files[file]["location id"]:
- files[file]["location id"] = db_access.get_location_id(Cnf["Dir::Pool"],files[file]["component"],utils.where_am_i());
- if not files[file].has_key("files id") or not files[file]["files id"]:
- files[file]["files id"] = db_access.set_files_id (filename, files[file]["size"], files[file]["md5sum"], files[file]["location id"])
- source_id = db_access.get_source_id (source, source_version);
- if source_id:
- projectB.query("INSERT INTO binaries (package, version, maintainer, source, architecture, file, type, sig_fpr) VALUES ('%s', '%s', %d, %d, %d, %d, '%s', %d)"
- % (package, version, maintainer_id, source_id, architecture_id, files[file]["files id"], type, fingerprint_id));
- else:
- projectB.query("INSERT INTO binaries (package, version, maintainer, architecture, file, type, sig_fpr) VALUES ('%s', '%s', %d, %d, %d, '%s', %d)"
- % (package, version, maintainer_id, architecture_id, files[file]["files id"], type, fingerprint_id));
- for suite in changes["distribution"].keys():
- suite_id = db_access.get_suite_id(suite);
- projectB.query("INSERT INTO bin_associations (suite, bin) VALUES (%d, currval('binaries_id_seq'))" % (suite_id));
-
- # If the .orig.tar.gz is in a legacy directory we need to poolify
- # it, so that apt-get source (and anything else that goes by the
- # "Directory:" field in the Sources.gz file) works.
- orig_tar_id = Katie.pkg.orig_tar_id;
- orig_tar_location = Katie.pkg.orig_tar_location;
- legacy_source_untouchable = Katie.pkg.legacy_source_untouchable;
- if orig_tar_id != None and orig_tar_location == "legacy":
- q = projectB.query("SELECT DISTINCT ON (f.id) l.path, f.filename, f.id as files_id, df.source, df.id as dsc_files_id, f.size, f.md5sum FROM files f, dsc_files df, location l WHERE df.source IN (SELECT source FROM dsc_files WHERE file = %s) AND f.id = df.file AND l.id = f.location AND (l.type = 'legacy' OR l.type = 'legacy-mixed')" % (orig_tar_id));
- qd = q.dictresult();
- for qid in qd:
- # Is this an old upload superseded by a newer -sa upload? (See check_dsc() for details)
- if legacy_source_untouchable.has_key(qid["files_id"]):
- continue;
- # First move the files to the new location
- legacy_filename = qid["path"]+qid["filename"];
- pool_location = utils.poolify (changes["source"], files[file]["component"]);
- pool_filename = pool_location + os.path.basename(qid["filename"]);
- destination = Cnf["Dir::Pool"] + pool_location
- utils.move(legacy_filename, destination);
- # Then Update the DB's files table
- q = projectB.query("UPDATE files SET filename = '%s', location = '%s' WHERE id = '%s'" % (pool_filename, dsc_location_id, qid["files_id"]));
-
- # If this is a sourceful diff only upload that is moving non-legacy
- # cross-component we need to copy the .orig.tar.gz into the new
- # component too for the same reasons as above.
- #
- if changes["architecture"].has_key("source") and orig_tar_id != None and \
- orig_tar_location != "legacy" and orig_tar_location != dsc_location_id:
- q = projectB.query("SELECT l.path, f.filename, f.size, f.md5sum FROM files f, location l WHERE f.id = %s AND f.location = l.id" % (orig_tar_id));
- ql = q.getresult()[0];
- old_filename = ql[0] + ql[1];
- file_size = ql[2];
- file_md5sum = ql[3];
- new_filename = utils.poolify(changes["source"], dsc_component) + os.path.basename(old_filename);
- new_files_id = db_access.get_files_id(new_filename, file_size, file_md5sum, dsc_location_id);
- if new_files_id == None:
- utils.copy(old_filename, Cnf["Dir::Pool"] + new_filename);
- new_files_id = db_access.set_files_id(new_filename, file_size, file_md5sum, dsc_location_id);
- projectB.query("UPDATE dsc_files SET file = %s WHERE source = %s AND file = %s" % (new_files_id, source_id, orig_tar_id));
-
- # Install the files into the pool
- for file in files.keys():
- destination = Cnf["Dir::Pool"] + files[file]["pool name"] + file;
- utils.move(file, destination);
- Logger.log(["installed", file, files[file]["type"], files[file]["size"], files[file]["architecture"]]);
- install_bytes = install_bytes + float(files[file]["size"]);
-
- # Copy the .changes file across for suite which need it.
- copy_changes_p = copy_katie_p = 0;
- for suite in changes["distribution"].keys():
- if Cnf.has_key("Suite::%s::CopyChanges" % (suite)):
- copy_changes_p = 1;
- # and the .katie file...
- if Cnf.has_key("Suite::%s::CopyKatie" % (suite)):
- copy_katie_p = 1;
- if copy_changes_p:
- utils.copy(pkg.changes_file, Cnf["Dir::Root"] + Cnf["Suite::%s::CopyChanges" % (suite)]);
- if copy_katie_p:
- utils.copy(Katie.pkg.changes_file[:-8]+".katie", Cnf["Suite::%s::CopyKatie" % (suite)]);
-
- projectB.query("COMMIT WORK");
-
- # Move the .changes into the 'done' directory
- try:
- utils.move (pkg.changes_file, os.path.join(Cnf["Dir::Queue::Done"], os.path.basename(pkg.changes_file)));
- except:
- utils.warn("couldn't move changes file '%s' to DONE directory. [Got %s]" % (os.path.basename(pkg.changes_file), sys.exc_type));
-
- os.unlink(Katie.pkg.changes_file[:-8]+".katie");
-
- if changes["architecture"].has_key("source") and Urgency_Logger:
- Urgency_Logger.log(dsc["source"], dsc["version"], changes["urgency"]);
-
- # Undo the work done in katie.py(accept) to help auto-building
- # from accepted.
- projectB.query("BEGIN WORK");
- for suite in changes["distribution"].keys():
- if suite not in Cnf.ValueList("Dinstall::AcceptedAutoBuildSuites"):
- continue;
- now_date = time.strftime("%Y-%m-%d %H:%M", time.localtime(time.time()));
- suite_id = db_access.get_suite_id(suite);
- dest_dir = Cnf["Dir::AcceptedAutoBuild"];
- if Cnf.FindB("Dinstall::SecurityAcceptedAutoBuild"):
- dest_dir = os.path.join(dest_dir, suite);
- for file in files.keys():
- dest = os.path.join(dest_dir, file);
- # Remove it from the list of packages for later processing by apt-ftparchive
- projectB.query("UPDATE accepted_autobuild SET in_accepted = 'f', last_used = '%s' WHERE filename = '%s' AND suite = %s" % (now_date, dest, suite_id));
- if not Cnf.FindB("Dinstall::SecurityAcceptedAutoBuild"):
- # Update the symlink to point to the new location in the pool
- pool_location = utils.poolify (changes["source"], files[file]["component"]);
- src = os.path.join(Cnf["Dir::Pool"], pool_location, os.path.basename(file));
- if os.path.islink(dest):
- os.unlink(dest);
- os.symlink(src, dest);
- # Update last_used on any non-upload .orig.tar.gz symlink
- if orig_tar_id:
- # Determine the .orig.tar.gz file name
- for dsc_file in dsc_files.keys():
- if dsc_file[-12:] == ".orig.tar.gz":
- orig_tar_gz = os.path.join(dest_dir, dsc_file);
- # Remove it from the list of packages for later processing by apt-ftparchive
- projectB.query("UPDATE accepted_autobuild SET in_accepted = 'f', last_used = '%s' WHERE filename = '%s' AND suite = %s" % (now_date, orig_tar_gz, suite_id));
- projectB.query("COMMIT WORK");
-
- # Finally...
- install_count = install_count + 1;
-
-################################################################################
-
-def stable_install (summary, short_summary):
- global install_count;
-
- print "Installing to stable.";
-
- # Begin a transaction; if we bomb out anywhere between here and the COMMIT WORK below, the DB will not be changed.
- projectB.query("BEGIN WORK");
-
- # Add the source to stable (and remove it from proposed-updates)
- for file in files.keys():
- if files[file]["type"] == "dsc":
- package = dsc["source"];
- version = dsc["version"]; # NB: not files[file]["version"], that has no epoch
- q = projectB.query("SELECT id FROM source WHERE source = '%s' AND version = '%s'" % (package, version))
- ql = q.getresult();
- if not ql:
- utils.fubar("[INTERNAL ERROR] couldn't find '%s' (%s) in source table." % (package, version));
- source_id = ql[0][0];
- suite_id = db_access.get_suite_id('proposed-updates');
- projectB.query("DELETE FROM src_associations WHERE suite = '%s' AND source = '%s'" % (suite_id, source_id));
- suite_id = db_access.get_suite_id('stable');
- projectB.query("INSERT INTO src_associations (suite, source) VALUES ('%s', '%s')" % (suite_id, source_id));
-
- # Add the binaries to stable (and remove it/them from proposed-updates)
- for file in files.keys():
- if files[file]["type"] == "deb":
- package = files[file]["package"];
- version = files[file]["version"];
- architecture = files[file]["architecture"];
- q = projectB.query("SELECT b.id FROM binaries b, architecture a WHERE b.package = '%s' AND b.version = '%s' AND (a.arch_string = '%s' OR a.arch_string = 'all') AND b.architecture = a.id" % (package, version, architecture));
- ql = q.getresult();
- if not ql:
- utils.fubar("[INTERNAL ERROR] couldn't find '%s' (%s for %s architecture) in binaries table." % (package, version, architecture));
- binary_id = ql[0][0];
- suite_id = db_access.get_suite_id('proposed-updates');
- projectB.query("DELETE FROM bin_associations WHERE suite = '%s' AND bin = '%s'" % (suite_id, binary_id));
- suite_id = db_access.get_suite_id('stable');
- projectB.query("INSERT INTO bin_associations (suite, bin) VALUES ('%s', '%s')" % (suite_id, binary_id));
-
- projectB.query("COMMIT WORK");
-
- utils.move (pkg.changes_file, Cnf["Dir::Morgue"] + '/katie/' + os.path.basename(pkg.changes_file));
-
- ## Update the Stable ChangeLog file
- new_changelog_filename = Cnf["Dir::Root"] + Cnf["Suite::Stable::ChangeLogBase"] + ".ChangeLog";
- changelog_filename = Cnf["Dir::Root"] + Cnf["Suite::Stable::ChangeLogBase"] + "ChangeLog";
- if os.path.exists(new_changelog_filename):
- os.unlink (new_changelog_filename);
-
- new_changelog = utils.open_file(new_changelog_filename, 'w');
- for file in files.keys():
- if files[file]["type"] == "deb":
- new_changelog.write("stable/%s/binary-%s/%s\n" % (files[file]["component"], files[file]["architecture"], file));
- elif utils.re_issource.match(file) != None:
- new_changelog.write("stable/%s/source/%s\n" % (files[file]["component"], file));
- else:
- new_changelog.write("%s\n" % (file));
- chop_changes = katie.re_fdnic.sub("\n", changes["changes"]);
- new_changelog.write(chop_changes + '\n\n');
- if os.access(changelog_filename, os.R_OK) != 0:
- changelog = utils.open_file(changelog_filename);
- new_changelog.write(changelog.read());
- new_changelog.close();
- if os.access(changelog_filename, os.R_OK) != 0:
- os.unlink(changelog_filename);
- utils.move(new_changelog_filename, changelog_filename);
-
- install_count = install_count + 1;
-
- if not Options["No-Mail"] and changes["architecture"].has_key("source"):
- Subst["__SUITE__"] = " into stable";
- Subst["__SUMMARY__"] = summary;
- mail_message = utils.TemplateSubst(Subst,Cnf["Dir::Templates"]+"/katie.installed");
- utils.send_mail(mail_message, "");
- Katie.announce(short_summary, 1)
-
- # Finally remove the .katie file
- katie_file = os.path.join(Cnf["Suite::Proposed-Updates::CopyKatie"], os.path.basename(Katie.pkg.changes_file[:-8]+".katie"));
- os.unlink(katie_file);
-
-################################################################################
-
-def process_it (changes_file):
- global reject_message;
-
- reject_message = "";
-
- # Absolutize the filename to avoid the requirement of being in the
- # same directory as the .changes file.
- pkg.changes_file = os.path.abspath(changes_file);
-
- # And since handling of installs to stable munges with the CWD;
- # save and restore it.
- pkg.directory = os.getcwd();
-
- if installing_to_stable:
- old = Katie.pkg.changes_file;
- Katie.pkg.changes_file = os.path.basename(old);
- os.chdir(Cnf["Suite::Proposed-Updates::CopyKatie"]);
-
- Katie.init_vars();
- Katie.update_vars();
- Katie.update_subst();
-
- if installing_to_stable:
- Katie.pkg.changes_file = old;
-
- check();
- action();
-
- # Restore CWD
- os.chdir(pkg.directory);
-
-###############################################################################
-
-def main():
- global projectB, Logger, Urgency_Logger, installing_to_stable;
-
- changes_files = init();
-
- if Options["Help"]:
- usage();
-
- if Options["Version"]:
- print "katie %s" % (katie_version);
- sys.exit(0);
-
- # -n/--dry-run invalidates some other options which would involve things happening
- if Options["No-Action"]:
- Options["Automatic"] = "";
-
- # Check that we aren't going to clash with the daily cron job
-
- if not Options["No-Action"] and os.path.exists("%s/Archive_Maintenance_In_Progress" % (Cnf["Dir::Root"])) and not Options["No-Lock"]:
- utils.fubar("Archive maintenance in progress. Try again later.");
-
- # If running from within proposed-updates; assume an install to stable
- if string.find(os.getcwd(), 'proposed-updates') != -1:
- installing_to_stable = 1;
-
- # Obtain lock if not in no-action mode and initialize the log
- if not Options["No-Action"]:
- lock_fd = os.open(Cnf["Dinstall::LockFile"], os.O_RDWR | os.O_CREAT);
- fcntl.lockf(lock_fd, FCNTL.F_TLOCK);
- Logger = Katie.Logger = logging.Logger(Cnf, "katie");
- if not installing_to_stable and Cnf.get("Dir::UrgencyLog"):
- Urgency_Logger = Urgency_Log(Cnf);
-
- # Initialize the substitution template mapping global
- bcc = "X-Katie: %s" % (katie_version);
- if Cnf.has_key("Dinstall::Bcc"):
- Subst["__BCC__"] = bcc + "\nBcc: %s" % (Cnf["Dinstall::Bcc"]);
- else:
- Subst["__BCC__"] = bcc;
- if Cnf.has_key("Dinstall::StableRejector"):
- Subst["__STABLE_REJECTOR__"] = Cnf["Dinstall::StableRejector"];
-
- # Sort the .changes files so that we process sourceful ones first
- changes_files.sort(utils.changes_compare);
-
- # Process the changes files
- for changes_file in changes_files:
- print "\n" + changes_file;
- process_it (changes_file);
-
- if install_count:
- sets = "set"
- if install_count > 1:
- sets = "sets"
- sys.stderr.write("Installed %d package %s, %s.\n" % (install_count, sets, utils.size_type(int(install_bytes))));
- Logger.log(["total",install_count,install_bytes]);
-
- if not Options["No-Action"]:
- Logger.close();
- if Urgency_Logger:
- Urgency_Logger.close();
-
-###############################################################################
-
-if __name__ == '__main__':
- main();
# Utility functions for katie
# Copyright (C) 2001, 2002 James Troup <james@nocrew.org>
-# $Id: katie.py,v 1.26 2002-08-26 18:07:24 ajt Exp $
+# $Id: katie.py,v 1.27 2002-10-16 02:47:32 troup Exp $
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
import apt_inst, apt_pkg;
from types import *;
-from string import lower;
###############################################################################
filename = Cnf["Dir::Override"] + Cnf["Dinstall::GroupOverrideFilename"];
file = utils.open_file(filename);
for line in file.readlines():
- line = lower(string.strip(utils.re_comments.sub('', line)));
+ line = utils.re_comments.sub('', line).lower().strip();
if line != "":
self.group_maint[line] = 1;
file.close();
changes = pkg.changes;
dsc = pkg.dsc;
- (dsc_rfc822, dsc_name, dsc_email) = utils.fix_maintainer (lower(dsc.get("maintainer",Cnf["Dinstall::MyEmailAddress"])));
+ (dsc_rfc822, dsc_name, dsc_email) = utils.fix_maintainer (dsc.get("maintainer",Cnf["Dinstall::MyEmailAddress"]).lower());
# changes["changedbyname"] == dsc_name is probably never true, but better safe than sorry
- if dsc_name == lower(changes["maintainername"]) and \
- (changes["changedby822"] == "" or lower(changes["changedbyname"]) == dsc_name):
+ if dsc_name == changes["maintainername"].lower() and \
+ (changes["changedby822"] == "" or changes["changedbyname"].lower() == dsc_name):
return 0;
if dsc.has_key("uploaders"):
- uploaders = string.split(lower(dsc["uploaders"]), ",");
+ uploaders = dsc["uploaders"].lower().split(",");
uploadernames = {};
for i in uploaders:
- (rfc822, name, email) = utils.fix_maintainer (string.strip(i));
+ (rfc822, name, email) = utils.fix_maintainer (i.strip());
uploadernames[name] = "";
- if uploadernames.has_key(lower(changes["changedbyname"])):
+ if uploadernames.has_key(changes["changedbyname"].lower()):
return 0;
# Some group maintained packages (e.g. Debian QA) are never NMU's
- if self.group_maint.has_key(lower(changes["maintaineremail"])):
+ if self.group_maint.has_key(changes["maintaineremail"].lower()):
return 0;
return 1;
if not changes.has_key("maintainer822"):
changes["maintainer822"] = self.Cnf["Dinstall::MyEmailAddress"];
- Subst["__ARCHITECTURE__"] = string.join(changes["architecture"].keys(), ' ' );
+ Subst["__ARCHITECTURE__"] = " ".join(changes["architecture"].keys());
Subst["__CHANGES_FILENAME__"] = os.path.basename(self.pkg.changes_file);
Subst["__FILE_CONTENTS__"] = changes.get("filecontents", "");
Subst["__MAINTAINER_TO__"] = changes["maintainer822"];
Subst["__MAINTAINER__"] = changes.get("maintainer", "Unknown");
if self.Cnf.has_key("Dinstall::TrackingServer") and changes.has_key("source"):
- Subst["__MAINTAINER_TO__"] = Subst["__MAINTAINER_TO__"] + "\nBcc: %s@%s" % (changes["source"], self.Cnf["Dinstall::TrackingServer"])
+ Subst["__MAINTAINER_TO__"] += "\nBcc: %s@%s" % (changes["source"], self.Cnf["Dinstall::TrackingServer"])
# Apply any global override of the Maintainer field
if self.Cnf.get("Dinstall::OverrideMaintainer"):
for file in file_keys:
if files[file].has_key("byhand"):
byhand = 1
- summary = summary + file + " byhand\n"
+ summary += file + " byhand\n"
elif files[file].has_key("new"):
new = 1
- summary = summary + "(new) %s %s %s\n" % (file, files[file]["priority"], files[file]["section"])
+ summary += "(new) %s %s %s\n" % (file, files[file]["priority"], files[file]["section"])
if files[file].has_key("othercomponents"):
- summary = summary + "WARNING: Already present in %s distribution.\n" % (files[file]["othercomponents"])
+ summary += "WARNING: Already present in %s distribution.\n" % (files[file]["othercomponents"])
if files[file]["type"] == "deb":
- summary = summary + apt_pkg.ParseSection(apt_inst.debExtractControl(utils.open_file(file)))["Description"] + '\n';
+ summary += apt_pkg.ParseSection(apt_inst.debExtractControl(utils.open_file(file)))["Description"] + '\n';
else:
files[file]["pool name"] = utils.poolify (changes["source"], files[file]["component"])
destination = self.Cnf["Dir::PoolRoot"] + files[file]["pool name"] + file
- summary = summary + file + "\n to " + destination + "\n"
+ summary += file + "\n to " + destination + "\n"
short_summary = summary;
f = re_fdnic.sub("\n .\n", changes.get("changes",""));
if byhand or new:
- summary = summary + "Changes: " + f;
+ summary += "Changes: " + f;
- summary = summary + self.announce(short_summary, 0)
+ summary += self.announce(short_summary, 0)
return (summary, short_summary);
bugs.sort();
if not self.nmu.is_an_nmu(self.pkg):
- summary = summary + "Closing bugs: ";
+ summary += "Closing bugs: ";
for bug in bugs:
- summary = summary + "%s " % (bug);
+ summary += "%s " % (bug);
if action:
Subst["__BUG_NUMBER__"] = bug;
if changes["distribution"].has_key("stable"):
if action:
self.Logger.log(["closing bugs"]+bugs);
else: # NMU
- summary = summary + "Setting bugs to severity fixed: ";
+ summary += "Setting bugs to severity fixed: ";
control_message = "";
for bug in bugs:
- summary = summary + "%s " % (bug);
- control_message = control_message + "tag %s + fixed\n" % (bug);
+ summary += "%s " % (bug);
+ control_message += "tag %s + fixed\n" % (bug);
if action and control_message != "":
Subst["__CONTROL_MESSAGE__"] = control_message;
mail_message = utils.TemplateSubst(Subst,Cnf["Dir::Templates"]+"/jennifer.bug-nmu-fixed");
utils.send_mail (mail_message, "");
if action:
self.Logger.log(["setting bugs to fixed"]+bugs);
- summary = summary + "\n";
+ summary += "\n";
return summary;
###########################################################################
if list == "" or lists_done.has_key(list):
continue;
lists_done[list] = 1;
- summary = summary + "Announcing to %s\n" % (list);
+ summary += "Announcing to %s\n" % (list);
if action:
Subst["__ANNOUNCE_LIST_ADDRESS__"] = list;
file_keys = files.keys();
for file in file_keys:
utils.move(file, Cnf["Dir::Queue::Accepted"]);
- self.accept_bytes = self.accept_bytes + float(files[file]["size"])
- self.accept_count = self.accept_count + 1;
+ self.accept_bytes += float(files[file]["size"])
+ self.accept_count += 1;
# Send accept mail, announce to lists, close bugs and check for
# override disparities
if self.pkg.orig_tar_id:
# Determine the .orig.tar.gz file name
for dsc_file in self.pkg.dsc_files.keys():
- if dsc_file[-12:] == ".orig.tar.gz":
+ if dsc_file.endswith(".orig.tar.gz"):
filename = dsc_file;
dest = os.path.join(dest_dir, filename);
# If it doesn't exist, create a symlink
if not files[file].has_key("new") and files[file]["type"] == "deb":
section = files[file]["section"];
override_section = files[file]["override section"];
- if lower(section) != lower(override_section) and section != "-":
+ if section.lower() != override_section.lower() and section != "-":
# Ignore this; it's a common mistake and not worth whining about
- if lower(section) == "non-us/main" and lower(override_section) == "non-us":
+ if section.lower() == "non-us/main" and override_section.lower() == "non-us":
continue;
- summary = summary + "%s: section is overridden from %s to %s.\n" % (file, section, override_section);
+ summary += "%s: section is overridden from %s to %s.\n" % (file, section, override_section);
priority = files[file]["priority"];
override_priority = files[file]["override priority"];
if priority != override_priority and priority != "-":
- summary = summary + "%s: priority is overridden from %s to %s.\n" % (file, priority, override_priority);
+ summary += "%s: priority is overridden from %s to %s.\n" % (file, priority, override_priority);
if summary == "":
return;
while answer == 'E':
os.system("%s %s" % (editor, temp_filename))
file = utils.open_file(temp_filename);
- reject_message = string.join(file.readlines());
+ reject_message = " ".join(file.readlines());
file.close();
print "Reject message:";
print utils.prefix_multi_line_string(reject_message," ");
prompt = "[R]eject, Edit, Abandon, Quit ?"
answer = "XXX";
- while string.find(prompt, answer) == -1:
+ while prompt.find(answer) == -1:
answer = utils.our_raw_input(prompt);
m = re_default_answer.search(prompt);
if answer == "":
answer = m.group(1);
- answer = string.upper(answer[:1]);
+ answer = answer[:1].upper();
os.unlink(temp_filename);
if answer == 'A':
return 1;
type_id = db_access.get_override_type_id(type);
# FIXME: nasty non-US speficic hack
- if lower(component[:7]) == "non-us/":
+ if component[:7].lower() == "non-us/":
component = component[7:];
q = self.projectB.query("SELECT s.section, p.priority FROM override o, section s, priority p WHERE package = '%s' AND suite = %s AND component = %s AND type = %s AND o.section = s.id AND o.priority = p.id"
# Unlike other rejects we add new lines first to avoid trailing
# new lines when this message is passed back up to a caller.
if self.reject_message:
- self.reject_message = self.reject_message + "\n";
- self.reject_message = self.reject_message + prefix + str;
+ self.reject_message += "\n";
+ self.reject_message += prefix + str;
################################################################################
# Check versions for each target suite
for target_suite in self.pkg.changes["distribution"].keys():
- must_be_newer_than = map(lower, self.Cnf.ValueList("Suite::%s::VersionChecks::MustBeNewerThan" % (target_suite)));
- must_be_older_than = map(lower, self.Cnf.ValueList("Suite::%s::VersionChecks::MustBeOlderThan" % (target_suite)));
+ must_be_newer_than = map(string.lower, self.Cnf.ValueList("Suite::%s::VersionChecks::MustBeNewerThan" % (target_suite)));
+ must_be_older_than = map(string.lower, self.Cnf.ValueList("Suite::%s::VersionChecks::MustBeOlderThan" % (target_suite)));
# Enforce "must be newer than target suite" even if conffile omits it
if target_suite not in must_be_newer_than:
must_be_newer_than.append(target_suite);
if ql:
# Ignore exact matches for .orig.tar.gz
match = 0;
- if dsc_file[-12:] == ".orig.tar.gz":
+ if dsc_file.endswith(".orig.tar.gz"):
for i in ql:
if files.has_key(dsc_file) and \
int(files[dsc_file]["size"]) == int(i[0]) and \
if not match:
self.reject("can not overwrite existing copy of '%s' already in the archive." % (dsc_file));
- elif dsc_file[-12:] == ".orig.tar.gz":
+ elif dsc_file.endswith(".orig.tar.gz"):
# Check in the pool
q = self.projectB.query("SELECT l.path, f.filename, l.type, f.id, l.id FROM files f, location l WHERE (f.filename ~ '/%s$' OR f.filename = '%s') AND l.id = f.location" % (utils.regex_safe(dsc_file), dsc_file));
ql = q.getresult();
--- /dev/null
+#!/usr/bin/env python
+
+# Installs Debian packages
+# Copyright (C) 2000, 2001, 2002 James Troup <james@nocrew.org>
+# $Id: kelly,v 1.1 2002-10-16 02:47:32 troup Exp $
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+# Originally based on dinstall by Guy Maor <maor@debian.org>
+
+###############################################################################
+
+# Cartman: "I'm trying to make the best of a bad situation, I don't
+# need to hear crap from a bunch of hippy freaks living in
+# denial. Screw you guys, I'm going home."
+#
+# Kyle: "But Cartman, we're trying to..."
+#
+# Cartman: "uhh.. screw you guys... home."
+
+###############################################################################
+
+import FCNTL, fcntl, os, sys, time;
+import apt_pkg;
+import db_access, katie, logging, utils;
+
+###############################################################################
+
+# Globals
+kelly_version = "$Revision: 1.1 $";
+
+Cnf = None;
+Options = None;
+Logger = None;
+Urgency_Logger = None;
+projectB = None;
+Katie = None;
+pkg = None;
+
+reject_message = "";
+changes = None;
+dsc = None;
+dsc_files = None;
+files = None;
+Subst = None;
+
+install_count = 0;
+install_bytes = 0.0;
+
+installing_to_stable = 0;
+
+###############################################################################
+
+# FIXME: this should go away to some Debian specific file
+# FIXME: should die if file already exists
+
+class Urgency_Log:
+ "Urgency Logger object"
+ def __init__ (self, Cnf):
+ "Initialize a new Urgency Logger object"
+ self.Cnf = Cnf;
+ self.timestamp = time.strftime("%Y%m%d%H%M%S");
+ # Create the log directory if it doesn't exist
+ self.log_dir = Cnf["Dir::UrgencyLog"];
+ if not os.path.exists(self.log_dir):
+ umask = os.umask(00000);
+ os.makedirs(self.log_dir, 02775);
+ # Open the logfile
+ self.log_filename = "%s/.install-urgencies-%s.new" % (self.log_dir, self.timestamp);
+ self.log_file = utils.open_file(self.log_filename, 'w');
+ self.writes = 0;
+
+ def log (self, source, version, urgency):
+ "Log an event"
+ self.log_file.write(" ".join([source, version, urgency])+'\n');
+ self.log_file.flush();
+ self.writes += 1;
+
+ def close (self):
+ "Close a Logger object"
+ self.log_file.flush();
+ self.log_file.close();
+ if self.writes:
+ new_filename = "%s/install-urgencies-%s" % (self.log_dir, self.timestamp);
+ utils.move(self.log_filename, new_filename);
+ else:
+ os.unlink(self.log_filename);
+
+###############################################################################
+
+def reject (str, prefix="Rejected: "):
+ global reject_message;
+ if str:
+ reject_message += prefix + str + "\n";
+
+# Recheck anything that relies on the database; since that's not
+# frozen between accept and our run time.
+
+def check():
+ for file in files.keys():
+ # Check that the source still exists
+ if files[file]["type"] == "deb":
+ source_version = files[file]["source version"];
+ source_package = files[file]["source package"];
+ if not changes["architecture"].has_key("source") \
+ and not Katie.source_exists(source_package, source_version):
+ reject("no source found for %s %s (%s)." % (source_package, source_version, file));
+
+ # Version and file overwrite checks
+ if not installing_to_stable:
+ if files[file]["type"] == "deb":
+ reject(Katie.check_binary_against_db(file));
+ elif files[file]["type"] == "dsc":
+ reject(Katie.check_source_against_db(file));
+ (reject_msg, is_in_incoming) = Katie.check_dsc_against_db(file);
+ reject(reject_msg);
+
+ # Check the package is still in the override tables
+ for suite in changes["distribution"].keys():
+ if not Katie.in_override_p(files[file]["package"], files[file]["component"], suite, files[file].get("dbtype",""), file):
+ reject("%s is NEW for %s." % (file, suite));
+
+###############################################################################
+
+def init():
+ global Cnf, Options, Katie, projectB, changes, dsc, dsc_files, files, pkg, Subst;
+
+ Cnf = utils.get_conf()
+
+ Arguments = [('a',"automatic","Dinstall::Options::Automatic"),
+ ('h',"help","Dinstall::Options::Help"),
+ ('m',"manual-reject","Dinstall::Options::Manual-Reject", "HasArg"),
+ ('n',"no-action","Dinstall::Options::No-Action"),
+ ('p',"no-lock", "Dinstall::Options::No-Lock"),
+ ('s',"no-mail", "Dinstall::Options::No-Mail"),
+ ('V',"version","Dinstall::Options::Version")];
+
+ for i in ["automatic", "help", "manual-reject", "no-action",
+ "no-lock", "no-mail", "version"]:
+ if not Cnf.has_key("Dinstall::Options::%s" % (i)):
+ Cnf["Dinstall::Options::%s" % (i)] = "";
+
+ changes_files = apt_pkg.ParseCommandLine(Cnf,Arguments,sys.argv);
+ Options = Cnf.SubTree("Dinstall::Options")
+
+ Katie = katie.Katie(Cnf);
+ projectB = Katie.projectB;
+
+ changes = Katie.pkg.changes;
+ dsc = Katie.pkg.dsc;
+ dsc_files = Katie.pkg.dsc_files;
+ files = Katie.pkg.files;
+ pkg = Katie.pkg;
+ Subst = Katie.Subst;
+
+ return changes_files;
+
+###############################################################################
+
+def usage (exit_code=0):
+ print """Usage: dinstall [OPTION]... [CHANGES]...
+ -a, --automatic automatic run
+ -h, --help show this help and exit.
+ -n, --no-action don't do anything
+ -p, --no-lock don't check lockfile !! for cron.daily only !!
+ -s, --no-mail don't send any mail
+ -V, --version display the version number and exit"""
+ sys.exit(exit_code)
+
+###############################################################################
+
+def action ():
+ (summary, short_summary) = Katie.build_summaries();
+
+ (prompt, answer) = ("", "XXX")
+ if Options["No-Action"] or Options["Automatic"]:
+ answer = 'S'
+
+ if reject_message.find("Rejected") != -1:
+ print "REJECT\n" + reject_message,;
+ prompt = "[R]eject, Skip, Quit ?";
+ if Options["Automatic"]:
+ answer = 'R';
+ else:
+ print "INSTALL\n" + reject_message + summary,;
+ prompt = "[I]nstall, Skip, Quit ?";
+ if Options["Automatic"]:
+ answer = 'I';
+
+ while prompt.find(answer) == -1:
+ answer = utils.our_raw_input(prompt);
+ m = katie.re_default_answer.match(prompt);
+ if answer == "":
+ answer = m.group(1);
+ answer = answer[:1].upper();
+
+ if answer == 'R':
+ do_reject ();
+ elif answer == 'I':
+ if not installing_to_stable:
+ install();
+ else:
+ stable_install(summary, short_summary);
+ elif answer == 'Q':
+ sys.exit(0)
+
+###############################################################################
+
+# Our reject is not really a reject, but an unaccept, but since a) the
+# code for that is non-trivial (reopen bugs, unannounce etc.), b) this
+# should be exteremly rare, for now we'll go with whining at our admin
+# folks...
+
+def do_reject ():
+ Subst["__REJECTOR_ADDRESS__"] = Cnf["Dinstall::MyEmailAddress"];
+ Subst["__REJECT_MESSAGE__"] = reject_message;
+ Subst["__CC__"] = "Cc: " + Cnf["Dinstall::MyEmailAddress"];
+ reject_mail_message = utils.TemplateSubst(Subst,Cnf["Dir::Templates"]+"/kelly.unaccept");
+
+ # Write the rejection email out as the <foo>.reason file
+ reason_filename = os.path.basename(pkg.changes_file[:-8]) + ".reason";
+ reject_filename = Cnf["Dir::Queue::Reject"] + '/' + reason_filename;
+ # If we fail here someone is probably trying to exploit the race
+ # so let's just raise an exception ...
+ if os.path.exists(reject_filename):
+ os.unlink(reject_filename);
+ fd = os.open(reject_filename, os.O_RDWR|os.O_CREAT|os.O_EXCL, 0644);
+ os.write(fd, reject_mail_message);
+ os.close(fd);
+
+ utils.send_mail (reject_mail_message, "");
+ Logger.log(["unaccepted", pkg.changes_file]);
+
+###############################################################################
+
+def install ():
+ global install_count, install_bytes;
+
+ print "Installing."
+
+ Logger.log(["installing changes",pkg.changes_file]);
+
+ # Begin a transaction; if we bomb out anywhere between here and the COMMIT WORK below, the DB will not be changed.
+ projectB.query("BEGIN WORK");
+
+ # Add the .dsc file to the DB
+ for file in files.keys():
+ if files[file]["type"] == "dsc":
+ package = dsc["source"]
+ version = dsc["version"] # NB: not files[file]["version"], that has no epoch
+ maintainer = dsc["maintainer"]
+ maintainer = maintainer.replace("'", "\\'")
+ maintainer_id = db_access.get_or_set_maintainer_id(maintainer);
+ fingerprint_id = db_access.get_or_set_fingerprint_id(dsc["fingerprint"]);
+ install_date = time.strftime("%Y-%m-%d");
+ filename = files[file]["pool name"] + file;
+ dsc_location_id = files[file]["location id"];
+ if not files[file].has_key("files id") or not files[file]["files id"]:
+ files[file]["files id"] = db_access.set_files_id (filename, files[file]["size"], files[file]["md5sum"], dsc_location_id)
+ projectB.query("INSERT INTO source (source, version, maintainer, file, install_date, sig_fpr) VALUES ('%s', '%s', %d, %d, '%s', %s)"
+ % (package, version, maintainer_id, files[file]["files id"], install_date, fingerprint_id));
+
+ for suite in changes["distribution"].keys():
+ suite_id = db_access.get_suite_id(suite);
+ projectB.query("INSERT INTO src_associations (suite, source) VALUES (%d, currval('source_id_seq'))" % (suite_id))
+
+ # Add the source files to the DB (files and dsc_files)
+ projectB.query("INSERT INTO dsc_files (source, file) VALUES (currval('source_id_seq'), %d)" % (files[file]["files id"]));
+ for dsc_file in dsc_files.keys():
+ filename = files[file]["pool name"] + dsc_file;
+ # If the .orig.tar.gz is already in the pool, it's
+ # files id is stored in dsc_files by check_dsc().
+ files_id = dsc_files[dsc_file].get("files id", None);
+ if files_id == None:
+ files_id = db_access.get_files_id(filename, dsc_files[dsc_file]["size"], dsc_files[dsc_file]["md5sum"], dsc_location_id);
+ # FIXME: needs to check for -1/-2 and or handle exception
+ if files_id == None:
+ files_id = db_access.set_files_id (filename, dsc_files[dsc_file]["size"], dsc_files[dsc_file]["md5sum"], dsc_location_id);
+ projectB.query("INSERT INTO dsc_files (source, file) VALUES (currval('source_id_seq'), %d)" % (files_id));
+
+ # Add the .deb files to the DB
+ for file in files.keys():
+ if files[file]["type"] == "deb":
+ package = files[file]["package"]
+ version = files[file]["version"]
+ maintainer = files[file]["maintainer"]
+ maintainer = maintainer.replace("'", "\\'")
+ maintainer_id = db_access.get_or_set_maintainer_id(maintainer);
+ fingerprint_id = db_access.get_or_set_fingerprint_id(changes["fingerprint"]);
+ architecture = files[file]["architecture"]
+ architecture_id = db_access.get_architecture_id (architecture);
+ type = files[file]["dbtype"];
+ dsc_component = files[file]["component"]
+ source = files[file]["source package"]
+ source_version = files[file]["source version"];
+ filename = files[file]["pool name"] + file;
+ if not files[file].has_key("location id") or not files[file]["location id"]:
+ files[file]["location id"] = db_access.get_location_id(Cnf["Dir::Pool"],files[file]["component"],utils.where_am_i());
+ if not files[file].has_key("files id") or not files[file]["files id"]:
+ files[file]["files id"] = db_access.set_files_id (filename, files[file]["size"], files[file]["md5sum"], files[file]["location id"])
+ source_id = db_access.get_source_id (source, source_version);
+ if source_id:
+ projectB.query("INSERT INTO binaries (package, version, maintainer, source, architecture, file, type, sig_fpr) VALUES ('%s', '%s', %d, %d, %d, %d, '%s', %d)"
+ % (package, version, maintainer_id, source_id, architecture_id, files[file]["files id"], type, fingerprint_id));
+ else:
+ projectB.query("INSERT INTO binaries (package, version, maintainer, architecture, file, type, sig_fpr) VALUES ('%s', '%s', %d, %d, %d, '%s', %d)"
+ % (package, version, maintainer_id, architecture_id, files[file]["files id"], type, fingerprint_id));
+ for suite in changes["distribution"].keys():
+ suite_id = db_access.get_suite_id(suite);
+ projectB.query("INSERT INTO bin_associations (suite, bin) VALUES (%d, currval('binaries_id_seq'))" % (suite_id));
+
+ # If the .orig.tar.gz is in a legacy directory we need to poolify
+ # it, so that apt-get source (and anything else that goes by the
+ # "Directory:" field in the Sources.gz file) works.
+ orig_tar_id = Katie.pkg.orig_tar_id;
+ orig_tar_location = Katie.pkg.orig_tar_location;
+ legacy_source_untouchable = Katie.pkg.legacy_source_untouchable;
+ if orig_tar_id != None and orig_tar_location == "legacy":
+ q = projectB.query("SELECT DISTINCT ON (f.id) l.path, f.filename, f.id as files_id, df.source, df.id as dsc_files_id, f.size, f.md5sum FROM files f, dsc_files df, location l WHERE df.source IN (SELECT source FROM dsc_files WHERE file = %s) AND f.id = df.file AND l.id = f.location AND (l.type = 'legacy' OR l.type = 'legacy-mixed')" % (orig_tar_id));
+ qd = q.dictresult();
+ for qid in qd:
+ # Is this an old upload superseded by a newer -sa upload? (See check_dsc() for details)
+ if legacy_source_untouchable.has_key(qid["files_id"]):
+ continue;
+ # First move the files to the new location
+ legacy_filename = qid["path"] + qid["filename"];
+ pool_location = utils.poolify (changes["source"], files[file]["component"]);
+ pool_filename = pool_location + os.path.basename(qid["filename"]);
+ destination = Cnf["Dir::Pool"] + pool_location
+ utils.move(legacy_filename, destination);
+ # Then Update the DB's files table
+ q = projectB.query("UPDATE files SET filename = '%s', location = '%s' WHERE id = '%s'" % (pool_filename, dsc_location_id, qid["files_id"]));
+
+ # If this is a sourceful diff only upload that is moving non-legacy
+ # cross-component we need to copy the .orig.tar.gz into the new
+ # component too for the same reasons as above.
+ #
+ if changes["architecture"].has_key("source") and orig_tar_id != None and \
+ orig_tar_location != "legacy" and orig_tar_location != dsc_location_id:
+ q = projectB.query("SELECT l.path, f.filename, f.size, f.md5sum FROM files f, location l WHERE f.id = %s AND f.location = l.id" % (orig_tar_id));
+ ql = q.getresult()[0];
+ old_filename = ql[0] + ql[1];
+ file_size = ql[2];
+ file_md5sum = ql[3];
+ new_filename = utils.poolify(changes["source"], dsc_component) + os.path.basename(old_filename);
+ new_files_id = db_access.get_files_id(new_filename, file_size, file_md5sum, dsc_location_id);
+ if new_files_id == None:
+ utils.copy(old_filename, Cnf["Dir::Pool"] + new_filename);
+ new_files_id = db_access.set_files_id(new_filename, file_size, file_md5sum, dsc_location_id);
+ projectB.query("UPDATE dsc_files SET file = %s WHERE source = %s AND file = %s" % (new_files_id, source_id, orig_tar_id));
+
+ # Install the files into the pool
+ for file in files.keys():
+ destination = Cnf["Dir::Pool"] + files[file]["pool name"] + file;
+ utils.move(file, destination);
+ Logger.log(["installed", file, files[file]["type"], files[file]["size"], files[file]["architecture"]]);
+ install_bytes += float(files[file]["size"]);
+
+ # Copy the .changes file across for suite which need it.
+ copy_changes_p = copy_katie_p = 0;
+ for suite in changes["distribution"].keys():
+ if Cnf.has_key("Suite::%s::CopyChanges" % (suite)):
+ copy_changes_p = 1;
+ # and the .katie file...
+ if Cnf.has_key("Suite::%s::CopyKatie" % (suite)):
+ copy_katie_p = 1;
+ if copy_changes_p:
+ utils.copy(pkg.changes_file, Cnf["Dir::Root"] + Cnf["Suite::%s::CopyChanges" % (suite)]);
+ if copy_katie_p:
+ utils.copy(Katie.pkg.changes_file[:-8]+".katie", Cnf["Suite::%s::CopyKatie" % (suite)]);
+
+ projectB.query("COMMIT WORK");
+
+ # Move the .changes into the 'done' directory
+ try:
+ utils.move (pkg.changes_file, os.path.join(Cnf["Dir::Queue::Done"], os.path.basename(pkg.changes_file)));
+ except:
+ utils.warn("couldn't move changes file '%s' to DONE directory. [Got %s]" % (os.path.basename(pkg.changes_file), sys.exc_type));
+
+ os.unlink(Katie.pkg.changes_file[:-8]+".katie");
+
+ if changes["architecture"].has_key("source") and Urgency_Logger:
+ Urgency_Logger.log(dsc["source"], dsc["version"], changes["urgency"]);
+
+ # Undo the work done in katie.py(accept) to help auto-building
+ # from accepted.
+ projectB.query("BEGIN WORK");
+ for suite in changes["distribution"].keys():
+ if suite not in Cnf.ValueList("Dinstall::AcceptedAutoBuildSuites"):
+ continue;
+ now_date = time.strftime("%Y-%m-%d %H:%M");
+ suite_id = db_access.get_suite_id(suite);
+ dest_dir = Cnf["Dir::AcceptedAutoBuild"];
+ if Cnf.FindB("Dinstall::SecurityAcceptedAutoBuild"):
+ dest_dir = os.path.join(dest_dir, suite);
+ for file in files.keys():
+ dest = os.path.join(dest_dir, file);
+ # Remove it from the list of packages for later processing by apt-ftparchive
+ projectB.query("UPDATE accepted_autobuild SET in_accepted = 'f', last_used = '%s' WHERE filename = '%s' AND suite = %s" % (now_date, dest, suite_id));
+ if not Cnf.FindB("Dinstall::SecurityAcceptedAutoBuild"):
+ # Update the symlink to point to the new location in the pool
+ pool_location = utils.poolify (changes["source"], files[file]["component"]);
+ src = os.path.join(Cnf["Dir::Pool"], pool_location, os.path.basename(file));
+ if os.path.islink(dest):
+ os.unlink(dest);
+ os.symlink(src, dest);
+ # Update last_used on any non-upload .orig.tar.gz symlink
+ if orig_tar_id:
+ # Determine the .orig.tar.gz file name
+ for dsc_file in dsc_files.keys():
+ if dsc_file.endswith(".orig.tar.gz"):
+ orig_tar_gz = os.path.join(dest_dir, dsc_file);
+ # Remove it from the list of packages for later processing by apt-ftparchive
+ projectB.query("UPDATE accepted_autobuild SET in_accepted = 'f', last_used = '%s' WHERE filename = '%s' AND suite = %s" % (now_date, orig_tar_gz, suite_id));
+ projectB.query("COMMIT WORK");
+
+ # Finally...
+ install_count += 1;
+
+################################################################################
+
+def stable_install (summary, short_summary):
+ global install_count;
+
+ print "Installing to stable.";
+
+ # Begin a transaction; if we bomb out anywhere between here and the COMMIT WORK below, the DB will not be changed.
+ projectB.query("BEGIN WORK");
+
+ # Add the source to stable (and remove it from proposed-updates)
+ for file in files.keys():
+ if files[file]["type"] == "dsc":
+ package = dsc["source"];
+ version = dsc["version"]; # NB: not files[file]["version"], that has no epoch
+ q = projectB.query("SELECT id FROM source WHERE source = '%s' AND version = '%s'" % (package, version))
+ ql = q.getresult();
+ if not ql:
+ utils.fubar("[INTERNAL ERROR] couldn't find '%s' (%s) in source table." % (package, version));
+ source_id = ql[0][0];
+ suite_id = db_access.get_suite_id('proposed-updates');
+ projectB.query("DELETE FROM src_associations WHERE suite = '%s' AND source = '%s'" % (suite_id, source_id));
+ suite_id = db_access.get_suite_id('stable');
+ projectB.query("INSERT INTO src_associations (suite, source) VALUES ('%s', '%s')" % (suite_id, source_id));
+
+ # Add the binaries to stable (and remove it/them from proposed-updates)
+ for file in files.keys():
+ if files[file]["type"] == "deb":
+ package = files[file]["package"];
+ version = files[file]["version"];
+ architecture = files[file]["architecture"];
+ q = projectB.query("SELECT b.id FROM binaries b, architecture a WHERE b.package = '%s' AND b.version = '%s' AND (a.arch_string = '%s' OR a.arch_string = 'all') AND b.architecture = a.id" % (package, version, architecture));
+ ql = q.getresult();
+ if not ql:
+ utils.fubar("[INTERNAL ERROR] couldn't find '%s' (%s for %s architecture) in binaries table." % (package, version, architecture));
+ binary_id = ql[0][0];
+ suite_id = db_access.get_suite_id('proposed-updates');
+ projectB.query("DELETE FROM bin_associations WHERE suite = '%s' AND bin = '%s'" % (suite_id, binary_id));
+ suite_id = db_access.get_suite_id('stable');
+ projectB.query("INSERT INTO bin_associations (suite, bin) VALUES ('%s', '%s')" % (suite_id, binary_id));
+
+ projectB.query("COMMIT WORK");
+
+ utils.move (pkg.changes_file, Cnf["Dir::Morgue"] + '/katie/' + os.path.basename(pkg.changes_file));
+
+ ## Update the Stable ChangeLog file
+ new_changelog_filename = Cnf["Dir::Root"] + Cnf["Suite::Stable::ChangeLogBase"] + ".ChangeLog";
+ changelog_filename = Cnf["Dir::Root"] + Cnf["Suite::Stable::ChangeLogBase"] + "ChangeLog";
+ if os.path.exists(new_changelog_filename):
+ os.unlink (new_changelog_filename);
+
+ new_changelog = utils.open_file(new_changelog_filename, 'w');
+ for file in files.keys():
+ if files[file]["type"] == "deb":
+ new_changelog.write("stable/%s/binary-%s/%s\n" % (files[file]["component"], files[file]["architecture"], file));
+ elif utils.re_issource.match(file) != None:
+ new_changelog.write("stable/%s/source/%s\n" % (files[file]["component"], file));
+ else:
+ new_changelog.write("%s\n" % (file));
+ chop_changes = katie.re_fdnic.sub("\n", changes["changes"]);
+ new_changelog.write(chop_changes + '\n\n');
+ if os.access(changelog_filename, os.R_OK) != 0:
+ changelog = utils.open_file(changelog_filename);
+ new_changelog.write(changelog.read());
+ new_changelog.close();
+ if os.access(changelog_filename, os.R_OK) != 0:
+ os.unlink(changelog_filename);
+ utils.move(new_changelog_filename, changelog_filename);
+
+ install_count += 1;
+
+ if not Options["No-Mail"] and changes["architecture"].has_key("source"):
+ Subst["__SUITE__"] = " into stable";
+ Subst["__SUMMARY__"] = summary;
+ mail_message = utils.TemplateSubst(Subst,Cnf["Dir::Templates"]+"/kelly.installed");
+ utils.send_mail(mail_message, "");
+ Katie.announce(short_summary, 1)
+
+ # Finally remove the .katie file
+ katie_file = os.path.join(Cnf["Suite::Proposed-Updates::CopyKatie"], os.path.basename(Katie.pkg.changes_file[:-8]+".katie"));
+ os.unlink(katie_file);
+
+################################################################################
+
+def process_it (changes_file):
+ global reject_message;
+
+ reject_message = "";
+
+ # Absolutize the filename to avoid the requirement of being in the
+ # same directory as the .changes file.
+ pkg.changes_file = os.path.abspath(changes_file);
+
+ # And since handling of installs to stable munges with the CWD;
+ # save and restore it.
+ pkg.directory = os.getcwd();
+
+ if installing_to_stable:
+ old = Katie.pkg.changes_file;
+ Katie.pkg.changes_file = os.path.basename(old);
+ os.chdir(Cnf["Suite::Proposed-Updates::CopyKatie"]);
+
+ Katie.init_vars();
+ Katie.update_vars();
+ Katie.update_subst();
+
+ if installing_to_stable:
+ Katie.pkg.changes_file = old;
+
+ check();
+ action();
+
+ # Restore CWD
+ os.chdir(pkg.directory);
+
+###############################################################################
+
+def main():
+ global projectB, Logger, Urgency_Logger, installing_to_stable;
+
+ changes_files = init();
+
+ if Options["Help"]:
+ usage();
+
+ if Options["Version"]:
+ print "kelly %s" % (kelly_version);
+ sys.exit(0);
+
+ # -n/--dry-run invalidates some other options which would involve things happening
+ if Options["No-Action"]:
+ Options["Automatic"] = "";
+
+ # Check that we aren't going to clash with the daily cron job
+
+ if not Options["No-Action"] and os.path.exists("%s/Archive_Maintenance_In_Progress" % (Cnf["Dir::Root"])) and not Options["No-Lock"]:
+ utils.fubar("Archive maintenance in progress. Try again later.");
+
+ # If running from within proposed-updates; assume an install to stable
+ if os.getcwd().find('proposed-updates') != -1:
+ installing_to_stable = 1;
+
+ # Obtain lock if not in no-action mode and initialize the log
+ if not Options["No-Action"]:
+ lock_fd = os.open(Cnf["Dinstall::LockFile"], os.O_RDWR | os.O_CREAT);
+ fcntl.lockf(lock_fd, FCNTL.F_TLOCK);
+ Logger = Katie.Logger = logging.Logger(Cnf, "katie");
+ if not installing_to_stable and Cnf.get("Dir::UrgencyLog"):
+ Urgency_Logger = Urgency_Log(Cnf);
+
+ # Initialize the substitution template mapping global
+ bcc = "X-Katie: %s" % (kelly_version);
+ if Cnf.has_key("Dinstall::Bcc"):
+ Subst["__BCC__"] = bcc + "\nBcc: %s" % (Cnf["Dinstall::Bcc"]);
+ else:
+ Subst["__BCC__"] = bcc;
+ if Cnf.has_key("Dinstall::StableRejector"):
+ Subst["__STABLE_REJECTOR__"] = Cnf["Dinstall::StableRejector"];
+
+ # Sort the .changes files so that we process sourceful ones first
+ changes_files.sort(utils.changes_compare);
+
+ # Process the changes files
+ for changes_file in changes_files:
+ print "\n" + changes_file;
+ process_it (changes_file);
+
+ if install_count:
+ sets = "set"
+ if install_count > 1:
+ sets = "sets"
+ sys.stderr.write("Installed %d package %s, %s.\n" % (install_count, sets, utils.size_type(int(install_bytes))));
+ Logger.log(["total",install_count,install_bytes]);
+
+ if not Options["No-Action"]:
+ Logger.close();
+ if Urgency_Logger:
+ Urgency_Logger.close();
+
+###############################################################################
+
+if __name__ == '__main__':
+ main();
# Handles NEW and BYHAND packages
# Copyright (C) 2001, 2002 James Troup <james@nocrew.org>
-# $Id: lisa,v 1.17 2002-05-23 12:19:05 troup Exp $
+# $Id: lisa,v 1.18 2002-10-16 02:47:32 troup Exp $
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
################################################################################
-import copy, errno, os, readline, string, stat, sys, tempfile;
+import copy, errno, os, readline, stat, sys, tempfile;
import apt_pkg, apt_inst;
import db_access, fernanda, katie, logging, utils;
# Globals
-lisa_version = "$Revision: 1.17 $";
+lisa_version = "$Revision: 1.18 $";
Cnf = None;
Options = None;
def reject (str, prefix="Rejected: "):
global reject_message;
if str:
- reject_message = reject_message + prefix + str + "\n";
+ reject_message += prefix + str + "\n";
def recheck():
global reject_message;
print "REJECT\n" + reject_message,;
prompt = "[R]eject, Skip, Quit ?";
- while string.find(prompt, answer) == -1:
+ while prompt.find(answer) == -1:
answer = utils.our_raw_input(prompt);
m = katie.re_default_answer.match(prompt);
if answer == "":
answer = m.group(1);
- answer = string.upper(answer[:1]);
+ answer = answer[:1].upper();
if answer == 'R':
Katie.do_reject(0, reject_message);
ctime = os.stat(d["filename"])[stat.ST_CTIME];
if ctime < oldest:
oldest = ctime;
- have_note = have_note + (d.has_key("lisa note"));
+ have_note += (d.has_key("lisa note"));
per_source[source]["oldest"] = oldest;
if not have_note:
per_source[source]["note_state"] = 0; # none
broken = 0;
index = 0;
for pkg in new.keys():
- index = index + 1;
+ index += 1;
section = new[pkg]["section"];
priority = new[pkg]["priority"];
if new[pkg]["section id"] == -1:
- section = section + "[!]";
+ section += "[!]";
broken = 1;
if new[pkg]["priority id"] == -1:
- priority = priority + "[!]";
+ priority += "[!]";
broken = 1;
if indexed:
line = "(%s): %-20s %-20s %-20s" % (index, pkg, priority, section);
else:
line = "%-20s %-20s %-20s" % (pkg, priority, section);
- line = string.strip(line)+'\n';
+ line = line.strip()+'\n';
file.write(line);
note = Katie.pkg.changes.get("lisa note");
if note:
os.unlink(temp_filename);
# Parse the new data
for line in lines:
- line = string.strip(line[:-1]);
+ line = line.strip();
if line == "":
continue;
- s = string.split(line);
+ s = line.split();
# Pad the list if necessary
s[len(s):3] = [None] * (3-len(s));
(pkg, priority, section) = s[:3];
utils.warn("Ignoring unknown package '%s'" % (pkg));
else:
# Strip off any invalid markers, print_new will readd them.
- if section[-3:] == "[!]":
+ if section.endswith("[!]"):
section = section[:-3];
- if priority[-3:] == "[!]":
+ if priority.endswith("[!]"):
priority = priority[:-3];
for file in new[pkg]["files"]:
Katie.pkg.files[file]["section"] = section;
type = new[index]["type"];
done = 0
while not done:
- print string.join([index, priority, section], '\t');
+ print "\t".join([index, priority, section]);
answer = "XXX";
if type != "dsc":
prompt = "[S]ection, Done ? ";
edit_priority = edit_section = 0;
- while string.find(prompt, answer) == -1:
+ while prompt.find(answer) == -1:
answer = utils.our_raw_input(prompt);
m = katie.re_default_answer.match(prompt)
if answer == "":
answer = m.group(1)
- answer = string.upper(answer[:1])
+ answer = answer[:1].upper()
if answer == 'P':
edit_priority = 1;
readline.set_completer(Priorities.complete);
got_priority = 0;
while not got_priority:
- new_priority = string.strip(utils.our_raw_input("New priority: "));
+ new_priority = utils.our_raw_input("New priority: ").strip();
if Priorities.priorities.count(new_priority) == 0:
print "E: '%s' is not a valid priority, try again." % (new_priority);
else:
readline.set_completer(Sections.complete);
got_section = 0;
while not got_section:
- new_section = string.strip(utils.our_raw_input("New section: "));
+ new_section = utils.our_raw_input("New section: ").strip();
if Sections.sections.count(new_section) == 0:
print "E: '%s' is not a valid section, try again." % (new_section);
else:
new_index = {};
index = 0;
for i in new.keys():
- index = index + 1;
+ index += 1;
new_index[index] = i;
prompt = "(%s) edit override <n>, Editor, Done ? " % (index_range(index));
got_answer = 0
while not got_answer:
answer = utils.our_raw_input(prompt);
- answer = string.upper(answer[:1]);
+ answer = answer[:1].upper();
if answer == "E" or answer == "D":
got_answer = 1;
elif katie.re_isanum.match (answer):
while answer == 'E':
os.system("%s %s" % (editor, temp_filename))
temp_file = utils.open_file(temp_filename);
- note = string.rstrip(temp_file.read());
+ note = temp_file.read().rstrip();
temp_file.close();
print "Note:";
print utils.prefix_multi_line_string(note," ");
prompt = "[D]one, Edit, Abandon, Quit ?"
answer = "XXX";
- while string.find(prompt, answer) == -1:
+ while prompt.find(answer) == -1:
answer = utils.our_raw_input(prompt);
m = katie.re_default_answer.search(prompt);
if answer == "":
answer = m.group(1);
- answer = string.upper(answer[:1]);
+ answer = answer[:1].upper();
os.unlink(temp_filename);
if answer == 'A':
return;
for file in files.keys():
if files[file]["type"] == "deb":
control = apt_pkg.ParseSection(apt_inst.debExtractControl(utils.open_file(file)));
- summary = summary + "\n";
- summary = summary + "Package: %s\n" % (control.Find("Package"));
- summary = summary + "Description: %s\n" % (control.Find("Description"));
+ summary += "\n";
+ summary += "Package: %s\n" % (control.Find("Package"));
+ summary += "Description: %s\n" % (control.Find("Description"));
Katie.Subst["__BINARY_DESCRIPTIONS__"] = summary;
bxa_mail = utils.TemplateSubst(Katie.Subst,Cnf["Dir::Templates"]+"/lisa.bxa_notification");
utils.send_mail(bxa_mail,"");
print "W: [!] marked entries must be fixed before package can be processed.";
if note:
print "W: note must be removed before package can be processed.";
- prompt = prompt + "Remove note, ";
+ prompt += "Remove note, ";
- prompt = prompt + "Edit overrides, Check, Manual reject, Note edit, [S]kip, Quit ?";
+ prompt += "Edit overrides, Check, Manual reject, Note edit, [S]kip, Quit ?";
- while string.find(prompt, answer) == -1:
+ while prompt.find(answer) == -1:
answer = utils.our_raw_input(prompt);
m = katie.re_default_answer.search(prompt);
if answer == "":
answer = m.group(1)
- answer = string.upper(answer[:1])
+ answer = answer[:1].upper()
if answer == 'A':
done = add_overrides (new);
elif answer == 'N':
edit_note(changes.get("lisa note", ""));
elif answer == 'R':
- confirm = string.lower(utils.our_raw_input("Really clear note (y/N)? "));
+ confirm = utils.our_raw_input("Really clear note (y/N)? ").lower();
if confirm == "y":
del changes["lisa note"];
elif answer == 'S':
else:
prompt = "Manual reject, [S]kip, Quit ?";
- while string.find(prompt, answer) == -1:
+ while prompt.find(answer) == -1:
answer = utils.our_raw_input(prompt);
m = katie.re_default_answer.search(prompt);
if answer == "":
answer = m.group(1);
- answer = string.upper(answer[:1]);
+ answer = answer[:1].upper();
if answer == 'A':
done = 1;
+#!/usr/bin/env python
+
# Logging functions
# Copyright (C) 2001, 2002 James Troup <james@nocrew.org>
-# $Id: logging.py,v 1.2 2002-05-08 11:17:45 troup Exp $
+# $Id: logging.py,v 1.3 2002-10-16 02:47:32 troup Exp $
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
################################################################################
-import os, pwd, string, time
-import utils
+import os, pwd, time;
+import utils;
################################################################################
umask = os.umask(00000);
os.makedirs(logdir, 02775);
# Open the logfile
- logfilename = "%s/%s" % (logdir, time.strftime("%Y-%m", time.localtime(time.time())));
+ logfilename = "%s/%s" % (logdir, time.strftime("%Y-%m"));
logfile = utils.open_file(logfilename, 'a');
# Seek to the end of the logfile
logfile.seek(0,2);
"Log an event"
# Prepend the timestamp and program name
details.insert(0, self.program);
- timestamp = time.strftime("%Y%m%d%H%M%S", time.localtime(time.time()));
+ timestamp = time.strftime("%Y%m%d%H%M%S");
details.insert(0, timestamp);
# Force the contents of the list to be string.join-able
details = map(str, details);
# Write out the log in TSV
- self.logfile.write(string.join(details, '~')+'\n');
+ self.logfile.write("~".join(details)+'\n');
# Flush the output to enable tail-ing
self.logfile.flush();
# Display information about package(s) (suite, version, etc.)
# Copyright (C) 2000, 2001, 2002 James Troup <james@nocrew.org>
-# $Id: madison,v 1.20 2002-07-14 15:02:07 troup Exp $
+# $Id: madison,v 1.21 2002-10-16 02:47:32 troup Exp $
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
################################################################################
-import pg, string, sys;
+import pg, sys;
import utils, db_access;
import apt_pkg;
ql.extend(q.getresult());
d = {};
for i in ql:
- results = results + 1;
+ results += 1;
pkg = i[0];
version = i[1];
architecture = i[2];
sys.stdout.write("%10s | %10s | %13s | " % (pkg, version, suite));
arches = d[pkg][version][suite];
arches.sort(arch_compare);
- sys.stdout.write(string.join(arches, ", "));
+ sys.stdout.write(", ".join(arches));
sys.stdout.write('\n');
if not results:
# General purpose package removal tool for ftpmaster
# Copyright (C) 2000, 2001, 2002 James Troup <james@nocrew.org>
-# $Id: melanie,v 1.30 2002-08-29 22:56:29 troup Exp $
+# $Id: melanie,v 1.31 2002-10-16 02:47:32 troup Exp $
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
################################################################################
-import commands, os, pg, re, string, sys, tempfile
+import commands, os, pg, re, sys, tempfile
import utils, db_access
import apt_pkg, apt_inst;
# going to do now?"
def game_over():
- answer = string.lower(utils.our_raw_input("Continue (y/N)? "));
+ answer = utils.our_raw_input("Continue (y/N)? ").lower();
if answer != "y":
print "Aborted."
sys.exit(1);
# 3) contains a '@' - assumed to be an email address, used unmofidied
#
carbon_copy = [];
- for copy_to in string.split(Options.get("Carbon-Copy")):
+ for copy_to in Options.get("Carbon-Copy").split():
if utils.str_isnum(copy_to):
carbon_copy.append(copy_to + "@" + Cnf["Dinstall::BugServer"]);
elif copy_to == 'package':
field = "b.package";
else:
field = "s.source";
- con_packages = "AND %s IN (%s)" % (field, string.join(map(repr, arguments), ", "));
+ con_packages = "AND %s IN (%s)" % (field, ", ".join(map(repr, arguments)));
(con_suites, con_architectures, con_components, check_source) = \
utils.parse_args(Options);
# Additional suite checks
suite_ids_list = [];
- suites = string.split(Options["Suite"]);
+ suites = Options["Suite"].split();
suites_list = utils.join_with_commas_and(suites);
if not Options["No-Action"]:
for suite in suites:
utils.warn("'source' in -a/--argument makes no sense and is ignored.");
# Additional component processing
- over_con_components = string.replace(con_components, "c.id", "component");
+ over_con_components = con_components.replace("c.id", "component");
print "Working...",
sys.stdout.flush();
binary_packages[i[0]] = "";
# Then parse each .dsc that we found earlier to see what binary packages it thinks it produces
for i in source_packages.keys():
- filename = string.join(source_packages[i], '/');
+ filename = "/".join(source_packages[i]);
try:
dsc = utils.parse_changes(filename);
except utils.cant_open_exc:
utils.warn("couldn't open '%s'." % (filename));
continue;
- for package in string.split(dsc.get("binary"), ','):
- package = string.strip(package);
+ for package in dsc.get("binary").split(','):
+ package = package.strip();
binary_packages[package] = "";
# Then for each binary package: find any version in
# unstable, check the Source: field in the deb matches our
for package in binary_packages.keys():
q = projectB.query("SELECT l.path, f.filename, b.package, b.version, a.arch_string, b.id, b.maintainer FROM binaries b, bin_associations ba, architecture a, suite su, files f, location l, component c WHERE ba.bin = b.id AND ba.suite = su.id AND b.architecture = a.id AND b.file = f.id AND f.location = l.id AND l.component = c.id %s %s %s AND b.package = '%s'" % (con_suites, con_components, con_architectures, package));
for i in q.getresult():
- filename = string.join(i[:2], '/');
+ filename = "/".join(i[:2]);
control = apt_pkg.ParseSection(apt_inst.debExtractControl(utils.open_file(filename)))
source = control.Find("Source", control.Find("Package"));
source = re_strip_source_version.sub('', source);
utils.fubar ("vi invocation failed for `%s'!" % (temp_filename), result)
file = utils.open_file(temp_filename);
for line in file.readlines():
- Options["Reason"] = Options["Reason"] + line;
+ Options["Reason"] += line;
os.unlink(temp_filename);
# Generate the summary of what's to be removed
versions = d[package].keys();
versions.sort();
for version in versions:
- summary = summary + "%10s | %10s | %s\n" % (package, version, string.join(d[package][version], ", "));
+ summary += "%10s | %10s | %s\n" % (package, version, ", ".join(d[package][version]));
print "Will remove the following packages from %s:" % (suites_list);
print
print summary
- print "Maintainer: %s" % string.join(maintainer_list, ", ")
+ print "Maintainer: %s" % ", ".join(maintainer_list)
if Options["Done"]:
print "Will also close bugs: "+Options["Done"];
if carbon_copy:
- print "Will also send CCs to:" + string.join(carbon_copy, ", ")
+ print "Will also send CCs to:" + ", ".join(carbon_copy)
print
print "------------------- Reason -------------------"
print Options["Reason"];
if Cnf.Find("Melanie::Bcc") != "":
bcc.append(Cnf["Melanie::Bcc"]);
if bcc:
- Subst["__BCC__"] = "Bcc: " + string.join(bcc, ", ");
+ Subst["__BCC__"] = "Bcc: " + ", ".join(bcc);
else:
Subst["__BCC__"] = "X-Filler: 42";
- Subst["__CC__"] = "X-Melanie: $Revision: 1.30 $";
+ Subst["__CC__"] = "X-Melanie: $Revision: 1.31 $";
if carbon_copy:
- Subst["__CC__"] = Subst["__CC__"] + "\nCc: " + string.join(carbon_copy, ", ");
+ Subst["__CC__"] += "\nCc: " + ", ".join(carbon_copy);
Subst["__SUITE_LIST__"] = suites_list;
Subst["__SUMMARY__"] = summary;
Subst["__ADMIN_ADDRESS__"] = Cnf["Dinstall::MyAdminAddress"];
Archive = Cnf.SubTree("Archive::%s" % (whereami));
Subst["__MASTER_ARCHIVE__"] = Archive["OriginServer"];
Subst["__PRIMARY_MIRROR__"] = Archive["PrimaryMirror"];
- for bug in string.split(Options["Done"]):
+ for bug in Options["Done"].split():
Subst["__BUG_NUMBER__"] = bug;
mail_message = utils.TemplateSubst(Subst,Cnf["Dir::Templates"]+"/melanie.bug-close");
utils.send_mail (mail_message, "")
# Manipulate override files
# Copyright (C) 2000, 2001, 2002 James Troup <james@nocrew.org>
-# $Id: natalie,v 1.3 2002-07-14 15:01:19 troup Exp $
+# $Id: natalie,v 1.4 2002-10-16 02:47:32 troup Exp $
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
################################################################################
-import pg, string, sys, time;
+import pg, sys, time;
import utils, db_access, logging;
import apt_pkg;
start_time = time.time();
projectB.query("BEGIN WORK");
for line in file.readlines():
- line = string.strip(utils.re_comments.sub('', line[:-1]))
+ line = utils.re_comments.sub('', line[:-1]).strip();
if line == "":
continue;
maintainer_override = None;
if type == "dsc":
- split_line = string.split(line, None, 2);
+ split_line = line.split(None, 2);
if len(split_line) == 2:
(package, section) = split_line;
elif len(split_line) == 3:
(package, section, maintainer_override) = split_line;
else:
utils.warn("'%s' does not break into 'package section [maintainer-override]'." % (line));
- c_error = c_error + 1;
+ c_error += 1;
continue;
priority = "source";
else: # binary or udeb
- split_line = string.split(line, None, 3);
+ split_line = line.split(None, 3);
if len(split_line) == 3:
(package, priority, section) = split_line;
elif len(split_line) == 4:
(package, priority, section, maintainer_override) = split_line;
else:
utils.warn("'%s' does not break into 'package priority section [maintainer-override]'." % (line));
- c_error = c_error + 1;
+ c_error += 1;
continue;
section_id = db_access.get_section_id(section);
if section_id == -1:
utils.warn("'%s' is not a valid section. ['%s' in suite %s, component %s]." % (section, package, suite, component));
- c_error = c_error + 1;
+ c_error += 1;
continue;
priority_id = db_access.get_priority_id(priority);
if priority_id == -1:
utils.warn("'%s' is not a valid priority. ['%s' in suite %s, component %s]." % (priority, package, suite, component));
- c_error = c_error + 1;
+ c_error += 1;
continue;
if new.has_key(package):
utils.warn("Can't insert duplicate entry for '%s'; ignoring all but the first. [suite %s, component %s]" % (package, suite, component));
- c_error = c_error + 1;
+ c_error += 1;
continue;
new[package] = "";
if original.has_key(package):
old_section_id == section_id and \
old_maintainer_override == maintainer_override:
# If it's unchanged or we're in 'add only' mode, ignore it
- c_skipped = c_skipped + 1;
+ c_skipped += 1;
continue;
else:
# If it's changed, delete the old one so we can
# reinsert it with the new information
- c_updated = c_updated + 1;
+ c_updated += 1;
projectB.query("DELETE FROM override WHERE suite = %s AND component = %s AND package = '%s' AND type = %s"
% (suite_id, component_id, package, type_id));
# Log changes
Logger.log(["changed maintainer override",package,old_maintainer_override,maintainer_override]);
update_p = 1;
else:
- c_added = c_added + 1;
+ c_added += 1;
update_p = 0;
if maintainer_override:
if not new.has_key(package):
projectB.query("DELETE FROM override WHERE suite = %s AND component = %s AND package = '%s' AND type = %s"
% (suite_id, component_id, package, type_id));
- c_removed = c_removed + 1;
+ c_removed += 1;
Logger.log(["removed override",suite,component,type,package]);
projectB.query("COMMIT WORK");
# Populate the DB
# Copyright (C) 2000, 2001, 2002 James Troup <james@nocrew.org>
-# $Id: neve,v 1.13 2002-06-09 17:33:46 troup Exp $
+# $Id: neve,v 1.14 2002-10-16 02:47:32 troup Exp $
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
###############################################################################
-import commands, os, pg, re, select, string, tempfile, time;
+import commands, os, pg, re, select, tempfile, time;
import apt_pkg;
import db_access, utils;
if len(r) > 0:
more_data.append(fd);
if fd == c2pwrite or fd == errin:
- output = output + r;
+ output += r;
elif fd == status_read:
- status = status + r;
+ status += r;
else:
utils.fubar("Unexpected file descriptor [%s] returned from select\n" % (fd));
if not more_data:
def reject (str, prefix="Rejected: "):
global reject_message;
if str:
- reject_message = reject_message + prefix + str + "\n";
+ reject_message += prefix + str + "\n";
###############################################################################
# Process the status-fd output
keywords = {};
bad = internal_error = "";
- for line in string.split(status, '\n'):
- line = string.strip(line);
+ for line in status.split('\n'):
+ line = line.strip();
if line == "":
continue;
- split = string.split(line);
+ split = line.split();
if len(split) < 2:
- internal_error = internal_error + "gpgv status line is malformed (< 2 atoms) ['%s'].\n" % (line);
+ internal_error += "gpgv status line is malformed (< 2 atoms) ['%s'].\n" % (line);
continue;
(gnupg, keyword) = split[:2];
if gnupg != "[GNUPG:]":
- internal_error = internal_error + "gpgv status line is malformed (incorrect prefix '%s').\n" % (gnupg);
+ internal_error += "gpgv status line is malformed (incorrect prefix '%s').\n" % (gnupg);
continue;
args = split[2:];
if keywords.has_key(keyword) and keyword != "NODATA" and keyword != "SIGEXPIRED":
- internal_error = internal_error + "found duplicate status token ('%s')." % (keyword);
+ internal_error += "found duplicate status token ('%s')." % (keyword);
continue;
else:
keywords[keyword] = args;
# Next check gpgv exited with a zero return code
if exit_status and not keywords.has_key("NO_PUBKEY"):
reject("gpgv failed while checking %s." % (filename));
- if string.strip(status):
+ if status.strip():
reject(utils.prefix_multi_line_string(status, " [GPG status-fd output:] "), "");
else:
reject(utils.prefix_multi_line_string(output, " [GPG output:] "), "");
for keyword in keywords.keys():
if not known_keywords.has_key(keyword):
- reject("found unknown status token '%s' from gpgv with args '%s' in %s." % (keyword, repr(keywords[keyword]), filename));
+ reject("found unknown status token '%s' from gpgv with args '%r' in %s." % (keyword, keywords[keyword], filename));
bad = 1;
if bad:
projectB.query("DELETE FROM suite")
for suite in Cnf.SubTree("Suite").List():
SubSec = Cnf.SubTree("Suite::%s" %(suite))
- projectB.query("INSERT INTO suite (suite_name) VALUES ('%s')" % string.lower(suite));
+ projectB.query("INSERT INTO suite (suite_name) VALUES ('%s')" % suite.lower());
for i in ("Version", "Origin", "Description"):
if SubSec.has_key(i):
- projectB.query("UPDATE suite SET %s = '%s' WHERE suite_name = '%s'" % (string.lower(i), SubSec[i], string.lower(suite)))
+ projectB.query("UPDATE suite SET %s = '%s' WHERE suite_name = '%s'" % (i.lower(), SubSec[i], suite.lower()))
for architecture in Cnf.ValueList("Suite::%s::Architectures" % (suite)):
architecture_id = db_access.get_architecture_id (architecture);
projectB.query("INSERT INTO suite_architectures (suite, architecture) VALUES (currval('suite_id_seq'), %d)" % (architecture_id));
def get_or_set_files_id (filename, size, md5sum, location_id):
global files_id_cache, files_id_serial, files_query_cache;
- cache_key = string.join((filename, size, md5sum, repr(location_id)), '~')
+ cache_key = "~".join((filename, size, md5sum, repr(location_id)));
if not files_id_cache.has_key(cache_key):
- files_id_serial = files_id_serial + 1
+ files_id_serial += 1
files_query_cache.write("%d\t%s\t%s\t%s\t%d\n" % (files_id_serial, filename, size, md5sum, location_id));
files_id_cache[cache_key] = files_id_serial
def process_sources (location, filename, suite, component, archive, dsc_dir):
global source_cache, source_query_cache, src_associations_query_cache, dsc_files_query_cache, source_id_serial, src_associations_id_serial, dsc_files_id_serial, source_cache_for_binaries, orig_tar_gz_cache, reject_message;
- suite = string.lower(suite);
+ suite = suite.lower();
suite_id = db_access.get_suite_id(suite);
try:
file = utils.open_file (filename);
if reject_message:
utils.fubar("%s: %s" % (dsc_file, reject_message));
maintainer = Scanner.Section["maintainer"]
- maintainer = string.replace(maintainer, "'", "\\'");
+ maintainer = maintainer.replace("'", "\\'");
maintainer_id = db_access.get_or_set_maintainer_id(maintainer);
directory = Scanner.Section["directory"];
location_id = db_access.get_location_id (location, component, archive);
- if directory[-1:] != "/":
- directory = directory + '/';
+ if not directory.endswith("/"):
+ directory += '/';
directory = poolify (directory, location);
- if directory != "" and directory[-1:] != "/":
- directory = directory + '/';
+ if directory != "" and not directory.endswith("/"):
+ directory += '/';
no_epoch_version = utils.re_no_epoch.sub('', version);
# Add all files referenced by the .dsc to the files table
ids = [];
- for line in string.split(Scanner.Section["files"],'\n'):
+ for line in Scanner.Section["files"].split('\n'):
id = None;
- (md5sum, size, filename) = string.split(string.strip(line));
+ (md5sum, size, filename) = line.strip().split();
# Don't duplicate .orig.tar.gz's
- if filename[-12:] == ".orig.tar.gz":
+ if filename.endswith(".orig.tar.gz"):
cache_key = "%s~%s~%s" % (filename, size, md5sum);
if orig_tar_gz_cache.has_key(cache_key):
id = orig_tar_gz_cache[cache_key];
id = get_or_set_files_id (directory + filename, size, md5sum, location_id);
ids.append(id);
# If this is the .dsc itself; save the ID for later.
- if filename[-4:] == ".dsc":
+ if filename.endswith(".dsc"):
files_id = id;
filename = directory + package + '_' + no_epoch_version + '.dsc'
cache_key = "%s~%s" % (package, version);
if not source_cache.has_key(cache_key):
nasty_key = "%s~%s" % (package, version)
- source_id_serial = source_id_serial + 1;
+ source_id_serial += 1;
if not source_cache_for_binaries.has_key(nasty_key):
source_cache_for_binaries[nasty_key] = source_id_serial;
tmp_source_id = source_id_serial;
source_cache[cache_key] = source_id_serial;
source_query_cache.write("%d\t%s\t%s\t%d\t%d\t%s\t%s\n" % (source_id_serial, package, version, maintainer_id, files_id, install_date, fingerprint_id))
for id in ids:
- dsc_files_id_serial = dsc_files_id_serial + 1;
+ dsc_files_id_serial += 1;
dsc_files_query_cache.write("%d\t%d\t%d\n" % (dsc_files_id_serial, tmp_source_id,id));
else:
tmp_source_id = source_cache[cache_key];
- src_associations_id_serial = src_associations_id_serial + 1;
+ src_associations_id_serial += 1;
src_associations_query_cache.write("%d\t%d\t%d\n" % (src_associations_id_serial, suite_id, tmp_source_id))
file.close();
count_total = 0;
count_bad = 0;
- suite = string.lower(suite);
+ suite = suite.lower();
suite_id = db_access.get_suite_id(suite);
try:
file = utils.open_file (filename);
package = Scanner.Section["package"]
version = Scanner.Section["version"]
maintainer = Scanner.Section["maintainer"]
- maintainer = string.replace(maintainer, "'", "\\'")
+ maintainer = maintainer.replace("'", "\\'")
maintainer_id = db_access.get_or_set_maintainer_id(maintainer);
architecture = Scanner.Section["architecture"]
architecture_id = db_access.get_architecture_id (architecture);
else:
source = Scanner.Section["source"]
source_version = ""
- if string.find(source, "(") != -1:
+ if source.find("(") != -1:
m = utils.re_extract_src_version.match(source)
source = m.group(1)
source_version = m.group(2)
if not binary_cache.has_key(cache_key):
if not source_id:
source_id = "\N";
- count_bad = count_bad + 1;
+ count_bad += 1;
else:
source_id = repr(source_id);
- binaries_id_serial = binaries_id_serial + 1;
+ binaries_id_serial += 1;
binaries_query_cache.write("%d\t%s\t%s\t%d\t%s\t%d\t%d\t%s\t%s\n" % (binaries_id_serial, package, version, maintainer_id, source_id, architecture_id, files_id, type, fingerprint_id));
binary_cache[cache_key] = binaries_id_serial;
tmp_binaries_id = binaries_id_serial;
else:
tmp_binaries_id = binary_cache[cache_key];
- bin_associations_id_serial = bin_associations_id_serial + 1;
+ bin_associations_id_serial += 1;
bin_associations_query_cache.write("%d\t%d\t%d\n" % (bin_associations_id_serial, suite_id, tmp_binaries_id));
- count_total = count_total +1;
+ count_total += 1;
file.close();
if count_bad != 0:
# Check for obsolete binary packages
# Copyright (C) 2000, 2001, 2002 James Troup <james@nocrew.org>
-# $Id: rene,v 1.14 2002-08-07 17:19:29 troup Exp $
+# $Id: rene,v 1.15 2002-10-16 02:47:32 troup Exp $
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
################################################################################
-import commands, pg, os, string, sys, tempfile;
+import commands, pg, os, sys, tempfile;
import utils, db_access;
import apt_pkg;
Cnf = utils.get_conf()
- Arguments = [('h',"help","Catherine::Options::Help"),
- ('V',"version","Catherine::Options::Version"),
- ('l',"limit", "Catherine::Options::Limit", "HasArg"),
- ('n',"no-action","Catherine::Options::No-Action"),
- ('v',"verbose","Catherine::Options::Verbose")];
-
- apt_pkg.ParseCommandLine(Cnf,Arguments,sys.argv);
+ apt_pkg.ParseCommandLine(Cnf,[],sys.argv);
projectB = pg.connect(Cnf["DB::Name"], Cnf["DB::Host"], int(Cnf["DB::Port"]));
db_access.init(Cnf, projectB);
# Check for packages built on architectures they shouldn't be.
if architecture != "any" and architecture != "all":
architectures = {};
- for arch in string.split(architecture):
- architectures[string.strip(arch)] = "";
- for binary in string.split(binaries, ','):
- binary = string.strip(binary);
+ for arch in architecture.split():
+ architectures[arch.strip()] = "";
+ for binary in binaries.split(','):
+ binary = binary.strip();
q = projectB.query("SELECT a.arch_string, b.version FROM binaries b, bin_associations ba, architecture a WHERE ba.suite = %s AND ba.bin = b.id AND b.architecture = a.id AND b.package = '%s'" % (suite_id, binary));
ql = q.getresult();
if not ql:
if src_pkgs.has_key(source):
print " %s is a duplicated source package (%s and %s)" % (source, source_index, src_pkgs[source]);
src_pkgs[source] = source_index;
- for binary in string.split(binaries, ','):
- binary = string.strip(binary);
+ for binary in binaries.split(','):
+ binary = binary.strip();
if bin_pkgs.has_key(binary):
- print " %s is duplicated in %s and %s" % (binary, source, bin_pkgs[binary]);
+ print " binary %s is duplicated in source packages %s and %s" % (binary, source, bin_pkgs[binary]);
bin_pkgs[binary] = source;
source_binaries[source] = binaries;
source = Packages.Section.Find('Source', "");
if source == "":
source = package;
- if string.find(source, "(") != -1:
+ if source.find("(") != -1:
m = utils.re_extract_src_version.match(source)
source = m.group(1)
if not bin_pkgs.has_key(package) and not miss_src.has_key(package):
# rhona, cleans up unassociated binary and source packages
# Copyright (C) 2000, 2001, 2002 James Troup <james@nocrew.org>
-# $Id: rhona,v 1.24 2002-05-23 12:18:32 troup Exp $
+# $Id: rhona,v 1.25 2002-10-16 02:47:32 troup Exp $
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
print "Cleaning out packages..."
- date = time.strftime("%Y-%m-%d", time.localtime(time.time()));
+ date = time.strftime("%Y-%m-%d");
dest = Cnf["Dir::Morgue"] + '/' + Cnf["Rhona::MorgueSubDir"] + '/' + date;
if not os.path.exists(dest):
os.mkdir(dest);
continue;
if os.path.isfile(filename):
if os.path.islink(filename):
- count = count + 1;
+ count += 1;
if Options["No-Action"]:
print "Removing symlink %s..." % (filename);
else:
os.unlink(filename);
else:
- size = size + os.stat(filename)[stat.ST_SIZE];
- count = count + 1;
+ size += os.stat(filename)[stat.ST_SIZE];
+ count += 1;
dest_filename = dest + '/' + os.path.basename(filename);
# If the destination file exists; try to find another filename to use
maintainer_id = i[0];
if not Options["No-Action"]:
projectB.query("DELETE FROM maintainer WHERE id = %s" % (maintainer_id));
- count = count + 1;
+ count += 1;
projectB.query("COMMIT WORK");
if count > 0:
fingerprint_id = i[0];
if not Options["No-Action"]:
projectB.query("DELETE FROM fingerprint WHERE id = %s" % (fingerprint_id));
- count = count + 1;
+ count += 1;
projectB.query("COMMIT WORK");
if count > 0:
if not Cnf.FindB("Dinstall::SecurityAcceptedAutoBuild") and not os.path.islink(filename):
utils.fubar("%s (from accepted_autobuild) should be a symlink but isn't." % (filename));
os.unlink(filename);
- count = count + 1;
+ count += 1;
projectB.query("DELETE FROM accepted_autobuild WHERE last_used <= '%s'" % (our_delete_date));
if count:
if Options["Help"]:
usage();
- now_date = time.strftime("%Y-%m-%d %H:%M", time.localtime(time.time()));
+ now_date = time.strftime("%Y-%m-%d %H:%M");
delete_date = time.strftime("%Y-%m-%d %H:%M", time.localtime(time.time()-int(Cnf["Rhona::StayOfExecution"])));
check_binaries();
# Clean incoming of old unused files
# Copyright (C) 2000, 2001, 2002 James Troup <james@nocrew.org>
-# $Id: shania,v 1.16 2002-05-23 09:54:23 troup Exp $
+# $Id: shania,v 1.17 2002-10-16 02:47:32 troup Exp $
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
################################################################################
+# <aj> Bdale, a ham-er, and the leader,
+# <aj> Willy, a GCC maintainer,
+# <aj> Lamont-work, 'cause he's the top uploader....
+# <aj> Penguin Puff' save the day!
+# <aj> Porting code, trying to build the world,
+# <aj> Here they come just in time...
+# <aj> The Penguin Puff' Guys!
+# <aj> [repeat]
+# <aj> Penguin Puff'!
+# <aj> willy: btw, if you don't maintain gcc you need to start, since
+# the lyrics fit really well that way
+
+################################################################################
+
import os, stat, sys, time;
import utils;
import apt_pkg;
# Ensure a directory exists to remove files to
if not Options["No-Action"]:
- date = time.strftime("%Y-%m-%d", time.localtime(time.time()));
+ date = time.strftime("%Y-%m-%d");
del_dir = Cnf["Dir::Morgue"] + '/' + Cnf["Shania::MorgueSubDir"] + '/' + date;
if not os.path.exists(del_dir):
os.makedirs(del_dir, 02775);
for i in os.listdir('.'):
if os.path.isfile(i):
all_files[i] = 1;
- if i[-8:] == ".changes":
+ if i.endswith(".changes"):
changes_files.append(i);
# Proces all .changes and .dsc files.
dsc_files = {};
for file in files.keys():
- if file[-4:] == ".dsc":
+ if file.endswith(".dsc"):
try:
dsc = utils.parse_changes(file);
dsc_files = utils.build_file_list(dsc, is_a_dsc=1);
# Sanity check the database
# Copyright (C) 2000, 2001, 2002 James Troup <james@nocrew.org>
-# $Id: tea,v 1.20 2002-06-08 00:23:51 troup Exp $
+# $Id: tea,v 1.21 2002-10-16 02:47:32 troup Exp $
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
################################################################################
-import pg, sys, os, string, stat, time
+import pg, sys, os, stat, time
import utils, db_access
import apt_pkg, apt_inst;
def process_dir (unused, dirname, filenames):
global waste, db_files, excluded;
- if string.find(dirname, '/disks-') != -1 or string.find(dirname, 'upgrade-') != -1:
+ if dirname.find('/disks-') != -1 or dirname.find('upgrade-') != -1:
return;
# hack; can't handle .changes files
- if string.find(dirname, 'proposed-updates') != -1:
+ if dirname.find('proposed-updates') != -1:
return;
for name in filenames:
filename = os.path.abspath(dirname+'/'+name);
- filename = string.replace(filename, 'potato-proposed-updates', 'proposed-updates');
+ filename = filename.replace('potato-proposed-updates', 'proposed-updates');
if os.path.isfile(filename) and not os.path.islink(filename) and not db_files.has_key(filename) and not excluded.has_key(filename):
- waste = waste + os.stat(filename)[stat.ST_SIZE];
+ waste += os.stat(filename)[stat.ST_SIZE];
print filename
################################################################################
for component in Cnf.SubTree("Component").List():
if component == "mixed":
continue;
- component = string.lower(component);
+ component = component.lower();
list_filename = '%s%s_%s_source.list' % (Cnf["Dir::Lists"], suite, component);
list_file = utils.open_file(list_filename);
for line in list_file.readlines():
utils.parse_changes(file, dsc_whitespace_rules=1);
except utils.invalid_dsc_format_exc, line:
utils.warn("syntax error in .dsc file '%s', line %s." % (file, line));
- count = count + 1;
+ count += 1;
if count:
utils.warn("Found %s invalid .dsc files." % (count));
first_filename = "";
broken = 0;
for j in q2.getresult():
- filename = j[0]+j[1];
+ filename = j[0] + j[1];
path = os.path.dirname(filename);
if first_path == "":
first_path = path;
broken = 1;
print "WOAH, we got a live one here... %s [%s] {%s}" % (filename, source_id, symlink);
if broken:
- broken_count = broken_count + 1;
+ broken_count += 1;
print "Found %d source packages where the source is not all in one directory." % (broken_count);
################################################################################
apt_inst.debExtract(file,Ent,"control.tar.gz");
file.seek(0);
apt_inst.debExtract(file,Ent,"data.tar.gz");
- count = count + 1;
+ count += 1;
print "Checked %d files (out of %d)." % (count, len(db_files.keys()));
################################################################################
has_tar = 1;
if not has_tar:
utils.warn("%s has no .tar.gz in the .dsc file." % (file));
- count = count + 1;
+ count += 1;
if count:
utils.warn("Found %s invalid .dsc files." % (count));
# Check utils.parse_changes()'s for handling of multi-line fields
# Copyright (C) 2000 James Troup <james@nocrew.org>
-# $Id: test.py,v 1.1 2001-05-17 01:17:54 troup Exp $
+# $Id: test.py,v 1.2 2002-10-16 02:47:32 troup Exp $
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
################################################################################
-import os, string, sys
+import os, sys
sys.path.append(os.path.abspath('../../'));
def fail(message):
sys.stderr.write("%s\n" % (message));
sys.exit(1);
-
+
################################################################################
def main ():
if o != "":
del changes["binary"]
changes["binary"] = {}
- for j in string.split(o):
+ for j in o.split():
changes["binary"][j] = 1
if not changes["binary"].has_key("krb5-ftpd"):
# Check utils.extract_component_from_section()
# Copyright (C) 2000 James Troup <james@nocrew.org>
-# $Id: test.py,v 1.2 2002-01-19 18:58:07 troup Exp $
+# $Id: test.py,v 1.3 2002-10-16 02:47:32 troup Exp $
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
################################################################################
-import os, string, sys
+import os, sys;
sys.path.append(os.path.abspath('../../'));
def fail(message):
sys.stderr.write("%s\n" % (message));
sys.exit(1);
-
+
################################################################################
# prefix: non-US
def test(input, output):
result = utils.extract_component_from_section(input);
if result != output:
- fail ("%s -> %s [should have been %s]" % (input, repr(result), repr(output)));
+ fail ("%s -> %r [should have been %r]" % (input, result, output));
def main ():
# Err, whoops? should probably be "utils", "main"...
+#!/usr/bin/env python
+
# Utility functions
# Copyright (C) 2000, 2001, 2002 James Troup <james@nocrew.org>
-# $Id: utils.py,v 1.50 2002-07-14 15:01:04 troup Exp $
+# $Id: utils.py,v 1.51 2002-10-16 02:47:32 troup Exp $
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
def extract_component_from_section(section):
component = "";
- if string.find(section, '/') != -1:
- component = string.split(section, '/')[0];
- if string.lower(component) == "non-us" and string.count(section, '/') > 0:
- s = component + '/' + string.split(section, '/')[1];
+ if section.find('/') != -1:
+ component = section.split('/')[0];
+ if component.lower() == "non-us" and section.count('/') > 0:
+ s = component + '/' + section.split('/')[1];
if Cnf.has_key("Component::%s" % s): # Avoid e.g. non-US/libs
component = s;
- if string.lower(section) == "non-us":
+ if section.lower() == "non-us":
component = "non-US/main";
# non-US prefix is case insensitive
- if string.lower(component)[:6] == "non-us":
+ if component.lower()[:6] == "non-us":
component = "non-US"+component[6:];
# Expand default component
index = 0;
indexed_lines = {};
for line in lines:
- index = index + 1;
+ index += 1;
indexed_lines[index] = line[:-1];
inside_signature = 0;
index = 0;
first = -1;
while index < max(indices):
- index = index + 1;
+ index += 1;
line = indexed_lines[index];
if line == "":
if dsc_whitespace_rules:
- index = index + 1;
+ index += 1;
if index > max(indices):
raise invalid_dsc_format_exc, index;
line = indexed_lines[index];
- if string.find(line, "-----BEGIN PGP SIGNATURE") != 0:
+ if not line.startswith("-----BEGIN PGP SIGNATURE"):
raise invalid_dsc_format_exc, index;
inside_signature = 0;
break;
- if string.find(line, "-----BEGIN PGP SIGNATURE") == 0:
+ if line.startswith("-----BEGIN PGP SIGNATURE"):
break;
- if string.find(line, "-----BEGIN PGP SIGNED MESSAGE") == 0:
+ if line.startswith("-----BEGIN PGP SIGNED MESSAGE"):
if dsc_whitespace_rules:
inside_signature = 1;
while index < max(indices) and line != "":
- index = index + 1;
+ index += 1;
line = indexed_lines[index];
continue;
slf = re_single_line_field.match(line);
if slf:
- field = string.lower(slf.groups()[0]);
+ field = slf.groups()[0].lower();
changes[field] = slf.groups()[1];
first = 1;
continue;
if line == " .":
- changes[field] = changes[field] + '\n';
+ changes[field] += '\n';
continue;
mlf = re_multi_line_field.match(line);
if mlf:
if first == -1:
raise changes_parse_error_exc, "'%s'\n [Multi-line field continuing on from nothing?]" % (line);
if first == 1 and changes[field] != "":
- changes[field] = changes[field] + '\n';
+ changes[field] += '\n';
first = 0;
- changes[field] = changes[field] + mlf.groups()[0] + '\n';
+ changes[field] += mlf.groups()[0] + '\n';
continue;
- error = error + line;
+ error += line;
if dsc_whitespace_rules and inside_signature:
raise invalid_dsc_format_exc, index;
changes_in.close();
- changes["filecontents"] = string.join (lines, "");
+ changes["filecontents"] = "".join(lines);
if error != "":
raise changes_parse_error_exc, error;
if not changes.has_key("files"):
raise no_files_exc
- for i in string.split(changes["files"], "\n"):
+ for i in changes["files"].split("\n"):
if i == "":
break
- s = string.split(i)
+ s = i.split();
section = priority = "";
try:
if is_a_dsc:
if m != None and len(m.groups()) == 2:
name = m.group(1)
email = m.group(2)
- if string.find(name, ',') != -1 or string.find(name, '.') != -1:
+ if name.find(',') != -1 or name.find('.') != -1:
rfc822 = re_parse_maintainer.sub(r"\2 (\1)", maintainer)
return (rfc822, name, email)
def poolify (source, component):
if component != "":
- component = component + '/';
+ component += '/';
# FIXME: this is nasty
- component = string.lower(component);
- component = string.replace(component, 'non-us/', 'non-US/');
+ component = component.lower().replace('non-us/', 'non-US/');
if source[:3] == "lib":
return component + source[:4] + '/' + source + '/'
else:
os.umask(umask);
#print "Moving %s to %s..." % (src, dest);
if os.path.exists(dest) and os.path.isdir(dest):
- dest = dest + '/' + os.path.basename(src);
+ dest += '/' + os.path.basename(src);
# Don't overwrite unless forced to
if os.path.exists(dest):
if not overwrite:
os.umask(umask);
#print "Copying %s to %s..." % (src, dest);
if os.path.exists(dest) and os.path.isdir(dest):
- dest = dest + '/' + os.path.basename(src);
+ dest += '/' + os.path.basename(src);
# Don't overwrite unless forced to
if os.path.exists(dest):
if not overwrite:
# (woefully incomplete)
def regex_safe (s):
- s = string.replace(s, '+', '\\\\+');
- s = string.replace(s, '.', '\\\\.');
+ s = s.replace('+', '\\\\+');
+ s = s.replace('.', '\\\\.');
return s
######################################################################################
file = open_file(filename);
template = file.read();
for x in map.keys():
- template = string.replace(template,x,map[x]);
+ template = template.replace(x,map[x]);
file.close();
return template;
# Returns the user name with a laughable attempt at rfc822 conformancy
# (read: removing stray periods).
def whoami ():
- return string.replace(string.split(pwd.getpwuid(os.getuid())[4],',')[0], '.', '');
+ return pwd.getpwuid(os.getuid())[4].split(',')[0].replace('.', '');
######################################################################################
if o != "":
del changes["architecture"]
changes["architecture"] = {}
- for j in string.split(o):
+ for j in o.split():
changes["architecture"][j] = 1
# Sort by source name, source version, 'have source', and then by filename
orig_dest = dest;
while os.path.exists(dest) and extra < too_many:
dest = orig_dest + '.' + repr(extra);
- extra = extra + 1;
+ extra += 1;
if extra >= too_many:
raise tried_too_hard_exc;
return dest;
list.append("");
else:
list.append(original[i]);
- return string.join(list, sep);
+ return sep.join(list);
################################################################################
def prefix_multi_line_string(str, prefix):
out = "";
- for line in string.split(str, '\n'):
- line = string.strip(line);
+ for line in str.split('\n'):
+ line = line.strip();
if line:
- out = out + "%s%s\n" % (prefix, line);
+ out += "%s%s\n" % (prefix, line);
# Strip trailing new line
if out:
out = out[:-1];
error = None;
orig_filename = file
- if file[-6:] == ".katie":
+ if file.endswith(".katie"):
file = file[:-6]+".changes";
- if file[-8:] != ".changes":
+ if not file.endswith(".changes"):
error = "invalid file type; not a changes file";
else:
if not os.access(file,os.R_OK):
def join_with_commas_and(list):
if len(list) == 0: return "nothing";
if len(list) == 1: return list[0];
- return string.join(list[:-1], ", ") + " and " + list[-1];
+ return ", ".join(list[:-1]) + " and " + list[-1];
################################################################################
# Process suite
if Options["Suite"]:
suite_ids_list = [];
- for suite in string.split(Options["Suite"]):
+ for suite in Options["Suite"].split():
suite_id = db_access.get_suite_id(suite);
if suite_id == -1:
- utils.warn("suite '%s' not recognised." % (suite));
+ warn("suite '%s' not recognised." % (suite));
else:
suite_ids_list.append(suite_id);
if suite_ids_list:
- con_suites = "AND su.id IN (%s)" % string.join(map(str, suite_ids_list), ", ");
+ con_suites = "AND su.id IN (%s)" % ", ".join(map(str, suite_ids_list));
else:
fubar("No valid suite given.");
else:
# Process component
if Options["Component"]:
component_ids_list = [];
- for component in string.split(Options["Component"]):
+ for component in Options["Component"].split():
component_id = db_access.get_component_id(component);
if component_id == -1:
warn("component '%s' not recognised." % (component));
else:
component_ids_list.append(component_id);
if component_ids_list:
- con_components = "AND c.id IN (%s)" % string.join(map(str, component_ids_list), ", ");
+ con_components = "AND c.id IN (%s)" % ", ".join(map(str, component_ids_list));
else:
fubar("No valid component given.");
else:
if Options["Architecture"]:
arch_ids_list = [];
check_source = 0;
- for architecture in string.split(Options["Architecture"]):
+ for architecture in Options["Architecture"].split():
if architecture == "source":
check_source = 1;
else:
else:
arch_ids_list.append(architecture_id);
if arch_ids_list:
- con_architectures = "AND a.id IN (%s)" % string.join(map(str, arch_ids_list), ", ");
+ con_architectures = "AND a.id IN (%s)" % ", ".join(map(str, arch_ids_list));
else:
if not check_source:
fubar("No valid architecture given.");
# Create all the Release files
# Copyright (C) 2001, 2002 Anthony Towns <ajt@debian.org>
-# $Id: ziyi,v 1.22 2002-06-08 00:18:47 troup Exp $
+# $Id: ziyi,v 1.23 2002-10-16 02:47:32 troup Exp $
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
################################################################################
-import sys, os, popen2, tempfile, stat, string, time
+import sys, os, popen2, tempfile, stat, time
import utils
import apt_pkg
def compressnames (tree,type,file):
compress = AptCnf.get("%s::%s::Compress" % (tree,type), AptCnf.get("Default::%s::Compress" % (type), ". gzip"))
result = []
- cl = string.split(compress)
+ cl = compress.split()
uncompress = ("." not in cl)
- for mode in string.split(compress):
+ for mode in compress.split():
if mode == ".":
result.append(file)
elif mode == "gzip":
del x,r
break
f.write(x)
- size = size + len(x)
+ size += len(x)
f.flush()
f.seek(0)
return (size, f)
for name in files:
try:
if name[0] == "<":
- j = string.index(name, "/")
- k = string.index(name, ">")
+ j = name.index("/")
+ k = name.index(">")
(cat, ext, name) = (name[1:j], name[j+1:k], name[k+1:])
(size, file_handle) = create_temp_file("%s %s%s%s" %
(cat, path, name, ext))
print "Skipping: " + suite + " (untouchable)"
continue
- suite = string.lower(suite)
+ suite = suite.lower()
origin = SuiteBlock["Origin"]
label = SuiteBlock.get("Label", origin)
out.write("Date: %s\n" % (time.strftime("%a, %d %b %Y %H:%M:%S UTC", time.gmtime(time.time()))))
if notautomatic != "":
out.write("NotAutomatic: %s\n" % (notautomatic))
- out.write("Architectures: %s\n" % (string.join(filter(utils.real_arch, SuiteBlock.ValueList("Architectures")))))
+ out.write("Architectures: %s\n" % (" ".join(filter(utils.real_arch, SuiteBlock.ValueList("Architectures")))))
if components:
- out.write("Components: %s\n" % (string.join(components)))
+ out.write("Components: %s\n" % (" ".join(components)))
out.write("Description: %s\n" % (SuiteBlock["Description"]))
files = []
if AptCnf.has_key("tree::%s" % (tree)):
- for sec in string.split(AptCnf["tree::%s::Sections" % (tree)]):
- for arch in string.split(AptCnf["tree::%s::Architectures" % (tree)]):
+ for sec in AptCnf["tree::%s::Sections" % (tree)].split():
+ for arch in AptCnf["tree::%s::Architectures" % (tree)].split():
if arch == "source":
for file in compressnames("tree::%s" % (tree), "Sources", "%s/%s/Sources" % (sec, arch)):
files.append(file)
try:
release = open(relpath, "w")
- #release = open(string.replace(longsuite,"/","_") + "_" + arch + "_" + sec + "_Release", "w")
+ #release = open(longsuite.replace("/","_") + "_" + arch + "_" + sec + "_Release", "w")
except IOError:
utils.fubar("Couldn't write to " + relpath);
files.append(rel)
if AptCnf.has_key("tree::%s/main" % (tree)):
- sec = string.split(AptCnf["tree::%s/main::Sections" % (tree)])[0]
+ sec = AptCnf["tree::%s/main::Sections" % (tree)].split()[0]
if sec != "debian-installer":
print "ALERT: weird non debian-installer section in %s" % (tree)
- for arch in string.split(AptCnf["tree::%s/main::Architectures" % (tree)]):
+ for arch in AptCnf["tree::%s/main::Architectures" % (tree)].split():
if arch != "source": # always true
for file in compressnames("tree::%s/main" % (tree), "Packages", "main/%s/binary-%s/Packages" % (sec, arch)):
files.append(file)
elif AptCnf.has_key("bindirectory::%s" % (tree)):
for file in compressnames("bindirectory::%s" % (tree), "Packages", AptCnf["bindirectory::%s::Packages" % (tree)]):
- files.append(string.replace(file,tree+"/","",1))
+ files.append(file.replace(tree+"/","",1))
for file in compressnames("bindirectory::%s" % (tree), "Sources", AptCnf["bindirectory::%s::Sources" % (tree)]):
- files.append(string.replace(file,tree+"/","",1))
+ files.append(file.replace(tree+"/","",1))
else:
print "ALERT: no tree/bindirectory for %s" % (tree)
if Cnf.has_key("Dinstall::SigningKeyring"):
keyring = "--secret-keyring \"%s\"" % Cnf["Dinstall::SigningKeyring"]
if Cnf.has_key("Dinstall::SigningPubKeyring"):
- keyring = keyring + " --keyring \"%s\"" % Cnf["Dinstall::SigningPubKeyring"]
+ keyring += " --keyring \"%s\"" % Cnf["Dinstall::SigningPubKeyring"]
arguments = "--no-options --batch --no-tty --armour"
if Cnf.has_key("Dinstall::SigningKeyIds"):
- signkeyids = string.split(Cnf["Dinstall::SigningKeyIds"])
+ signkeyids = Cnf["Dinstall::SigningKeyIds"].split()
else:
signkeyids = [""]