mirror of
https://github.com/freedomofpress/dangerzone.git
synced 2025-04-28 18:02:38 +02:00
install: Build Dangerzone RPMs using our SPEC file
Replace the deprecated `bdist_rpm` method of creating RPMs for Dangerzone. Instead, update our `install/linux/build-rpm.py` script, to build Dangerzone RPMs using our SPEC file under `install/linux/dangerzone.spec`. The script now essentially creates a source distribution (sdist) using `poetry build`, and then uses `rpmbuild` to create binary and source RPMs. Fixes #298
This commit is contained in:
parent
6cc2a953ff
commit
01d63e4eda
3 changed files with 117 additions and 46 deletions
|
@ -468,7 +468,7 @@ class Env:
|
||||||
version = dz_version()
|
version = dz_version()
|
||||||
if self.distro == "fedora":
|
if self.distro == "fedora":
|
||||||
install_deps = DOCKERFILE_BUILD_FEDORA_DEPS
|
install_deps = DOCKERFILE_BUILD_FEDORA_DEPS
|
||||||
package = f"dangerzone-{version}-1.noarch.rpm"
|
package = f"dangerzone-{version}-1.fc{self.version}.x86_64.rpm"
|
||||||
package_src = git_root() / "dist" / package
|
package_src = git_root() / "dist" / package
|
||||||
package_dst = build_dir / package
|
package_dst = build_dir / package
|
||||||
install_cmd = "dnf install -y"
|
install_cmd = "dnf install -y"
|
||||||
|
|
|
@ -3,20 +3,105 @@
|
||||||
import argparse
|
import argparse
|
||||||
import inspect
|
import inspect
|
||||||
import os
|
import os
|
||||||
|
import pathlib
|
||||||
import shutil
|
import shutil
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import tempfile
|
||||||
|
|
||||||
root = os.path.dirname(
|
root = pathlib.Path(__file__).parent.parent.parent
|
||||||
os.path.dirname(
|
|
||||||
os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
with open(os.path.join(root, "share", "version.txt")) as f:
|
with open(os.path.join(root, "share", "version.txt")) as f:
|
||||||
version = f.read().strip()
|
version = f.read().strip()
|
||||||
|
|
||||||
|
|
||||||
|
def remove_contents(d):
|
||||||
|
"""Remove all the contents of a directory."""
|
||||||
|
for p in d.iterdir():
|
||||||
|
if p.is_file() or p.is_symlink():
|
||||||
|
p.unlink()
|
||||||
|
else:
|
||||||
|
shutil.rmtree(p)
|
||||||
|
|
||||||
|
|
||||||
|
def build(qubes=False):
|
||||||
|
"""Build an RPM package in a temporary directory.
|
||||||
|
|
||||||
|
The build process is the following:
|
||||||
|
|
||||||
|
1. Clean up any stale data from previous runs under ./dist. Note that this directory
|
||||||
|
is used by `poetry build` and `rpmbuild`.
|
||||||
|
2. Create the necessary RPM project structure under ./install/linux/rpm-build, and
|
||||||
|
use symlinks to point to ./dist, so that we don't need to move files explicitly.
|
||||||
|
3. Create a Python source distribution using `poetry build`. If we are building a
|
||||||
|
Qubes package and there is a container image under `share/`, stash it temporarily
|
||||||
|
under a different directory.
|
||||||
|
4. Build both binary and source RPMs using rpmbuild. Optionally, pass to the SPEC
|
||||||
|
`_qubes` flag, that denotes we want to build a package for Qubes.
|
||||||
|
"""
|
||||||
|
build_dir = root / "install" / "linux" / "rpm-build"
|
||||||
|
dist_path = root / "dist"
|
||||||
|
specfile_name = "dangerzone.spec"
|
||||||
|
specfile_path = root / "install" / "linux" / specfile_name
|
||||||
|
sdist_name = f"dangerzone-{version}.tar.gz"
|
||||||
|
|
||||||
|
print("* Deleting old dist")
|
||||||
|
if os.path.exists(dist_path):
|
||||||
|
remove_contents(dist_path)
|
||||||
|
else:
|
||||||
|
dist_path.mkdir()
|
||||||
|
|
||||||
|
print(f"* Creating RPM project structure under {build_dir}")
|
||||||
|
for d in ["BUILD", "BUILDROOT", "RPMS", "SOURCES", "SPECS"]:
|
||||||
|
subdir = build_dir / d
|
||||||
|
subdir.mkdir(exist_ok=True)
|
||||||
|
remove_contents(subdir)
|
||||||
|
|
||||||
|
shutil.copy2(specfile_path, build_dir / "SPECS")
|
||||||
|
rpm_dir = build_dir / "RPMS" / "x86_64"
|
||||||
|
srpm_dir = build_dir / "SRPMS"
|
||||||
|
if srpm_dir.exists():
|
||||||
|
os.unlink(srpm_dir)
|
||||||
|
os.symlink(dist_path, rpm_dir)
|
||||||
|
os.symlink(dist_path, srpm_dir)
|
||||||
|
|
||||||
|
print("* Creating a Python sdist")
|
||||||
|
container_tar_gz = root / "share" / "container.tar.gz"
|
||||||
|
container_tar_gz_bak = root / "container.tar.gz.bak"
|
||||||
|
stash_container = qubes and container_tar_gz.exists()
|
||||||
|
if stash_container:
|
||||||
|
container_tar_gz.rename(container_tar_gz_bak)
|
||||||
|
try:
|
||||||
|
subprocess.run(["poetry", "build", "-f", "sdist"], cwd=root, check=True)
|
||||||
|
os.rename(dist_path / sdist_name, build_dir / "SOURCES" / sdist_name)
|
||||||
|
finally:
|
||||||
|
if stash_container:
|
||||||
|
container_tar_gz_bak.rename(container_tar_gz)
|
||||||
|
|
||||||
|
print("* Building RPM package")
|
||||||
|
cmd = [
|
||||||
|
"rpmbuild",
|
||||||
|
"-v",
|
||||||
|
"--define",
|
||||||
|
f"_topdir {build_dir}",
|
||||||
|
"-ba",
|
||||||
|
"--nodebuginfo",
|
||||||
|
f"{build_dir}/SPECS/dangerzone.spec",
|
||||||
|
]
|
||||||
|
|
||||||
|
# In case of qubes, set the `%{_qubes}` SPEC variable to 1. See the dangerzone.spec
|
||||||
|
# file for more details on how that's used.
|
||||||
|
if qubes:
|
||||||
|
cmd += [
|
||||||
|
"--define",
|
||||||
|
f"_qubes 1",
|
||||||
|
]
|
||||||
|
subprocess.run(cmd, check=True)
|
||||||
|
|
||||||
|
print("")
|
||||||
|
print("The following files have been created:")
|
||||||
|
print("\n".join([str(p) for p in dist_path.iterdir()]))
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
|
@ -24,45 +109,7 @@ def main():
|
||||||
)
|
)
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
build_path = os.path.join(root, "build")
|
build(args.qubes)
|
||||||
dist_path = os.path.join(root, "dist")
|
|
||||||
|
|
||||||
print("* Deleting old build and dist")
|
|
||||||
if os.path.exists(build_path):
|
|
||||||
shutil.rmtree(build_path)
|
|
||||||
if os.path.exists(dist_path):
|
|
||||||
shutil.rmtree(dist_path)
|
|
||||||
|
|
||||||
if args.qubes:
|
|
||||||
print("> Building for a Qubes system")
|
|
||||||
os.environ["QUBES_TARGET"] = "1"
|
|
||||||
|
|
||||||
# Server and Client package requirements are bundled together since
|
|
||||||
# we assume the server and client qubes are installed on the same
|
|
||||||
# template
|
|
||||||
platform_dependant_packages = ",".join(
|
|
||||||
[
|
|
||||||
# Server package requirements
|
|
||||||
"python3-magic",
|
|
||||||
"libreoffice",
|
|
||||||
# Client package requirements
|
|
||||||
"tesseract", # FIXME add other languages
|
|
||||||
]
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
platform_dependant_packages = "podman"
|
|
||||||
|
|
||||||
print("* Building RPM package")
|
|
||||||
subprocess.run(
|
|
||||||
f"python3 setup.py bdist_rpm --requires='{platform_dependant_packages},python3-pyside2,python3-appdirs,python3-click,python3-pyxdg,python3-colorama,python3-requests,python3-markdown,python3-packaging'",
|
|
||||||
shell=True,
|
|
||||||
cwd=root,
|
|
||||||
check=True,
|
|
||||||
)
|
|
||||||
|
|
||||||
print("")
|
|
||||||
print("* To install run:")
|
|
||||||
print("sudo dnf install dist/dangerzone-{}-1.noarch.rpm".format(version))
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
|
@ -77,6 +77,7 @@ convert the documents within a secure sandbox.
|
||||||
|
|
||||||
%prep
|
%prep
|
||||||
%autosetup -p1 -n dangerzone-%{version}
|
%autosetup -p1 -n dangerzone-%{version}
|
||||||
|
|
||||||
# XXX: Replace the PySide6 dependency in the pyproject.toml file with PySide2,
|
# XXX: Replace the PySide6 dependency in the pyproject.toml file with PySide2,
|
||||||
# since the former does not exist in Fedora. Once we can completely migrate to
|
# since the former does not exist in Fedora. Once we can completely migrate to
|
||||||
# Qt6, we should remove this. For more details, see:
|
# Qt6, we should remove this. For more details, see:
|
||||||
|
@ -84,6 +85,29 @@ convert the documents within a secure sandbox.
|
||||||
# https://github.com/freedomofpress/dangerzone/issues/211
|
# https://github.com/freedomofpress/dangerzone/issues/211
|
||||||
sed -i 's/^PySide6.*$/PySide2 = "*"/' pyproject.toml
|
sed -i 's/^PySide6.*$/PySide2 = "*"/' pyproject.toml
|
||||||
|
|
||||||
|
# XXX: Replace all [tool.poetry.group.*] references in pyproject.toml with
|
||||||
|
# [tool.poetry.dev-dependencies], **ONLY** for Fedora 37.
|
||||||
|
#
|
||||||
|
# Fedora 37 ships python3-poetry-core v1.0.8. This version does not understand
|
||||||
|
# the dependency groups that were added in v1.2.0 [1]. Therefore, we need to
|
||||||
|
# dumb down the pyproject.toml file a bit, so that poetry-core can parse it.
|
||||||
|
# Note that the dev dependencies are not consulted for the creation of the RPM
|
||||||
|
# file, so doing so should be safe.
|
||||||
|
#
|
||||||
|
# The following sed invocations turn the various [tool.poetry.group.*] sections
|
||||||
|
# into one large [tool.poetry.dev-dependencies] section. Then, they patch the
|
||||||
|
# minimum required poetry-core version in pyproject.toml, to one that can be
|
||||||
|
# satisfied from the Fedora 37 repos.
|
||||||
|
#
|
||||||
|
# TODO: Remove this workaround once Fedora 37 (fedora-37) is EOL.
|
||||||
|
#
|
||||||
|
# [1]: https://python-poetry.org/docs/managing-dependencies/#dependency-groups
|
||||||
|
%if 0%{?fedora} == 37
|
||||||
|
sed -i 's/^\[tool.poetry.group.package.*$/[tool.poetry.dev-dependencies]/' pyproject.toml
|
||||||
|
sed -i '/^\[tool.poetry.group.*$/d' pyproject.toml
|
||||||
|
sed -i 's/poetry-core>=1.2.0/poetry-core>=1.0.0/' pyproject.toml
|
||||||
|
%endif
|
||||||
|
|
||||||
%generate_buildrequires
|
%generate_buildrequires
|
||||||
%pyproject_buildrequires -R
|
%pyproject_buildrequires -R
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue