Commit a46782db authored by Thomas Gambier's avatar Thomas Gambier 🚴🏼

obs/re6st: switch to Python 3

See merge request !205Co-authored-by: Julien Muchembled's avatarJulien Muchembled <jm@nexedi.com>
parent bef062d3
Pipeline #38574 failed with stage
in 0 seconds
# Note that this file and related scripts (bootstrap, install-eggs) don't
# contain anything specific to re6stnet. They could be reused as is for SlapOS.
# Note that this file and related scripts (build_python3_if_needed,
# install-eggs) don't contain anything specific to re6stnet. They could be
# reused as is for SlapOS.
# We don't strip ELF files because all dists automatically do it.
# For those that produce debug packages, these packages are anyway quite small
......@@ -8,7 +9,6 @@
BUILD = $(TARGET)
PATH := $(CURDIR)/$(BUILD)/parts/chrpath/bin:$(CURDIR)/$(BUILD)/parts/file/bin:$(CURDIR)/$(BUILD)/parts/perl/bin:$(PATH)
PYTHON = $(or $(shell command -v python2 || command -v python || command -v python3),$(error no Python found))
all: $(BUILD)/.installed.cfg
ifneq ($(wildcard upstream.mk),)
......@@ -21,11 +21,9 @@ else
install: _install
endif
$(BUILD)/bin/buildout:
cd $(BUILD) && $(PYTHON) -S $(CURDIR)/bootstrap
$(BUILD)/.installed.cfg: $(BUILD)/bin/buildout $(BUILD)/buildout.cfg
cd $(BUILD) && bin/buildout babeld-repository:recipe=
$(BUILD)/.installed.cfg: $(BUILD)/buildout.cfg
cd $(BUILD) && $(shell ./build_python3_if_needed) bin/buildout \
buildout:relative-paths=false babeld-repository:recipe=
touch $@
PROGS = $(patsubst %,$(DESTDIR)/usr/bin/%,$(BIN))
......@@ -39,7 +37,8 @@ $(PROGS): $(BUILD)/.installed.cfg
$(DESTDIR)/$(TARGET): $(BUILD)/.installed.cfg
rm -rf $@ && mkdir -p $@/parts
cd $(BUILD) && $(PYTHON) $(CURDIR)/install-eggs $@ $(BIN)
cd $(BUILD) && parts/python3/bin/python3 \
$(CURDIR)/install-eggs $@ $(BIN)
for x in $(filter-out $(NOPART),$(shell cd $(BUILD)/parts && echo *)); \
do cp --preserve=links -r $(BUILD)/parts/$$x $@/parts; done
cd $@ && $(CURDIR)/cleanup && chmod -R u+w .
......@@ -63,6 +62,12 @@ $(DESTDIR)/$(TARGET): $(BUILD)/.installed.cfg
rm $$d; ln -s /$(TARGET)$$s $$d; \
done
uniq = $(if $1,$(firstword $1) $(call uniq,$(filter-out $(firstword $1),$1)))
_dir = $(patsubst %/,%,$(call uniq,$(filter-out ./, $(dir $1))))
_anc = $(if $1,$1 $(call _anc,$(call _dir,$1)))
clean:
find $(BUILD) -mindepth 1 -maxdepth 1 \
$(patsubst %,! -name %,$(BUILD_KEEP)) |xargs rm -rf
cd $(BUILD) && find -mindepth 1 \( \
$(patsubst %, -path ./% -o,$(CLEAN_KEEP)) \
$(patsubst %, ! -path ./%,$(call _anc,$(call _dir,$(CLEAN_KEEP)))) \
-print0 \) -prune |xargs -r0 rm -r
# Maintainer: Rafael Monnerat <rafael@nexedi.com>
pkgname=re6st-node
pkgname=%PACKAGE%
pkgver=%VERSION%
pkgdesc="resilient, scalable, IPv6 network application"
pkgrel=1
arch=('x86_64' 'i686')
license=('GPL')
depends=(iptables iproute2)
makedepends=(python2)
makedepends=(python3)
install='re6stnet.install'
source=(${pkgname}_${pkgver}.tar.gz)
......
#!/usr/bin/python3 -S
import glob, os, shutil, sys, tarfile, tempfile, zipfile
dist = "download-cache/dist"
tmp = tempfile.mkdtemp()
try:
setuptools, = glob.glob(dist + "/setuptools-*")
if setuptools.endswith(".zip"):
zipfile.ZipFile(setuptools).extractall(tmp)
else:
tarfile.TarFile.open(setuptools, "r:*").extractall(tmp)
x, = os.listdir(tmp)
sys.path.insert(0, os.path.join(tmp, x))
from setuptools.command.easy_install import main
for x in "bin", "eggs":
try:
os.mkdir(x)
except OSError:
pass
main(["-f", dist, "-mxd", x, setuptools, "zc.buildout"])
finally:
shutil.rmtree(tmp)
with os.fdopen(os.open("bin/buildout", os.O_CREAT|os.O_WRONLY|os.O_TRUNC, 0o777), 'w') as f:
f.write("""\
#!%s -S
import os, sys
d = os.path.dirname(os.path.abspath(os.path.realpath(__file__)))
d = os.path.dirname(d) + %r
sys.path[:0] = (%s)
from zc.buildout.buildout import main
sys.exit(main())
""" % (
sys.executable,
"/%s/" % x,
", ".join(map("d + %r".__mod__, os.listdir(x))),
))
#!/bin/sh
set -e
# This script compiles python3 if current python3 is older than python3.7 (minimum version required by buildout)
# It returns the path of the python3 executable to use
python3 -c 'import sys; sys.exit(1) if sys.version_info < (3, 7) else print(sys.executable)' && exit
build_dir=.build
ark=$PWD/opt/re6st/python3.tar.xz
mkdir -p $build_dir
cd $build_dir
if [ ! -x python ]; then
tar --strip-components=1 -xaf "$ark"
./configure
make -j4
fi >/dev/null
readlink -f python
......@@ -10,10 +10,9 @@ download-cache = download-cache
develop =
extensions = slapos.rebootstrap
newest = false
relative-paths = true
allow-picked-versions = true
parts += chrpath python-bootstrap
parts = re6st-ovpn chrpath
[babeld-repository]
git-executable =
......@@ -23,12 +22,27 @@ location = ${buildout:directory}/babeld
post-install = make clean; make version.h
environment =
[python-bootstrap]
recipe = zc.recipe.egg
interpreter = python.tmp
eggs = slapos.libnetworkcache
# https://lab.nexedi.com/nexedi/slapos.buildout/merge_requests/11
scripts = dummy
# Adjust interpreter of OpenVPN hooks.
[re6st-ovpn]
=> re6stnet
recipe = slapos.recipe.build
update =
import os, shutil, sys
shebang = f'#!{sys.executable} -S\n'
ws = self.buildout['re6stnet'].recipe.working_set()[1]
for root, dirs, files in os.walk(ws.by_key['re6stnet'].location):
for x in files:
if x.startswith('ovpn-'):
x = os.path.join(root, x)
with open(x) as src:
if src.readline() != shebang:
y = x + '.new'
with open(y, 'w') as dst:
src.readline()
dst.write(shebang)
shutil.copyfileobj(src, dst)
shutil.copymode(x, y)
os.rename(y, x)
# Uguu, upstream buildout.cfg must be patched as it works the other way
# around from a packager point of view at least, thus at the end static
......@@ -38,13 +52,21 @@ scripts = dummy
# ./configure --prefix=BUILD_DIRECTORY && make install
# Instead of:
# ./configure --prefix=INSTALL_DIRECTORY && make install DESTDIR=BUILD_DIRECTORY
[python2.7]
[python3-common]
configure-options +=
--prefix=%(TARGET)s/parts/${:_buildout_section_name_}
environment +=
DESTDIR=%(ROOT)s
post-install =
set `echo -n ${:url} |md5sum`
ln -frs ${buildout:download-cache}/$1 ${buildout:directory}/python3.tar.xz
[python]
# Do not rely on existing installation of what we are building.
update +=
os.environ['SSL_CERT_DIR'] = self.buildout['openssl']['certs']
[openssl]
[openssl-common]
shared = false
prefix = %(TARGET)s/parts/${:_buildout_section_name_}
make-options +=
......@@ -60,3 +82,7 @@ environment =
# For old GCC like 4.8.5 on SLE 12 SP5.
environment +=
CFLAGS=-std=c99 -g -O2
[versions]
zc.buildout = 3.0.1+slapos008
re6stnet = %(RE6STNET_VERSION)s:whl
......@@ -2,13 +2,12 @@
set -e
pyclean() {
local x IFS='
local IFS='
'
x=`dpkg -L $1`
rm -f `for x in $x; do
case $x in *.py) echo $x[co];; esac
done`
find `dpkg -L $1 |sed -n 's,[^/]*\.py$,__pycache__,p' |
sort -u` -delete 2>/dev/null
}
pyclean $DPKG_MAINTSCRIPT_PACKAGE
#DEBHELPER#
......@@ -8,6 +8,7 @@ export DEB_BUILD_MAINT_OPTIONS = hardening=-format
include debian/common.mk
override_dh_auto_install:
make DESTDIR=$(TMP) PREFIX=/usr install
override_dh_link:
......
#!/usr/bin/python
import errno, os, shutil, sys
#!/usr/bin/python3
import os, shutil, sys
path = set()
......@@ -17,7 +17,7 @@ try:
for x in sys.argv[2:]:
x = os.path.join("bin", x)
try:
exec(compile(open(x, "rb").read(), x, 'exec'))
exec(compile(open(x).read(), x, 'exec'), {'__file__': x})
except Stop:
pass
finally:
......@@ -26,12 +26,14 @@ finally:
dest = sys.argv[1]
for x in path:
x = os.path.relpath(x)
if not dest:
print(x)
continue
d = os.path.join(dest, x)
try:
os.mkdir(os.path.basename(x))
except OSError as e:
if e.errno != errno.EEXIST:
raise
except FileExistsError:
pass
if os.path.isdir(x):
shutil.copytree(x, d, True)
else:
......
#!/usr/bin/env python
#!/usr/bin/env python3
#
# Copyright (C) 2016 Julien Muchembled <jm@nexedi.com>
#
......@@ -135,20 +135,20 @@ class task(_task):
return task_gen
def __init__(self, run, depends, provides=(),
__str_or_task = (basestring, _task)):
__str_or_task = (str, _task)):
self.run = run
self.depends = []
f = []
for x in (depends,) if isinstance(depends, __str_or_task) else depends:
(f if isinstance(x, basestring) else self.depends).append(x)
(f if isinstance(x, str) else self.depends).append(x)
f and self.depends.append(files(*f))
self.provides = ((provides,)
if isinstance(provides, basestring) or callable(provides)
if isinstance(provides, str) or callable(provides)
else provides)
self.why = self,
def __str__(self):
return self.run.__name__
return self.__name__
@property
def input(self):
......@@ -162,25 +162,29 @@ class task(_task):
deps.append((dep, dep(dry_run)))
x += dep.outputs
self.outputs = x = []
check_times = True
for p in self.provides:
if callable(p):
x += p(self)
o = p(self)
if o is None:
check_times = False
else:
x += o
else:
x.append(p)
if None not in x:
if check_times:
try:
_otime = _task._run(self)
except OSError as e:
if e.errno != errno.ENOENT:
raise
except FileNotFoundError:
pass
else:
if deps:
self.why = [dep for dep, itime in deps if _otime < itime]
if self.why:
print "# Processing %s: %s -> %s" % (self,
print("# Processing %s: %s -> %s" % (self,
", ".join(map(str, self.depends)),
", ".join("<%s>" % x.__name__ if callable(x) else x
for x in self.provides or "?"))
for x in self.provides or "?")))
if not dry_run:
try:
self.run(self)
......@@ -219,14 +223,18 @@ def main():
sys.modules["make"] = sys.modules.pop(__name__)
f = args.file
tasks = {"__file__": f.name}
exec(compile(f.read(), f.name, "exec"), tasks)
g = {"__file__": f.name}
exec(compile(f.read(), f.name, "exec"), g)
tasks = {}
for k, v in g.items():
if isinstance(v, _task):
v.__name__ = k
tasks[k] = v
if args.list:
print " ".join(sorted(k for k, v in tasks.iteritems()
if isinstance(v, _task)))
print(' '.join(sorted(tasks)))
return
for t in args.task:
if not isinstance(tasks.get(t), _task):
if t not in tasks:
sys.exit("%s is not a valid task." % t)
for t in args.task:
tasks[t](args.dry_run)
......@@ -249,18 +257,6 @@ class git(tree):
dry_run or subprocess.check_call(("git", "clone", self.url, root))
return _INF
def check_output(*args, **kw):
# BBB: 'input' arg is a backport from Python 3.4
input = kw.pop("input", None)
if input is not None:
kw["stdin"] = subprocess.PIPE
p = subprocess.Popen(stdout=subprocess.PIPE, *args, **kw)
out = p.communicate(input)[0]
if p.returncode:
raise subprocess.CalledProcessError(p.returncode,
args[0] if args else kw["args"])
return out
@contextmanager
def cwd(path):
p = os.getcwd()
......@@ -271,18 +267,13 @@ def cwd(path):
os.chdir(p)
def mkdir(path):
try:
os.makedirs(path)
except OSError as e:
if e.errno != errno.EEXIST or not os.path.isdir(path):
raise
os.makedirs(path, exist_ok=True)
def remove(path):
try:
os.remove(path)
except OSError as e:
if e.errno != errno.ENOENT:
raise
except FileNotFoundError:
pass
def rmtree(path):
if os.path.exists(path):
......@@ -292,12 +283,10 @@ def rmtree(path):
def make_tar_gz(path, mtime, xform=(lambda x: x), **kw):
# Make reproducible tarball. Otherwise, it's really annoying that we can't
# rely on 'osc status' to know whether there are real changes or not.
# BBB: Results differ between Python 2.6 and 2.7 because of tarfile.
__init__ = gzip.GzipFile.__init__
listdir = os.listdir
try:
if sys.version_info >= (2, 7):
gzip.GzipFile.__init__ = lambda *args: __init__(mtime=mtime, *args)
gzip.GzipFile.__init__ = lambda *args: __init__(mtime=mtime, *args)
os.listdir = lambda path: sorted(listdir(path))
t = tarfile.open(path, "w:gz", **kw)
_gettarinfo = t.gettarinfo
......@@ -314,10 +303,6 @@ def make_tar_gz(path, mtime, xform=(lambda x: x), **kw):
gzip.GzipFile.__init__ = __init__
os.listdir = listdir
t.close()
if sys.version_info < (2, 7):
with open(path, "r+") as t:
t.seek(4)
gzip.write32u(t, long(mtime))
if __name__ == "__main__":
sys.exit(main())
......@@ -6,9 +6,7 @@
# if rebuilding for new SlapOS version but same re6stnet.
# Non-obvious dependencies:
# - Debian: python-debian, python-docutils | python3-docutils
# We could avoid them by doing like for setuptools, but I'd rather go the
# opposite way: simplify the upload part by using the system setuptools.
# - Debian: python-debian, python3-docutils, python3-venv, iproute2
# This "makefile" is quite smart at only rebuilding the necessary parts after
# some change. The main exception concerns the download-cache & extends-cache,
......@@ -40,19 +38,22 @@
# If this way of packaging is reused for other software, postinst scripts
# should be implemented.
import os, rfc822, shutil, ssl, time, urllib
import os, email, shutil, ssl, time, venv
import urllib.request, urllib.parse, urllib.error
from glob import glob
from cStringIO import StringIO
from subprocess import check_call
from io import BytesIO
from subprocess import check_call, check_output, run, DEVNULL, STDOUT
from tempfile import TemporaryDirectory
from make import *
from debian.changelog import Changelog
from debian.deb822 import Deb822
BOOTSTRAP_URL = "https://bootstrap.pypa.io/bootstrap-buildout.py"
BOOTSTRAP = "http://www.nexedi.org/static/packages/source/slapos.buildout/zc.buildout-3.0.1%2Bslapos005.tar.gz"
PACKAGE = "re6st-node"
BIN = "re6st-conf re6st-registry re6stnet".split()
BUILD_KEEP = "babeld", "buildout.cfg", "download-cache", "extends-cache"
BUILD_KEEP = ("babeld", "bin/buildout", "buildout.cfg",
"download-cache", "extends-cache", "python3.tar.xz")
NOPART = "chrpath bison flex gnu-config lunzip m4 patch perl popt site_perl xz-utils".split()
TARGET = "opt/re6st"
......@@ -66,83 +67,58 @@ re6stnet = git("re6stnet", "https://lab.nexedi.com/nexedi/re6stnet.git",
slapos = git("slapos", "https://lab.nexedi.com/nexedi/slapos.git",
ctime=False) # ignore ctime due to hardlinks to *-cache
# The built Python can't use its certificates because its capath
# is already transformed to its installation value.
os.environ["SSL_CERT_DIR"] = ssl.get_default_verify_paths().capath
os.environ["TZ"] = "UTC"; time.tzset()
@task("buildout.cfg.in", BUILD + "/buildout.cfg")
def cfg(task):
cfg = open(task.input).read() % dict(
SLAPOS=os.path.abspath("slapos"),
ROOT="${buildout:directory}/" + os.path.relpath(ROOT, BUILD),
TARGET="/"+TARGET)
mkdir(BUILD)
open(task.output, "w").write(cfg)
def no_wheel():
args = ["sed", "-i", r"/def _satisfied(/s/\(\bsource=\)None/\11/"]
args += glob("eggs/zc.buildout-*/zc/buildout/easy_install.py")
check_call(args)
@task((cfg, slapos), (BUILD + "/bin/buildout", BUILD + "/bin/python"))
def bootstrap(task):
try:
os.utime(task.outputs[1], None)
except OSError:
bootstrap = urllib.urlopen(BOOTSTRAP_URL).read()
mkdir(BUILD + "/download-cache")
with cwd(BUILD):
rmtree("extends-cache")
os.mkdir("extends-cache")
check_output((sys.executable, "-S", "-",
# XXX: By starting with an older version,
# we'll have the wanted version in cache.
"--setuptools-version", "40.8.0",
"--buildout-version", "2.13.8"), input=bootstrap)
no_wheel()
check_call(("bin/buildout", "buildout:extensions=",
"buildout:newest=true", "buildout:parts=python-bootstrap"))
check_call(("bin/python.tmp", "bin/buildout", "bootstrap"))
assert not glob("download-cache/dist/*.whl")
os.rename("bin/python.tmp", "bin/python")
def sdist_version(egg):
global MTIME, VERSION
MTIME = os.stat(egg).st_mtime
def wheel():
global MTIME, RE6STNET_VERSION, VERSION
wheel, = glob(BUILD + '/download-cache/dist/re6stnet-*')
MTIME = os.stat(wheel).st_mtime
RE6STNET_VERSION = os.path.basename(wheel).split('-', 2)[1]
VERSION = "%s+slapos%s.g%s" % (
egg.rsplit("-", 1)[1].split(".tar.")[0],
RE6STNET_VERSION,
os.getenv("SLAPOS_EPOCH", "1"),
check_output(("git", "rev-parse", "--short", "HEAD"),
cwd="slapos").strip())
cwd="slapos", text=True).strip())
tarball.provides = "%s/%s_%s.tar.gz" % (DIST, PACKAGE, VERSION),
deb.provides = deb.provides[0], "%s/%s_%s.dsc" % (DIST, PACKAGE, VERSION)
mkdir(DIST)
return egg
return wheel
def sdist(task):
o = glob(BUILD + "/download-cache/dist/re6stnet-*")
def bootstrapped(task):
x = BUILD + '/bin/buildout'
try:
return sdist_version(*o),
except TypeError:
return None,
if not run((x, '-h'), stdout=DEVNULL, stderr=STDOUT).returncode:
return x, wheel()
except Exception:
pass
@task((bootstrap, re6stnet), ("re6stnet/re6stnet.egg-info", sdist))
def sdist(task):
# XXX: We'd like to produce a reproducible tarball, so that 'make_tar_gz'
# is really useful for the main tarball.
d = BUILD + "/download-cache/dist"
g = d + "/re6stnet-*"
map(os.remove, glob(g))
check_call((os.path.abspath(task.inputs[1]), "setup.py", "sdist",
"-d", os.path.abspath(d)), cwd="re6stnet")
task.outputs[1] = sdist_version(*glob(g))
# Touch target because the current directory is used as temporary
# storage, and it is cleaned up after that setup.py runs egg_info.
os.utime(task.outputs[0], None)
@task(sdist, BUILD + "/.installed.cfg")
@task((re6stnet, slapos, 'buildout.cfg.in'), bootstrapped)
def bootstrap(task):
rmtree(BUILD)
with TemporaryDirectory('venv', PACKAGE) as venv_dir:
venv.create(venv_dir, symlinks=True, with_pip=True)
check_call(('bin/pip', 'install', '--no-cache-dir',
'hatchling', 'slapos.libnetworkcache', BOOTSTRAP,
), cwd=venv_dir)
check_call((venv_dir + '/bin/hatchling', 'build', '-t', 'wheel',
'-d', os.path.abspath(BUILD + '/download-cache/dist'),
), cwd=task.inputs[0])
task.outputs += BUILD + '/bin/buildout', wheel()
cfg = open(task.inputs[2]).read() % dict(
RE6STNET_VERSION=RE6STNET_VERSION,
ROOT='${buildout:directory}/' + os.path.relpath(ROOT, BUILD),
SLAPOS=os.path.abspath('slapos'),
TARGET='/'+TARGET)
with cwd(BUILD):
os.mkdir('extends-cache')
open('buildout.cfg', 'w').write(cfg)
check_call((venv_dir + '/bin/buildout',
'buildout:extra-paths=',
'bootstrap'))
# just fix shebang
check_call((sys.executable, 'bin/buildout', 'bootstrap'))
@task(bootstrap, BUILD + "/.installed.cfg")
def buildout(task):
check_call(("bin/buildout",), cwd=BUILD)
# Touch target in case that buildout had nothing to do.
......@@ -152,7 +128,7 @@ def tarfile_addfileobj(tarobj, name, dataobj, statobj):
tarinfo = tarobj.gettarinfo(arcname=name, fileobj=statobj)
dataobj.seek(0, 2)
tarinfo.size = dataobj.tell()
dataobj.reset()
dataobj.seek(0)
tarobj.addfile(tarinfo, dataobj)
@task(re6stnet)
......@@ -160,42 +136,50 @@ def upstream(task):
check_call(("make", "-C", "re6stnet"))
task.outputs = glob("re6stnet/docs/*.[1-9]")
@task((upstream, buildout, __file__,
"Makefile.in", "cleanup", "install-eggs", "bootstrap"))
@task((upstream, buildout,
"Makefile.in", "build_python3_if_needed", "cleanup", "install-eggs"))
def tarball(task):
prefix = "%s-%s/" % (PACKAGE, VERSION)
build_keep = list(BUILD_KEEP)
build_keep += check_output((sys.executable,
os.path.relpath(task.inputs[-1], BUILD), '', 'buildout'),
text=True, cwd=BUILD).splitlines()
def xform(path):
if path == "re6stnet/Makefile":
path = "upstream.mk"
for p in "re6stnet/", "build/", "":
if path.startswith(p):
return prefix + path[len(p):]
with make_tar_gz(task.output, MTIME, xform) as t:
s = StringIO()
for k in "BIN", "NOPART", "BUILD_KEEP", "TARGET":
v = globals()[k]
s.write("%s = %s\n" % (k, v if type(v) is str else " ".join(v)))
with open(task.inputs[-4]) as x:
s = BytesIO()
for k in "BIN", "NOPART", "CLEAN_KEEP", "TARGET":
v = build_keep if k == "CLEAN_KEEP" else globals()[k]
s.write(("%s = %s\n" % (
k, v if type(v) is str else ' '.join(v),
)).encode())
with open("Makefile.in", 'rb') as x:
s.write(x.read())
tarfile_addfileobj(t, "Makefile", s, x)
s.truncate(0)
s.write("override PYTHON = /%s/parts/python2.7/bin/python\n" % TARGET)
with open("re6stnet/Makefile") as x:
s.write(x.read())
tarfile_addfileobj(t, "upstream.mk", s, x)
for x in task.inputs[-3:]:
t.add(x)
t.add("re6stnet/daemon")
t.add("re6stnet/Makefile")
for x in upstream.outputs:
t.add(x)
for x in BUILD_KEEP:
t.add(BUILD + "/" + x)
filter_ = lambda info: None if info.name.endswith((
"/.git", "/__pycache__",
)) else info
for x in build_keep:
t.add(BUILD + "/" + x, filter=filter_)
@task(sdist, "debian/changelog")
@task(bootstrap, "debian/changelog")
def dch(task):
with cwd("re6stnet") as p:
p += "/" + task.output
check_output(("make", "-f", "-", p,
"PACKAGE=" + PACKAGE, "VERSION=" + VERSION),
input=open("debian/common.mk").read().replace(task.output, p))
changelog = os.getcwd() + "/" + task.output
with open("re6stnet/debian/common.mk") as mk:
check_output(("make", "-f", "-", changelog,
"PACKAGE=" + PACKAGE, "VERSION=" + VERSION),
input=mk.read().replace(task.output, changelog).encode(),
cwd="re6stnet")
@task((dch, tree("debian")), DIST + "/debian.tar.gz")
def deb(task):
......@@ -205,16 +189,17 @@ def deb(task):
d["Source"] = s["Source"] = b["Package"] = PACKAGE
d["Version"] = VERSION
d["Architecture"] = b["Architecture"] = "any"
d["Build-Depends"] = s["Build-Depends"] = (
"python (>= 2.7) | python2 | python3-distutils, debhelper (>= 9.20120909),"
" debhelper (>= 10) | dh-systemd,"
" iproute2 | iproute"
)
b["Depends"] = "${shlibs:Depends}, iproute2 | iproute"
d["Build-Depends"] = s["Build-Depends"] = \
"debhelper (>= 10), iproute2" + ''.join(
# Before 3.10, pip wants distutils.
",\n python3 (>= 3.10) | python3-distutils (>= 3.7) | %s-dev" % x
for x in "libbz2 libffi liblzma libssl zlib1g".split())
del s["X-Python3-Version"]
b["Depends"] = "${shlibs:Depends}, iproute2"
b["Conflicts"] = b["Provides"] = b["Replaces"] = "re6stnet"
patched_control = StringIO("%s\n%s" % (s, b))
patched_control = BytesIO(("%s\n%s" % (s, b)).encode('utf-8'))
open(task.outputs[1], "w").write(str(d))
date = rfc822.parsedate_tz(Changelog(open(dch.output)).date)
date = email.utils.parsedate_tz(Changelog(open(dch.output)).date)
mtime = time.mktime(date[:9]) - date[9]
# Unfortunately, OBS does not support symlinks.
with make_tar_gz(task.outputs[0], mtime, dereference=True) as t:
......@@ -230,39 +215,21 @@ def deb(task):
upstream.difference_update((x, "debian/rules", "debian/source"))
# check we are aware of any upstream file we override
assert upstream.isdisjoint(added), upstream.intersection(added)
map(t.add, sorted(upstream))
@task((sdist, __file__), DIST + "/re6stnet.spec")
def rpm(task):
check_call(("sed", "-r", r"""
# https://fedoraproject.org/wiki/Packaging:Python_Appendix#Manual_byte_compilation
1i%%global __os_install_post %%(echo '%%{__os_install_post}' |grep -v brp-python-bytecompile)
/^%%define (_builddir|ver)/d
s/^(Name:\s*).*/\1%s/
s/^(Version:\s*).*/\1%s/
s/^(Release:\s*).*/\11/
/^BuildArch:/cAutoReqProv: no\
BuildRequires: gcc-c++, make, python, iproute\
#!BuildIgnore: rpmlint-Factory\
Source: %%{name}_%%{version}.tar.gz
/^Requires:/{
/iproute/!d
}
/^Recommends:/d
s/^(Conflicts:\s*).*/\1re6stnet/
/^%%description$/a%%prep\n%%setup -q
/^%%preun$/,/^$/{
/^$/ifind /%s -type f -name '*.py[co]' -delete
}
""" % (PACKAGE, VERSION, TARGET), "re6stnet/re6stnet.spec"),
stdout=open(task.output, "w"))
for u in sorted(upstream):
t.add(u)
def _template(task):
output = (open(task.inputs[-1]).read()
.replace("%PACKAGE%", PACKAGE)
.replace("%TARGET%", TARGET)
.replace("%VERSION%", VERSION)
)
open(task.output, 'w').write(output)
@task((sdist, "PKGBUILD.in"), DIST + "/PKGBUILD")
def arch(task):
pkgbuild = open(task.inputs[-1]).read().replace("%VERSION%", VERSION)
open(task.output, "w").write(pkgbuild)
rpm, arch = (task((bootstrap, name + '.in'), DIST + '/' + name)(_template)
for name in ("re6stnet.spec", "PKGBUILD"))
@task((tarball, deb, rpm, arch, "re6stnet.install"))
@task((tarball, deb, rpm, arch, "re6stnet.install", "re6st-node.rpmlintrc"))
def build(task):
pass
......
setBadness('binary-or-shlib-defines-rpath', 0)
setBadness('wrong-script-interpreter', 0)
setBadness('summary-not-capitalized', 0)
setBadness('devel-file-in-non-devel-package', 0)
%global __brp_mangle_shebangs %{nil}
%global __brp_python_bytecompile %{nil}
%define units re6stnet.service re6st-registry.service
Summary: resilient, scalable, IPv6 network application
Name: %PACKAGE%
Version: %VERSION%
Release: 1
License: GPLv2+
Group: Applications/Internet
AutoReqProv: no
BuildRequires: gcc-c++, make, python3, iproute
#!BuildIgnore: rpmlint-Factory
Source0: %{name}_%{version}.tar.gz
Source1: %{name}.rpmlintrc
Requires: iproute
BuildRequires: python3-devel
# dependencies for compilation of python3
BuildRequires: libffi-devel
BuildRequires: (lzma-devel or liblzma-devel or xz-devel)
BuildRequires: zlib-devel
BuildRequires: (libbz2-devel or bzip2-devel)
Conflicts: re6stnet
%description
%prep
%setup -q
%build
make
%install
set $RPM_BUILD_ROOT
make install PREFIX=%_prefix MANDIR=%_mandir DESTDIR=$1 %{?_unitdir:UNITDIR=%{_unitdir}}
# Exclude man pages because they will be compressed.
find $1 -mindepth 1 -path \*%_mandir -prune -o \
-name re6st\* -prune -printf /%%P\\n > INSTALLED
export QA_RPATHS=$(( 0x0001|0x0002|0x0020 ))
%clean
rm -rf "$RPM_BUILD_ROOT" INSTALLED
%files -f INSTALLED
%_mandir/*/*
%post
if [ $1 -eq 1 ]; then
/bin/systemctl preset %{units} || :
fi >/dev/null 2>&1
%preun
if [ $1 -eq 0 ]; then
/bin/systemctl --no-reload disable %{units} || :
/bin/systemctl stop %{units} || :
fi >/dev/null 2>&1
find %TARGET% -type d -name __pycache__ -print0 |xargs -r0 rm -r
%postun
/bin/systemctl daemon-reload >/dev/null 2>&1 || :
if [ $1 -ge 1 ]; then
/bin/systemctl try-restart %{units} >/dev/null 2>&1 || :
fi
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