...
 
Commits (10)
    https://gitcode.net/Netto2009/dak/-/commit/65eee09bc463e4fb517fd3d610437f7972591e92 ContentsTestCase: accept `IntegrityError` in addition to `FlushError` 2023-03-22T19:38:20+01:00 Ansgar ansgar@debian.org SQLAlchemy 1.4 raises `IntegrityError` here. https://gitcode.net/Netto2009/dak/-/commit/dce43697acb6094b8a3131dbf49fc7b0ceb69ddd ORMObject: drop `clone` member function 2023-03-22T19:38:25+01:00 Ansgar ansgar@debian.org The tests for `clone()` fail in Debian bookworm and the function seems unused. https://gitcode.net/Netto2009/dak/-/commit/bf8480486b2af1295cddb9e8e22a31eebc436e44 dm_command: set `DEBEMAIL` and `DEBFULLNAME` 2023-03-22T19:38:25+01:00 Ansgar ansgar@debian.org `dcut` is unhappy when it has no name or email address, but this can happen in some environments like containers. Set the variables to avoid failures. https://gitcode.net/Netto2009/dak/-/commit/80343838d579b868c952a4cefb393262883506dc newer_version: explicitly specify which relationship's parent to use 2023-03-22T19:38:25+01:00 Ansgar ansgar@debian.org SQLAlchemy 1.3 and 1.4 disagree whether to use `DBBinary.suites` (SQLA 1.3) or `DBSource.suites` (SQLA 1.4). Explicitly specify which one to use. https://gitcode.net/Netto2009/dak/-/commit/1d539f9a799df2e831da31260ec3fa5b745f5e6f cruft.py: add some type annotations 2023-03-22T19:38:26+01:00 Ansgar ansgar@debian.org https://gitcode.net/Netto2009/dak/-/commit/1af0bbf7e43782efed5dca273a606f21aefa4a2d Add a script to allow remote triggering of copy-installer 2023-04-10T23:08:41+02:00 Joerg Jaspert joerg@debian.org https://gitcode.net/Netto2009/dak/-/commit/1a408847504639db23006d0dfa189186e6adb476 One should use the SOURCE/DEST one allows to have, tssk. 2023-04-10T23:12:26+02:00 Joerg Jaspert joerg@debian.org https://gitcode.net/Netto2009/dak/-/commit/92d929ab389e281beae74392950134264becc84b Instead of summarizing and doing nothing, actually hardlink files 2023-04-12T22:47:45+02:00 Joerg Jaspert joerg@debian.org https://gitcode.net/Netto2009/dak/-/commit/f013f806ab29afc49af85ddd8d98d4bd2c201429 Allow trigger of copy_installer 2023-04-27T21:40:10+02:00 Joerg Jaspert joerg@debian.org https://gitcode.net/Netto2009/dak/-/commit/e6474090f5729486f0d938404bb5bfb068c152dc Merge branch 'master' into deploy 2023-04-27T21:40:40+02:00 Joerg Jaspert joerg@debian.org * master: Allow trigger of copy_installer Instead of summarizing and doing nothing, actually hardlink files One should use the SOURCE/DEST one allows to have, tssk. Add a script to allow remote triggering of copy-installer cruft.py: add some type annotations newer_version: explicitly specify which relationship's parent to use dm_command: set `DEBEMAIL` and `DEBFULLNAME` ORMObject: drop `clone` member function ContentsTestCase: accept `IntegrityError` in addition to `FlushError`
......@@ -182,7 +182,7 @@ function dedup() {
cd "${archiveroot}"
for dir in doc indices project tools; do
if [[ -d ${dir} ]]; then
jdupes --hardlink --noempty --quiet --summarize --recurse ${dir}
jdupes --hardlink --noempty --quiet --linkhard --recurse ${dir}
fi
done
done
......
......@@ -19,3 +19,6 @@ command="rsync --server --delete -vvlogDtpre.iLsfx . /srv/ftp.debian.org/web/def
## rrd file
command="rsync --server -vlogDtpre.iLsfx . /srv/ftp.debian.org/web/stat/deferred.rrd",restrict,from="128.31.0.69,2603:400a:ffff:bb8::801f:45,usper.debian.org" ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHyX7qEexkQ7YW6nskVxwF2zGAX8oJB56Tb7DlxM46Pu sync deferred rrd file
## dak copy installer
command="/srv/ftp-master.debian.org/dak/scripts/debian/copy_installer",restrict,from="195.192.210.131,2a02:16a8:dc41:100::131,respighi.debian.org" ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDSzZLd6Mqv1kZ57z5kZ4IYTf83cLLoP2fJTv35BZej9yrRyQEBbXuikkfjRhExJZioe3XNO5tLEYYN1aKlbOAU2q3JCuOzX2SzQ/OkDkfRGyiMEFjcyrL/LFfnJIHniugHV81t3EbHI/hKCzGijgDlh8X4GvKm01zy/2p1YQQr71ggiPfXGv0cJluUTN/iumrVjERRF6JRt9B9ldq+XlvXuR9jA1wGPse6p823+rNg06V8R709u9d+aV0qmM5OjVEjDsbq7DJ/KzxJkOxyurGJdqQGbU4j2yK0mATXH2PFH9lSATpiHCdsgHfrjIAO/OKzM8FMH/7PSD1Vl97SQPnObssTNjBabm0PrQNAxgwTXBKX29wmZf/3jn9dqRbF1tebo0+Xul+TpFFZ5gpMQLPGNaSlESm9UiIn7wI6LQ8/9rbbDACHONVvQAkK0111eY0OStno1XEf6Ul6DE35Ks1ZllD9E2AnvLChnuzvGtKScfjqBxM61FnwS+vw6R0Bmoc= kibi@tokyo
......@@ -27,7 +27,7 @@ from sqlalchemy import func
from sqlalchemy.orm import object_session, aliased
def newer_version(lowersuite_name, highersuite_name, session, include_equal=False):
def newer_version(lowersuite_name: str, highersuite_name: str, session, include_equal=False) -> list[tuple[str, str, str]]:
'''
Finds newer versions in lowersuite_name than in highersuite_name. Returns a
list of tuples (source, higherversion, lowerversion) where higherversion is
......@@ -53,9 +53,9 @@ def newer_version(lowersuite_name, highersuite_name, session, include_equal=Fals
func.max(DBSource.version).label('version'),
Architecture.arch_string,
func.max(DBBinary.version).label('binversion')). \
join(DBSource). \
with_parent(suite). \
join(Architecture). \
filter(DBBinary.suites.contains(suite)). \
join(DBBinary.source). \
join(DBBinary.architecture). \
group_by(
DBBinary.package,
DBSource.source,
......@@ -89,9 +89,9 @@ def newer_version(lowersuite_name, highersuite_name, session, include_equal=Fals
DBSource.version,
Architecture.arch_string
). \
join(DBSource). \
with_parent(highersuite). \
join(Architecture). \
filter(DBBinary.suites.contains(highersuite)). \
join(DBBinary.source). \
join(DBBinary.architecture). \
filter(DBSource.source == source). \
subquery()
q2 = session.query(q1.c.arch_string).group_by(q1.c.arch_string)
......@@ -132,7 +132,7 @@ def newer_version(lowersuite_name, highersuite_name, session, include_equal=Fals
return list
def get_package_names(suite):
def get_package_names(suite: Suite):
'''
Returns a query that selects all distinct package names from suite ordered
by package name.
......@@ -149,7 +149,7 @@ class NamedSource:
suite.
'''
def __init__(self, suite, source):
def __init__(self, suite: Suite, source: str):
self.source = source
query = suite.sources.filter_by(source=source). \
order_by(DBSource.version)
......@@ -171,7 +171,7 @@ class DejavuBinary:
built from multiple source packages.
'''
def __init__(self, suite, package):
def __init__(self, suite: Suite, package: str):
self.package = package
session = object_session(suite)
# We need a subquery to make sure that both binary and source packages
......@@ -184,7 +184,7 @@ class DejavuBinary:
for source, in src_query:
self.sources.append(str(NamedSource(suite, source)))
def has_multiple_sources(self):
def has_multiple_sources(self) -> bool:
'Has the package been built by multiple sources?'
return len(self.sources) > 1
......@@ -192,7 +192,7 @@ class DejavuBinary:
return "%s built by: %s" % (self.package, ", ".join(self.sources))
def report_multiple_source(suite):
def report_multiple_source(suite: Suite) -> None:
'''
Reports binary packages built from multiple source package with different
names.
......@@ -208,7 +208,7 @@ def report_multiple_source(suite):
print()
def query_without_source(suite_id, session):
def query_without_source(suite_id: int, session):
"""searches for arch: all packages from suite that do no longer
reference a source package in the same suite
......@@ -230,7 +230,7 @@ def query_without_source(suite_id, session):
return session.execute(query, {'suite_id': suite_id})
def queryNBS(suite_id, session):
def queryNBS(suite_id: int, session):
"""This one is really complex. It searches arch != all packages that
are no longer built from current source packages in suite.
......@@ -305,7 +305,7 @@ with
return session.execute(query, {'suite_id': suite_id})
def queryNBS_metadata(suite_id, session):
def queryNBS_metadata(suite_id: int, session):
"""searches for NBS packages based on metadata extraction of the
newest source for a given suite"""
......
......@@ -220,42 +220,6 @@ class ORMObject:
return object_session(self)
def clone(self, session=None):
"""
Clones the current object in a new session and returns the new clone. A
fresh session is created if the optional session parameter is not
provided. The function will fail if a session is provided and has
unflushed changes.
RATIONALE: SQLAlchemy's session is not thread safe. This method clones
an existing object to allow several threads to work with their own
instances of an ORMObject.
WARNING: Only persistent (committed) objects can be cloned. Changes
made to the original object that are not committed yet will get lost.
The session of the new object will always be rolled back to avoid
resource leaks.
"""
if self.session() is None:
raise RuntimeError(
'Method clone() failed for detached object:\n%s' % self)
self.session().flush()
mapper = object_mapper(self)
primary_key = mapper.primary_key_from_instance(self)
object_class = self.__class__
if session is None:
session = DBConn().session()
elif len(session.new) + len(session.dirty) + len(session.deleted) > 0:
raise RuntimeError(
'Method clone() failed due to unflushed changes in session.')
new_object = session.query(object_class).get(primary_key)
session.rollback()
if new_object is None:
raise RuntimeError(
'Method clone() failed for non-persistent object:\n%s' % self)
return new_object
__all__.append('ORMObject')
......
......@@ -85,6 +85,8 @@ EOF
dm_command() {
export GNUPGHOME=$DDRING
export DEBEMAIL=someone@example.invalid
export DEBFULLNAME="Some One"
signer=$1
dm=$2
action=$3
......
#!/bin/bash
# Copyright (C) 2008,2010,2023 Joerg Jaspert <joerg@debian.org>
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
set -e
set -u
# Load up some standard variables
export SCRIPTVARS=/srv/ftp-master.debian.org/dak/config/debian/vars
. $SCRIPTVARS
INPUT=(${SSH_ORIGINAL_COMMAND})
VERSION="${INPUT[0]}"
SOURCE="${INPUT[1]:-"unstable"}"
DEST="${INPUT[2]:-"testing"}"
SOURCE=${SOURCE,,}
DEST=${DEST,,}
# Change to a known safe location
cd ${masterdir}
if [[ -d ${ftpdir}/dists/${SOURCE}/main/installer-amd64/${VERSION} ]]; then
echo "Copying installer version ${VERSION} from ${SOURCE} to ${DEST}"
dak copy-installer -s ${SOURCE} -d ${DEST} ${VERSION}
else
echo "Couldn't see installer version ${VERSION} in ${SOURCE}s dir, not doing anything"
exit 1
fi
echo "Done"
exit 0
......@@ -32,7 +32,10 @@ class ContentsTestCase(DBDakTestCase):
contents2 = BinContents(file='usr/bin/hello',
binary=self.binary['hello_2.2-1_i386'])
self.session.add(contents2)
self.assertRaises(FlushError, self.session.flush)
# SQLAlchemy 1.4 raises IntegrityError, previous versions
# raised FlushError.
# Reference: https://docs.sqlalchemy.org/en/14/changelog/changelog_14.html#change-f7b996813d7921f404e0cc8457951f9a
self.assertRaises((FlushError, IntegrityError), self.session.flush)
def test_duplicates2(self):
'''
......
......@@ -147,33 +147,6 @@ class SessionTestCase(DBDakTestCase):
self.session.add(uid)
self.assertEqual(self.session, uid.session())
def test_clone(self):
'''
Tests the ORMObject.clone() method.
'''
uid1 = Uid(uid='foobar')
# no session yet
self.assertRaises(RuntimeError, uid1.clone)
self.session.add(uid1)
# object not persistent yet
self.assertRaises(RuntimeError, uid1.clone)
self.session.commit()
# test without session parameter
uid2 = uid1.clone()
self.assertTrue(uid1 is not uid2)
self.assertEqual(uid1.uid, uid2.uid)
self.assertTrue(uid2 not in uid1.session())
self.assertTrue(uid1 not in uid2.session())
# test with explicit session parameter
new_session = DBConn().session()
uid3 = uid1.clone(session=new_session)
self.assertEqual(uid1.uid, uid3.uid)
self.assertTrue(uid3 in new_session)
# test for ressource leaks with mass cloning
for _ in range(1, 1000):
uid1.clone()
def classes_to_clean(self):
# We need to clean all Uid objects in case some test fails.
return (Uid,)
......