Commit 3818c210 authored by Thomas Gambier's avatar Thomas Gambier 🚴🏼 Committed by Julien Muchembled

re6st: switch to Python 3

Co-authored-by: Julien Muchembled's avatarJulien Muchembled <jm@nexedi.com>
parent fc091d1f
# Note that this file and related scripts (bootstrap, install-eggs) don't # Note that this file and related scripts (build_python3_if_needed,
# contain anything specific to re6stnet. They could be reused as is for SlapOS. # 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. # We don't strip ELF files because all dists automatically do it.
# For those that produce debug packages, these packages are anyway quite small # For those that produce debug packages, these packages are anyway quite small
...@@ -8,7 +9,6 @@ ...@@ -8,7 +9,6 @@
BUILD = $(TARGET) BUILD = $(TARGET)
PATH := $(CURDIR)/$(BUILD)/parts/chrpath/bin:$(CURDIR)/$(BUILD)/parts/file/bin:$(CURDIR)/$(BUILD)/parts/perl/bin:$(PATH) 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 all: $(BUILD)/.installed.cfg
ifneq ($(wildcard upstream.mk),) ifneq ($(wildcard upstream.mk),)
...@@ -21,11 +21,9 @@ else ...@@ -21,11 +21,9 @@ else
install: _install install: _install
endif endif
$(BUILD)/bin/buildout: $(BUILD)/.installed.cfg: $(BUILD)/buildout.cfg
cd $(BUILD) && $(PYTHON) -S $(CURDIR)/bootstrap cd $(BUILD) && $(shell ./build_python3_if_needed) bin/buildout \
buildout:relative-paths=false babeld-repository:recipe=
$(BUILD)/.installed.cfg: $(BUILD)/bin/buildout $(BUILD)/buildout.cfg
cd $(BUILD) && bin/buildout babeld-repository:recipe=
touch $@ touch $@
PROGS = $(patsubst %,$(DESTDIR)/usr/bin/%,$(BIN)) PROGS = $(patsubst %,$(DESTDIR)/usr/bin/%,$(BIN))
...@@ -39,7 +37,8 @@ $(PROGS): $(BUILD)/.installed.cfg ...@@ -39,7 +37,8 @@ $(PROGS): $(BUILD)/.installed.cfg
$(DESTDIR)/$(TARGET): $(BUILD)/.installed.cfg $(DESTDIR)/$(TARGET): $(BUILD)/.installed.cfg
rm -rf $@ && mkdir -p $@/parts 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 *)); \ for x in $(filter-out $(NOPART),$(shell cd $(BUILD)/parts && echo *)); \
do cp --preserve=links -r $(BUILD)/parts/$$x $@/parts; done do cp --preserve=links -r $(BUILD)/parts/$$x $@/parts; done
cd $@ && $(CURDIR)/cleanup && chmod -R u+w . cd $@ && $(CURDIR)/cleanup && chmod -R u+w .
...@@ -63,6 +62,12 @@ $(DESTDIR)/$(TARGET): $(BUILD)/.installed.cfg ...@@ -63,6 +62,12 @@ $(DESTDIR)/$(TARGET): $(BUILD)/.installed.cfg
rm $$d; ln -s /$(TARGET)$$s $$d; \ rm $$d; ln -s /$(TARGET)$$s $$d; \
done 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: clean:
find $(BUILD) -mindepth 1 -maxdepth 1 \ cd $(BUILD) && find -mindepth 1 \( \
$(patsubst %,! -name %,$(BUILD_KEEP)) |xargs rm -rf $(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=%PACKAGE%
pkgname=re6st-node
pkgver=%VERSION% pkgver=%VERSION%
pkgdesc="resilient, scalable, IPv6 network application" pkgdesc="resilient, scalable, IPv6 network application"
pkgrel=1 pkgrel=1
arch=('x86_64' 'i686') arch=('x86_64' 'i686')
license=('GPL') license=('GPL')
depends=(iptables iproute2) depends=(iptables iproute2)
makedepends=(python2) makedepends=(python3)
install='re6stnet.install' install='re6stnet.install'
source=(${pkgname}_${pkgver}.tar.gz) 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,12 @@ download-cache = download-cache ...@@ -10,10 +10,12 @@ download-cache = download-cache
develop = develop =
extensions = slapos.rebootstrap extensions = slapos.rebootstrap
newest = false newest = false
relative-paths = true
allow-picked-versions = true find-links += https://softinst171429.host.vifib.net/public/
allow-hosts += softinst171429.host.vifib.net
parts += chrpath python-bootstrap parts = re6st-ovpn chrpath
[babeld-repository] [babeld-repository]
git-executable = git-executable =
...@@ -23,12 +25,27 @@ location = ${buildout:directory}/babeld ...@@ -23,12 +25,27 @@ location = ${buildout:directory}/babeld
post-install = make clean; make version.h post-install = make clean; make version.h
environment = environment =
[python-bootstrap] # Adjust interpreter of OpenVPN hooks.
recipe = zc.recipe.egg [re6st-ovpn]
interpreter = python.tmp => re6stnet
eggs = slapos.libnetworkcache recipe = slapos.recipe.build
# https://lab.nexedi.com/nexedi/slapos.buildout/merge_requests/11 update =
scripts = dummy 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 # 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 # around from a packager point of view at least, thus at the end static
...@@ -38,13 +55,21 @@ scripts = dummy ...@@ -38,13 +55,21 @@ scripts = dummy
# ./configure --prefix=BUILD_DIRECTORY && make install # ./configure --prefix=BUILD_DIRECTORY && make install
# Instead of: # Instead of:
# ./configure --prefix=INSTALL_DIRECTORY && make install DESTDIR=BUILD_DIRECTORY # ./configure --prefix=INSTALL_DIRECTORY && make install DESTDIR=BUILD_DIRECTORY
[python2.7] [python3-common]
configure-options += configure-options +=
--prefix=%(TARGET)s/parts/${:_buildout_section_name_} --prefix=%(TARGET)s/parts/${:_buildout_section_name_}
environment += environment +=
DESTDIR=%(ROOT)s DESTDIR=%(ROOT)s
post-install =
set `echo -n ${:url} |md5sum`
ln -frs ${buildout:download-cache}/$1 ${buildout:directory}/python3.tar.xz
[openssl] [python]
# Do not rely on existing installation of what we are building.
update +=
os.environ['SSL_CERT_DIR'] = self.buildout['openssl']['certs']
[openssl-common]
shared = false shared = false
prefix = %(TARGET)s/parts/${:_buildout_section_name_} prefix = %(TARGET)s/parts/${:_buildout_section_name_}
make-options += make-options +=
...@@ -60,3 +85,7 @@ environment = ...@@ -60,3 +85,7 @@ environment =
# For old GCC like 4.8.5 on SLE 12 SP5. # For old GCC like 4.8.5 on SLE 12 SP5.
environment += environment +=
CFLAGS=-std=c99 -g -O2 CFLAGS=-std=c99 -g -O2
[versions]
zc.buildout = 3.0.1+slapos005.mr36v6
re6stnet = %(RE6STNET_VERSION)s:whl
...@@ -2,13 +2,12 @@ ...@@ -2,13 +2,12 @@
set -e set -e
pyclean() { pyclean() {
local x IFS=' local IFS='
' '
x=`dpkg -L $1` find `dpkg -L $1 |sed -n 's,[^/]*\.py$,__pycache__,p' |
rm -f `for x in $x; do sort -u` -delete 2>/dev/null
case $x in *.py) echo $x[co];; esac
done`
} }
pyclean $DPKG_MAINTSCRIPT_PACKAGE pyclean $DPKG_MAINTSCRIPT_PACKAGE
#DEBHELPER# #DEBHELPER#
...@@ -8,6 +8,7 @@ export DEB_BUILD_MAINT_OPTIONS = hardening=-format ...@@ -8,6 +8,7 @@ export DEB_BUILD_MAINT_OPTIONS = hardening=-format
include debian/common.mk include debian/common.mk
override_dh_auto_install: override_dh_auto_install:
make DESTDIR=$(TMP) PREFIX=/usr install
override_dh_link: override_dh_link:
......
#!/usr/bin/python #!/usr/bin/python3
import errno, os, shutil, sys import os, shutil, sys
path = set() path = set()
...@@ -17,7 +17,7 @@ try: ...@@ -17,7 +17,7 @@ try:
for x in sys.argv[2:]: for x in sys.argv[2:]:
x = os.path.join("bin", x) x = os.path.join("bin", x)
try: try:
exec(compile(open(x, "rb").read(), x, 'exec')) exec(compile(open(x).read(), x, 'exec'), {'__file__': x})
except Stop: except Stop:
pass pass
finally: finally:
...@@ -26,12 +26,14 @@ finally: ...@@ -26,12 +26,14 @@ finally:
dest = sys.argv[1] dest = sys.argv[1]
for x in path: for x in path:
x = os.path.relpath(x) x = os.path.relpath(x)
if not dest:
print(x)
continue
d = os.path.join(dest, x) d = os.path.join(dest, x)
try: try:
os.mkdir(os.path.basename(x)) os.mkdir(os.path.basename(x))
except OSError as e: except FileExistsError:
if e.errno != errno.EEXIST: pass
raise
if os.path.isdir(x): if os.path.isdir(x):
shutil.copytree(x, d, True) shutil.copytree(x, d, True)
else: else:
......
#!/usr/bin/env python #!/usr/bin/env python3
# #
# Copyright (C) 2016 Julien Muchembled <jm@nexedi.com> # Copyright (C) 2016 Julien Muchembled <jm@nexedi.com>
# #
...@@ -135,20 +135,20 @@ class task(_task): ...@@ -135,20 +135,20 @@ class task(_task):
return task_gen return task_gen
def __init__(self, run, depends, provides=(), def __init__(self, run, depends, provides=(),
__str_or_task = (basestring, _task)): __str_or_task = (str, _task)):
self.run = run self.run = run
self.depends = [] self.depends = []
f = [] f = []
for x in (depends,) if isinstance(depends, __str_or_task) else depends: 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)) f and self.depends.append(files(*f))
self.provides = ((provides,) self.provides = ((provides,)
if isinstance(provides, basestring) or callable(provides) if isinstance(provides, str) or callable(provides)
else provides) else provides)
self.why = self, self.why = self,
def __str__(self): def __str__(self):
return self.run.__name__ return self.__name__
@property @property
def input(self): def input(self):
...@@ -162,25 +162,29 @@ class task(_task): ...@@ -162,25 +162,29 @@ class task(_task):
deps.append((dep, dep(dry_run))) deps.append((dep, dep(dry_run)))
x += dep.outputs x += dep.outputs
self.outputs = x = [] self.outputs = x = []
check_times = True
for p in self.provides: for p in self.provides:
if callable(p): if callable(p):
x += p(self) o = p(self)
if o is None:
check_times = False
else:
x += o
else: else:
x.append(p) x.append(p)
if None not in x: if check_times:
try: try:
_otime = _task._run(self) _otime = _task._run(self)
except OSError as e: except FileNotFoundError:
if e.errno != errno.ENOENT: pass
raise
else: else:
if deps: if deps:
self.why = [dep for dep, itime in deps if _otime < itime] self.why = [dep for dep, itime in deps if _otime < itime]
if self.why: if self.why:
print "# Processing %s: %s -> %s" % (self, print("# Processing %s: %s -> %s" % (self,
", ".join(map(str, self.depends)), ", ".join(map(str, self.depends)),
", ".join("<%s>" % x.__name__ if callable(x) else x ", ".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: if not dry_run:
try: try:
self.run(self) self.run(self)
...@@ -219,14 +223,18 @@ def main(): ...@@ -219,14 +223,18 @@ def main():
sys.modules["make"] = sys.modules.pop(__name__) sys.modules["make"] = sys.modules.pop(__name__)
f = args.file f = args.file
tasks = {"__file__": f.name} g = {"__file__": f.name}
exec(compile(f.read(), f.name, "exec"), tasks) 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: if args.list:
print " ".join(sorted(k for k, v in tasks.iteritems() print(' '.join(sorted(tasks)))
if isinstance(v, _task)))
return return
for t in args.task: 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) sys.exit("%s is not a valid task." % t)
for t in args.task: for t in args.task:
tasks[t](args.dry_run) tasks[t](args.dry_run)
...@@ -249,18 +257,6 @@ class git(tree): ...@@ -249,18 +257,6 @@ class git(tree):
dry_run or subprocess.check_call(("git", "clone", self.url, root)) dry_run or subprocess.check_call(("git", "clone", self.url, root))
return _INF 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 @contextmanager
def cwd(path): def cwd(path):
p = os.getcwd() p = os.getcwd()
...@@ -271,18 +267,13 @@ def cwd(path): ...@@ -271,18 +267,13 @@ def cwd(path):
os.chdir(p) os.chdir(p)
def mkdir(path): def mkdir(path):
try: os.makedirs(path, exist_ok=True)
os.makedirs(path)
except OSError as e:
if e.errno != errno.EEXIST or not os.path.isdir(path):
raise
def remove(path): def remove(path):
try: try:
os.remove(path) os.remove(path)
except OSError as e: except FileNotFoundError:
if e.errno != errno.ENOENT: pass
raise
def rmtree(path): def rmtree(path):
if os.path.exists(path): if os.path.exists(path):
...@@ -292,11 +283,9 @@ def rmtree(path): ...@@ -292,11 +283,9 @@ def rmtree(path):
def make_tar_gz(path, mtime, xform=(lambda x: x), **kw): def make_tar_gz(path, mtime, xform=(lambda x: x), **kw):
# Make reproducible tarball. Otherwise, it's really annoying that we can't # 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. # 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__ __init__ = gzip.GzipFile.__init__
listdir = os.listdir listdir = os.listdir
try: 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)) os.listdir = lambda path: sorted(listdir(path))
t = tarfile.open(path, "w:gz", **kw) t = tarfile.open(path, "w:gz", **kw)
...@@ -314,10 +303,6 @@ def make_tar_gz(path, mtime, xform=(lambda x: x), **kw): ...@@ -314,10 +303,6 @@ def make_tar_gz(path, mtime, xform=(lambda x: x), **kw):
gzip.GzipFile.__init__ = __init__ gzip.GzipFile.__init__ = __init__
os.listdir = listdir os.listdir = listdir
t.close() 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__": if __name__ == "__main__":
sys.exit(main()) sys.exit(main())
This diff is collapsed.
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