Commit c8b1c595 authored by Lisa's avatar Lisa

Add upload checks to akbm, defining a new command.

Failing checks causes a warning to be printed; the user is
responsible for follow-ups, e.g. asking the user for
confirmation before proceeding.

This allows to move some (incomplete and broken) check code
out of and into the server, where the files we
need to perform the checks are located already.
parent 3f128ddf
......@@ -36,6 +36,7 @@ import time
import pwd
import grp
from optparse import OptionParser
from sanity_checks import *
from subprocess import call
import tarfile
import contextlib
......@@ -149,6 +150,9 @@ def command_parse(config_opts):
parser.add_option("--repo-clean", action="store_const", const="repo-clean",
help="Clean the db")
parser.add_option("--repo-check-upload", action="store_const", const="repo-check-upload",
help="Sanity checks for a new upload")
parser.add_option("-l", "--lock", action="store_const", const="repo-lock",
help="Lock the db")
......@@ -158,7 +162,7 @@ def command_parse(config_opts):
parser.add_option("--recreate", action="store_const", const="repo-recreate",
help="[TODO] Recreate the whole db")
# options
parser.add_option("--arch", action ="store", dest="arch",
default='x86_64', help="Set the architecture, default: %default")
......@@ -447,7 +451,39 @@ def do_unlock_db(options, dbname, arch):
# let's lock the file
databaseunlock(dbpath + ".lock")
def do_check_upload(options, dbname, arch, args):
status_start("[SERVER] sanity check upload")
if options.dryrun:
return 0
pkgs = missingSignature(args)
if pkgs:
print('Missing signature for the following packages: %s' % str(pkgs))
return False
if options.dbname != 'lib32':
lib32_packages = checkLib32Package(CHAKRA_REPO, arch, args)
if lib32_packages:
print('The following lib32 packages exist, so they should be updated as soon '
'as possible if not done already:', lib32_packages)
return False
dups = checkDuplicates(CHAKRA_REPO, arch, options.dbname, args)
if dups:
print('The following packages already exist on the target repo: %s. Please verify '
'you have updated the pkgver or pkgrel correctly.' % dups)
return False
return True
def do_recreate_db(options, dbname, arch):
......@@ -502,6 +538,9 @@ def main(ret):
elif options.mode == 'repo-unlock':
do_unlock_db(options, options.dbname, options.arch)
elif options.mode == 'repo-check-upload':
do_check_upload(options, options.dbname, options.arch, args)
elif options.mode == 'repo-recreate':
do_recreate_db(options, options.dbname, options.arch)
# This is used by akbm when checking new uploads (repo-check-upload command).
import os
import re
def RemoveSignatureExtension(filename):
index = filename.index('.sig')
return filename[:index]
def IsPackageFile(filename):
return filename.endswith('.pkg.tar.xz')
def IsSignatureFile(filename):
return filename.endswith('.pkg.tar.xz.sig')
def GetPackageName(filename):
"""Retrieves the name of a package, without the version
and pkgrel, from the archive file name."""
pkgNames = []
pkgVerRe = '[0-9.]+'
# Divide the file name in pieces by -, then add pieces
# until you find a piece which represents a version (through
# regular expression). Then all the "name pieces" are joined
# together again to return the complete name.
# This should deal with package names containing numbers.
pieces = filename.split('-')
for p in pieces:
if re.match(pkgVerRe, p):
pkgName = '-'.join(pkgNames)
return pkgName
def missingSignature(filelist):
"""Checks whether there is a signature file for each
package file. Returns the list of package files with no
signature file."""
pkgsHasSig = {}
for f in filelist:
if IsPackageFile(f):
pkgsHasSig[f] = False
elif IsSignatureFile(f):
pkgsHasSig[RemoveSignatureExtension(f)] = True
return [x for x in pkgsHasSig if not pkgsHasSig[x]]
def checkDuplicates(reposPath, arch, repoName, filelist):
"""Checks whether the repository already contains the same
package file we are trying to upload. Returns the list of
duplicate files."""
repoPath = os.path.join(reposPath, repoName, arch)
dirListing = [ f for f in os.listdir(repoPath) if IsPackageFile(f) ]
intersection = set(filelist) & set(dirListing)
return intersection
# Calling this on a lib32 package should return an empty list.
def checkLib32Package(reposPath, arch, filelist):
"""Checks whether a package has a corresponding package in lib32. Returns
the list of lib32 package names that were found."""
repoPath = os.path.join(reposPath, 'lib32', arch)
repoListing = [ GetPackageName(f) for f in os.listdir(repoPath) if IsPackageFile(f) ]
packageNames32 = []
for pkgFile in filelist:
if IsSignatureFile(pkgFile):
pkgName = GetPackageName(pkgFile)
pkgName = 'lib32-' + pkgName
# We are not concerned with comparing versions, since that adds
# complexity, only whether a lib32 package exists or not.
if pkgName in repoListing:
return packageNames32
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment