Skip to content
Snippets Groups Projects
Verified Commit 3f6620bd authored by Kristian Klausen's avatar Kristian Klausen :tada:
Browse files

chore(cron-jobs): Remove obsolete integrity-check script and friends

The script was disabled over 7 years ago and just a month after
everything related to ABS was removed[2] (which the script depends on).

[1] archlinux/infrastructure@bcd20f65
[2] archlinux/infrastructure@184905ed
parent ea98599c
No related branches found
No related tags found
No related merge requests found
Pipeline #116960 passed
...@@ -8,9 +8,7 @@ The executables that you (might) care about are: ...@@ -8,9 +8,7 @@ The executables that you (might) care about are:
dbscripts/ dbscripts/
├── cron-jobs/ ├── cron-jobs/
│ ├── devlist-mailer
│ ├── ftpdir-cleanup │ ├── ftpdir-cleanup
│ ├── integrity-check
│ └── sourceballs │ └── sourceballs
├── db-move ├── db-move
├── db-remove ├── db-remove
...@@ -39,11 +37,6 @@ lower-level, but you don't want to go all the way down to pacman's ...@@ -39,11 +37,6 @@ lower-level, but you don't want to go all the way down to pacman's
- `db-repo-add` - `db-repo-add`
- `db-repo-remove` - `db-repo-remove`
Now, we'd like to be able to check that the repos are all OK, so we
have
- `cron-jobs/integrity-check`
When we remove a package from a repository, it stays in the package When we remove a package from a repository, it stays in the package
"pool". We would like to be able to eventually remove packages from "pool". We would like to be able to eventually remove packages from
the pool, to reclaim the disk space: the pool, to reclaim the disk space:
...@@ -52,7 +45,6 @@ the pool, to reclaim the disk space: ...@@ -52,7 +45,6 @@ the pool, to reclaim the disk space:
Things that haven't been mentioned yet: Things that haven't been mentioned yet:
- `cron-jobs/devlist-mailer`
- `cron-jobs/sourceballs` - `cron-jobs/sourceballs`
## Testing ## Testing
* Install the `make` and `podman` or `docker` packages depending on your * Install the `make` and `podman` or `docker` packages depending on your
......
...@@ -41,11 +41,6 @@ PKGEXT_DEFAULT=".pkg.tar.zst" ...@@ -41,11 +41,6 @@ PKGEXT_DEFAULT=".pkg.tar.zst"
# Allowed licenses: get sourceballs only for licenses in this array # Allowed licenses: get sourceballs only for licenses in this array
ALLOWED_LICENSES=('GPL' 'GPL1' 'GPL2' 'GPL3' 'LGPL' 'LGPL1' 'LGPL2' 'LGPL2.1' 'LGPL3' 'AGPL3') ALLOWED_LICENSES=('GPL' 'GPL1' 'GPL2' 'GPL3' 'LGPL' 'LGPL1' 'LGPL2' 'LGPL2.1' 'LGPL3' 'AGPL3')
# Where to send error emails, and who they are from
LIST="arch-dev-public@lists.archlinux.org"
#LIST="aaronmgriffin@gmail.com"
FROM="repomaint@archlinux.org"
# curated PATH to sanitize executables in a portable way # curated PATH to sanitize executables in a portable way
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
export PATH export PATH
......
#!/usr/bin/python2
#
# check_archlinux.py
#
# Original script by Scott Horowitz <stonecrest@gmail.com>
# Rewritten by Xavier Chantry <shiningxc@gmail.com>
#
# This script currently checks for a number of issues in your ABS tree:
# 1. Directories with missing PKGBUILDS
# 2. Invalid PKGBUILDs (bash syntax error for instance)
# 3. PKGBUILD names that don't match their directory
# 4. Duplicate PKGBUILDs
# 5. Valid arch's in PKGBUILDS
# 6. Missing (make-)dependencies
# 7. Hierarchy of repos (e.g., that a core package doesn't depend on
# a non-core package)
# 8. Circular dependencies
import os,re,commands,getopt,sys,tarfile
import pdb
import ctypes
_alpm = ctypes.cdll.LoadLibrary("libalpm.so")
DBEXT='.db.tar.gz'
packages = {} # pkgname : PacmanPackage
repopkgs = {} # pkgname : PacmanPackage
provisions = {} # provision : PacmanPackage
pkgdeps,makepkgdeps = {},{} # PacmanPackage : list of the PacmanPackage dependencies
invalid_pkgbuilds = []
missing_pkgbuilds = []
dups = []
dbonly = []
absonly = []
mismatches = []
missing_deps = []
missing_makedeps = []
invalid_archs = []
dep_hierarchy = []
makedep_hierarchy = []
circular_deps = [] # pkgname>dep1>dep2>...>pkgname
checked_deps = []
class PacmanPackage:
def __init__(self):
self.name,self.version = "",""
self.base = ""
self.path,self.repo = "",""
self.deps,self.makedeps = [],[]
self.provides,self.conflicts = [],[]
self.archs = []
class Depend:
def __init__(self,name,version,mod):
self.name = name
self.version = version
self.mod = mod
def parse_pkgbuilds(repos,arch):
for absroot in absroots:
for repo in repos:
cmd = os.path.dirname(os.path.realpath(sys.argv[0])) + '/parse_pkgbuilds.sh '
cmd += arch + ' ' + absroot + '/' + repo
(status,output) = commands.getstatusoutput(cmd)
if status != 0:
print "Error : failed to run '%s'" % cmd
sys.exit()
parse_data(repo,output)
def parse_data(repo,data):
attrname = None
for line in data.split('\n'):
if line.startswith('%'):
attrname = line.strip('%').lower()
elif line.strip() == '':
attrname = None
elif attrname == "invalid":
if repo in repos:
invalid_pkgbuilds.append(line)
elif attrname == "missing":
if repo in repos:
missing_pkgbuilds.append(line)
elif attrname == "name":
pkg = PacmanPackage()
pkg.name = line
pkg.repo = repo
dup = None
if pkg.name in packages:
dup = packages[pkg.name]
else:
packages[pkg.name] = pkg
elif attrname == "base":
pkg.base = line
elif attrname == "version":
pkg.version = line
elif attrname == "path":
pkg.path = line
if dup != None and (pkg.repo in repos or dup.repo in repos):
dups.append(pkg.path + " vs. " + dup.path)
elif attrname == "arch":
pkg.archs.append(line)
elif attrname == "depends":
pkg.deps.append(line)
elif attrname == "makedepends":
pkg.makedeps.append(line)
elif attrname == "conflicts":
pkg.conflicts.append(line)
elif attrname == "provides":
pkg.provides.append(line)
def parse_dbs(repos,arch):
dbpkgs = {}
for repo in repos:
pkgs = set([])
db = tarfile.open(os.path.join(repodir,repo,'os',arch,repo + DBEXT))
for line in db.getnames():
if not '/' in line:
pkgs.add(line.rsplit('-',2)[0])
dbpkgs[repo] = pkgs
return(dbpkgs)
def splitdep(dep):
name = dep
version = ""
mod = ""
for char in (">=", "<=", "=", ">", "<"):
pos = dep.find(char)
if pos > -1:
name = dep[:pos]
version = dep[pos:].replace(char, "")
mod = char
break
return Depend(name,version,mod)
def splitprov(prov):
name = prov
version = ""
pos = prov.find("=")
if pos > -1:
name = prov[:pos]
version = prov[pos:].replace("=", "")
return (name,version)
def vercmp(v1,mod,v2):
"""
>>> vercmp("1.0", "<=", "2.0")
True
>>> vercmp("1:1.0", ">", "2.0")
True
>>> vercmp("1.0.2", ">=", "2.1.0")
False
"""
s1 = ctypes.c_char_p(v1)
s2 = ctypes.c_char_p(v2)
res = _alpm.alpm_pkg_vercmp(s1,s2)
if res == 0:
return (mod.find("=") > -1)
elif res < 0:
return (mod.find("<") > -1)
elif res > 0:
return (mod.find(">") > -1)
return False
def depcmp(name,version,dep):
if name != dep.name:
return False
if dep.version == "" or dep.mod == "":
return True
if version == "":
return False
return vercmp(version,dep.mod,dep.version)
def provcmp(pkg,dep):
for prov in pkg.provides:
(provname,provver) = splitprov(prov)
if depcmp(provname,provver,dep):
return True
return False
def verify_dep(dep):
dep = splitdep(dep)
if dep.name in packages:
pkg = packages[dep.name]
if depcmp(pkg.name,pkg.version,dep):
return [pkg]
if dep.name in provisions:
provlist = provisions[dep.name]
results = []
for prov in provlist:
if provcmp(prov,dep):
results.append(prov)
return results
return []
def verify_deps(name,repo,deps):
pkg_deps = []
missdeps = []
hierarchy = []
for dep in deps:
pkglist = verify_dep(dep)
if pkglist == []:
missdeps.append(repo + "/" + name + " --> '" + dep + "'")
else:
valid_repos = get_repo_hierarchy(repo)
pkgdep = None
for pkg in pkglist:
if pkg.repo in valid_repos:
pkgdep = pkg
break
if not pkgdep:
pkgdep = pkglist[0]
hierarchy.append((repo,name,pkgdep))
pkg_deps.append(pkgdep)
return (pkg_deps,missdeps,hierarchy)
def compute_deplist(pkg):
list = []
stack = [pkg]
while stack != []:
dep = stack.pop()
if dep in pkgdeps:
for dep2 in pkgdeps[dep]:
if dep2 not in list:
list.append(dep2)
stack.append(dep2)
if dep in makepkgdeps:
for dep2 in makepkgdeps[dep]:
if dep2 not in list:
list.append(dep2)
stack.append(dep2)
return list
def check_hierarchy(deph):
hierarchy = []
for (repo,name,pkgdep) in deph:
deplist = compute_deplist(pkgdep)
valid_repos = get_repo_hierarchy(repo)
extdeps = []
for dep in deplist:
if dep.repo not in valid_repos:
extdeps.append(dep.name)
string = repo + "/" + name + " depends on " + pkgdep.repo + "/" + pkgdep.name + " ("
string += "%s extra (make)deps to pull" % len(extdeps)
if 0 < len(extdeps) < 10:
string += " : " + ' '.join(extdeps)
string += ")"
hierarchy.append(string)
return hierarchy
def get_repo_hierarchy(repo):
repo_hierarchy = {'core': ['core'], \
'extra': ['core', 'extra'], \
'community': ['core', 'extra', 'community'], \
'multilib': ['core', 'extra', 'community', 'multilib'] }
if repo in repo_hierarchy:
return repo_hierarchy[repo]
else:
return ['core','extra','community']
def verify_archs(name,repo,archs):
valid_archs = ['any', 'i686', 'x86_64']
invalid_archs = []
for arch in archs:
if arch not in valid_archs:
invalid_archs.append(repo + "/" + name + " --> " + arch)
return invalid_archs
def find_scc(packages):
# reset all variables
global index,S,pkgindex,pkglowlink
index = 0
S = []
pkgindex = {}
pkglowlink = {}
cycles = []
for pkg in packages:
tarjan(pkg)
def tarjan(pkg):
global index,S,pkgindex,pkglowlink,cycles
pkgindex[pkg] = index
pkglowlink[pkg] = index
index += 1
checked_deps.append(pkg)
S.append(pkg)
deps = []
if pkg in pkgdeps:
deps = pkgdeps[pkg]
for dep in deps:
if dep not in pkgindex:
tarjan(dep)
pkglowlink[pkg] = min(pkglowlink[pkg],pkglowlink[dep])
elif dep in S:
pkglowlink[pkg] = min(pkglowlink[pkg],pkgindex[dep])
if pkglowlink[pkg] == pkgindex[pkg]:
dep = S.pop()
if pkg == dep:
return
path = pkg.name
while pkg != dep:
path = dep.repo + "/" + dep.name + ">" + path
dep = S.pop()
path = dep.name + ">" + path
if pkg.repo in repos:
circular_deps.append(path)
def print_heading(heading):
print ""
print "=" * (len(heading) + 4)
print "= " + heading + " ="
print "=" * (len(heading) + 4)
def print_subheading(subheading):
print ""
print subheading
print "-" * (len(subheading) + 2)
def print_missdeps(pkgname,missdeps) :
for d in missdeps:
print pkgname + " : " + d
def print_result(list, subheading):
if len(list) > 0:
list.sort()
print_subheading(subheading)
for item in list:
print item
def print_results():
print_result(missing_pkgbuilds, "Missing PKGBUILDs")
print_result(invalid_pkgbuilds, "Invalid PKGBUILDs")
print_result(mismatches, "Mismatched Pkgnames")
print_result(dups, "Duplicate PKGBUILDs")
print_result(invalid_archs, "Invalid Archs")
print_result(missing_deps, "Missing Dependencies")
print_result(missing_makedeps, "Missing Makedepends")
print_result(dep_hierarchy, "Repo Hierarchy for Dependencies")
print_result(makedep_hierarchy, "Repo Hierarchy for Makedepends")
print_result(circular_deps, "Circular Dependencies")
print_result(dbonly, "Packages found in db, but not in tree")
print_result(absonly,"Packages found in tree, but not in db")
print_subheading("Summary")
print "Missing PKGBUILDs: ", len(missing_pkgbuilds)
print "Invalid PKGBUILDs: ", len(invalid_pkgbuilds)
print "Mismatching PKGBUILD names: ", len(mismatches)
print "Duplicate PKGBUILDs: ", len(dups)
print "Invalid archs: ", len(invalid_archs)
print "Missing (make)dependencies: ", len(missing_deps)+len(missing_makedeps)
print "Repo hierarchy problems: ", len(dep_hierarchy)+len(makedep_hierarchy)
print "Circular dependencies: ", len(circular_deps)
print "In db, but not in tree: ", len(dbonly)
print "In tree, but not in db: ", len(absonly)
print ""
def print_usage():
print ""
print "Usage: ./check_packages.py [OPTION]"
print ""
print "Options:"
print " --abs-tree=<path[,path]> Check the specified tree(s) (default : /var/abs)"
print " --repos=<r1,r2,...> Check the specified repos (default : core,extra)"
print " --arch=<i686|x86_64> Check the specified arch (default : x86_64)"
print " --repo-dir=<path> Check the dbs at the specified path (default : /srv/ftp)"
print " -h, --help Show this help and exit"
print ""
print "Examples:"
print "\n Check core and extra in existing abs tree:"
print " ./check_packages.py --abs-tree=/var/abs --repos=core,extra --arch=x86_64"
print "\n Check community:"
print " ./check_packages.py --abs-tree=/var/abs --repos=community --arch=x86_64"
print ""
if __name__ == "__main__":
## Default path to the abs root directory
absroots = ["/var/abs"]
## Default list of repos to check
repos = ['core', 'extra']
## Default arch
arch = "x86_64"
## Default repodir
repodir = "/srv/ftp"
try:
opts, args = getopt.getopt(sys.argv[1:], "", ["abs-tree=", "repos=",
"arch=", "repo-dir="])
except getopt.GetoptError:
print_usage()
sys.exit()
if opts != []:
for o, a in opts:
if o in ("--abs-tree"):
absroots = a.split(',')
elif o in ("--repos"):
repos = a.split(",")
elif o in ("--arch"):
arch = a
elif o in ("--repo-dir"):
repodir = a
else:
print_usage()
sys.exit()
if args != []:
print_usage()
sys.exit()
for absroot in absroots:
if not os.path.isdir(absroot):
print "Error : the abs tree " + absroot + " does not exist"
sys.exit()
for repo in repos:
repopath = absroot + "/" + repo
if not os.path.isdir(repopath):
print("Warning : the repository " + repo + " does not exist in " + absroot)
if not os.path.isdir(repodir):
print "Error: the repository directory %s does not exist" % repodir
sys.exit()
for repo in repos:
path = os.path.join(repodir,repo,'os',arch,repo + DBEXT)
if not os.path.isfile(path):
print "Error : repo DB %s : File not found" % path
sys.exit()
if not tarfile.is_tarfile(path):
print "Error : Cant open repo DB %s, not a valid tar file" % path
sys.exit()
# repos which need to be loaded
loadrepos = set([])
for repo in repos:
loadrepos = loadrepos | set(get_repo_hierarchy(repo))
print_heading("Integrity Check " + arch + " of " + ",".join(repos))
print("\nPerforming integrity checks...")
print("==> parsing pkgbuilds")
parse_pkgbuilds(loadrepos,arch)
# fill provisions
for name,pkg in packages.iteritems():
for prov in pkg.provides:
provname=prov.split("=")[0]
if provname not in provisions:
provisions[provname] = []
provisions[provname].append(pkg)
# fill repopkgs
for name,pkg in packages.iteritems():
if pkg.repo in repos:
repopkgs[name] = pkg
print("==> parsing db files")
dbpkgs = parse_dbs(repos,arch)
print("==> checking mismatches")
for name,pkg in repopkgs.iteritems():
pkgdirname = pkg.path.split("/")[-1]
if name != pkgdirname and pkg.base != pkgdirname:
mismatches.append(name + " vs. " + pkg.path)
print("==> checking archs")
for name,pkg in repopkgs.iteritems():
archs = verify_archs(name,pkg.repo,pkg.archs)
invalid_archs.extend(archs)
deph,makedeph = [],[]
print("==> checking dependencies")
for name,pkg in repopkgs.iteritems():
(deps,missdeps,hierarchy) = verify_deps(name,pkg.repo,pkg.deps)
pkgdeps[pkg] = deps
missing_deps.extend(missdeps)
deph.extend(hierarchy)
print("==> checking makedepends")
for name,pkg in repopkgs.iteritems():
(makedeps,missdeps,hierarchy) = verify_deps(name,pkg.repo,pkg.makedeps)
makepkgdeps[pkg] = makedeps
missing_makedeps.extend(missdeps)
makedeph.extend(hierarchy)
print("==> checking hierarchy")
dep_hierarchy = check_hierarchy(deph)
makedep_hierarchy = check_hierarchy(makedeph)
print("==> checking for circular dependencies")
# make sure pkgdeps is filled for every package
for name,pkg in packages.iteritems():
if pkg not in pkgdeps:
(deps,missdeps,_) = verify_deps(name,pkg.repo,pkg.deps)
pkgdeps[pkg] = deps
find_scc(repopkgs.values())
print("==> checking for differences between db files and pkgbuilds")
for repo in repos:
for pkg in dbpkgs[repo]:
if not (pkg in repopkgs and repopkgs[pkg].repo == repo):
dbonly.append("%s/%s" % (repo,pkg))
for name,pkg in repopkgs.iteritems():
if not name in dbpkgs[pkg.repo]:
absonly.append("%s/%s" % (pkg.repo,name))
print_results()
#!/bin/bash
# Usage : parse_pkgbuilds.sh arch <pkgbuilds_dir1,dir2,...>
# Example : parse_pkgbuilds.sh x86_64 /var/abs/core /var/abs/extra
exit() { return; }
splitpkg_overrides=('depends' 'optdepends' 'provides' 'conflicts')
variables=('pkgname' 'pkgbase' 'epoch' 'pkgver' 'pkgrel' 'makedepends' 'arch' "${splitpkg_overrides[@]}")
readonly -a variables splitpkg_overrides
backup_package_variables() {
for var in "${splitpkg_overrides[@]}"; do
declare -p "$var" 2>/dev/null || printf 'unset %q\n' "$var"
done
}
print_info() {
echo -e "%NAME%\n$pkgname\n"
if [ -n "$epoch" ]; then
echo -e "%VERSION%\n$epoch:$pkgver-$pkgrel\n"
else
echo -e "%VERSION%\n$pkgver-$pkgrel\n"
fi
echo -e "%PATH%\n$dir\n"
if [ -n "$pkgbase" ]; then
echo -e "%BASE%\n$pkgbase\n"
fi
if [ -n "$arch" ]; then
echo "%ARCH%"
for i in "${arch[@]}"; do echo "$i"; done
echo ""
fi
if [ -n "$depends" ]; then
echo "%DEPENDS%"
for i in "${depends[@]}"; do
echo "$i"
done
echo ""
fi
if [ -n "$makedepends" ]; then
echo "%MAKEDEPENDS%"
for i in "${makedepends[@]}"; do
echo "$i"
done
echo ""
fi
if [ -n "$conflicts" ]; then
echo "%CONFLICTS%"
for i in "${conflicts[@]}"; do echo "$i"; done
echo ""
fi
if [ -n "$provides" ]; then
echo "%PROVIDES%"
for i in "${provides[@]}"; do echo "$i"; done
echo ""
fi
}
source_pkgbuild() {
local restore_package_variables
ret=0
dir=$1
pkgbuild=$dir/PKGBUILD
for var in "${variables[@]}"; do
unset "${var}"
done
source "$pkgbuild" &>/dev/null || ret=$?
# ensure $pkgname and $pkgver variables were found
if [ $ret -ne 0 -o -z "$pkgname" -o -z "$pkgver" ]; then
echo -e "%INVALID%\n$pkgbuild\n"
return 1
fi
if [ "${#pkgname[@]}" -gt "1" ]; then
pkgbase=${pkgbase:-${pkgname[0]}}
for pkg in "${pkgname[@]}"; do
if [ "$(type -t "package_${pkg}")" != "function" ]; then
echo -e "%INVALID%\n$pkgbuild\n"
return 1
else
restore_package_variables=$(backup_package_variables)
pkgname=$pkg
while IFS= read -r line; do
var=${line%%=*}
var="${var#"${var%%[![:space:]]*}"}" # remove leading whitespace characters
for realvar in "${variables[@]}"; do
if [ "$var" == "$realvar" ]; then
eval $line
break
fi
done
done < <(type "package_${pkg}")
print_info
eval "$restore_package_variables"
fi
done
else
echo
print_info
fi
return 0
}
find_pkgbuilds() {
#Skip over some dirs
local d="${1##*/}"
if [ "$d" = "CVS" -o "$d" = ".svn" ]; then
return
fi
if [ -f "$1/PKGBUILD" ]; then
source_pkgbuild "$1"
return
fi
empty=1
for dir in "$1"/*; do
if [ -d "$dir" ]; then
find_pkgbuilds "$dir"
unset empty
fi
done
if [ -n "$empty" ]; then
echo -e "%MISSING%\n$1\n"
fi
}
if [ -z "$1" -o -z "$2" ]; then
exit 1
fi
CARCH=$1
shift
for dir in "$@"; do
find_pkgbuilds "$dir"
done
exit 0
#!/bin/bash
#Dummy helper to send email to arch-dev
# It does nothing if no output
# Load $LIST and $FROM from the config file
. "$(dirname "$(readlink -e "$0")")/../config"
SUBJECT="Repository Maintenance $(date +"%d-%m-%Y")"
if (( $# >= 1 )); then
SUBJECT="$1 $(date +"%d-%m-%Y")"
fi
if (( $# >= 2 )); then
LIST="$2"
fi
stdin="$(cat)"
#echo used to strip whitespace for checking for actual data
if [[ -n "$(echo $stdin)" ]]; then
echo "Subject: $SUBJECT
To: $LIST
From: $FROM
$stdin" | /usr/sbin/sendmail -F"$FROM" "$LIST"
fi
#!/bin/bash
dirname="$(dirname "$(readlink -e "$0")")"
. "${dirname}/../config"
. "${dirname}/../db-functions"
script_lock
if (( $# != 1 )); then
die "usage: %s <mailto>" "${0##*/}"
fi
mailto=$1
check() {
"${dirname}"/check_archlinux/check_packages.py \
--repos="${repos}" \
--abs-tree="/srv/abs/rsync/${arch},/srv/abs/rsync/any" \
--repo-dir="${FTP_BASE}" \
--arch="${arch}" \
2>&1 | "${dirname}"/devlist-mailer "Integrity Check ${arch}: ${repos}" "${mailto}"
}
repos='core,extra,community,multilib'
arch='x86_64'
check
script_unlock
...@@ -31,9 +31,7 @@ RUN pacman-key --init && \ ...@@ -31,9 +31,7 @@ RUN pacman-key --init && \
ln -sf /dbscripts/db-repo-remove /usr/local/bin/ && \ ln -sf /dbscripts/db-repo-remove /usr/local/bin/ && \
ln -sf /dbscripts/db-update /usr/local/bin/ && \ ln -sf /dbscripts/db-update /usr/local/bin/ && \
ln -sf /dbscripts/testing2x /usr/local/bin/ && \ ln -sf /dbscripts/testing2x /usr/local/bin/ && \
ln -sf /dbscripts/cron-jobs/devlist-mailer /usr/local/bin/ && \
ln -sf /dbscripts/cron-jobs/ftpdir-cleanup /usr/local/bin/ && \ ln -sf /dbscripts/cron-jobs/ftpdir-cleanup /usr/local/bin/ && \
ln -sf /dbscripts/cron-jobs/integrity-check /usr/local/bin/ && \
ln -sf /dbscripts/cron-jobs/sourceballs /usr/local/bin/ && \ ln -sf /dbscripts/cron-jobs/sourceballs /usr/local/bin/ && \
mkdir -p /etc/dbscripts/ && \ mkdir -p /etc/dbscripts/ && \
echo "tester <tester@archlinux.org> tester" > /etc/dbscripts/authors.conf && \ echo "tester <tester@archlinux.org> tester" > /etc/dbscripts/authors.conf && \
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment