Skip to content
DC* edited this page Jul 2, 2022 · 1 revision

Requirements

This package is a work in progress. Use with caution.

In order to build the Freenet's debian package you'll need a number of tools installed depending on how you wanna build the package.

Clone freenet/fred repository

Before anything you'll need to clone the freenet/fred repository. In this repository it's located the required configuration to build the debian package. We'll explore this configuration later in this guide.

Building locally

If you want to build the package on your machine you'll need the following:

  • OS: Debian/Ubuntu
  • Packages:
    • build-essential
    • debhelper
    • devscripts
    • equivs
    • debhelper (>= 9)
    • javahelper
    • quilt
    • adduser (>= 3.11)
    • git-core
    • default-jdk
    • wget
    • service-wrapper
    • git-buildpackage

You can install the main dependencies with the following code:

$ apt update
$ apt install build-essential debhelper devscripts equivs -y

Note: You may need to run with sudo.

Additional dependencies are declared via debian/control file (I'll explain this file later in this document). In order to install these dependencies you can use this command:

$ install_tool="apt-get -o Debug::pkgProblemResolver=yes --no-install-recommends --yes"
$ mk-build-deps --install -r --tool="${install_tool}" debian/control

Note: Be sure to run this command in the project's root directory.

Building with Docker

You can use a docker image with all the dependencies already in place for working with the package build. This way you don't risk breaking your system or having unnecessary packages installed.

To work inside the docker image do the following:

$ docker run -it -v "$PWD:/pkg" desyncr/fred-pkg-builder
$ cd /pkg

The commands would run locally and inside docker should be the same.

At this point you'll be setup to start hacking on the debian package.

Setup & directory structure

Having installed the required dependencies you will need to understand the file structure required to build the packages. Here's how my layout looks like:

› tree -L 2
fred-pkg
├── fred
│   ├── AUTHORS
│   ├── build.gradle
│   ├── build-offline.sh
│   ├── CONTRIBUTING.md
│   ├── debian
│   ├── dependencies.properties
│   ├── devnotes
│   ├── generator
│   ├── gradle
│   ├── gradlew
│   ├── gradlew.bat
│   ├── lib
│   ├── LICENSE
│   ├── NEWS.md
│   ├── README.md
│   ├── SECURITY.md
│   ├── src
│   ├── stats
│   ├── test
│   └── test-offline.sh

When building packages you'll be inside fred-pkg/fred. The resulting .deb file (and related artifacts) will be created under fred-pkg.

Building the package

Now you're ready to build the Debian package, either on your system or inside a docker container. In either case the instructions should be the same.

To build the package execute the following on the project root (fred-pkg/fred):

$ gbp buildpackage --git-ignore-new --git-ignore-branch --git-upstream-tag=debian-pkg -us -uc | tee /tmp/gbp.log

Explanation:

  • gbp: gbp is the tool we use the build the package straight from the git repo it's running on. https://manpages.debian.org/testing/git-buildpackage/gbp.1.en.html
  • buildpackage: gbp's command to build the package (create the source's tar, running the build etc)
  • --git-ignore-new: This flag makes gbp ignore new files, this is useful when testing local changes.
  • --git-upstream-tag: This tag tells gbp to use this upstream branch to package.
  • --git-ignore-branch: Don't check if the current branch matches DEBIAN-BRANCH. Normally the command should run on a specific branch for the package.
  • -uc: Don't sign the .changes file. We won't sign the package in this guide.
  • -us: Don't sign the sources. We won't sign the package in this guide.
  • tee /tmp/gbp.log: The gbp command's output is rather log, you want to see the output in the terminal but at the same time you'll want to have it logged to a file (in this case /tmp/gbp.log) for latter inspection in case it fails.

Hopefully the package builds. Otherwise see the sections with common errors.

You can inspect the log:

  • dpkg-source is called by gbp to generate a tar from the git repository and generate related files.
dpkg-source: info: using source format '3.0 (quilt)'
dpkg-source: info: building freenet using existing ./freenet_0.7.5+1493.orig.tar.gz
dpkg-source: info: building freenet in freenet_0.7.5+1493-1.debian.tar.xz
dpkg-source: info: building freenet in freenet_0.7.5+1493-1.dsc
  • This is the core of the process. The gbp buildpackage command builds the package through gradle which is fred's build system.

Essentially freenet is build at this stage. Dependencies are packaged and copied into a common build directory to latter be packaged into the .deb package.

The output of the build process is mainly located at /tmp/fred-build.

 debian/rules build
dh build --with javahelper
   dh_update_autotools_config
   dh_autoreconf
   dh_auto_configure
   jh_linkjars
        rm -f debian/freenet.debhelper.log
   debian/rules override_dh_auto_build
make[1]: Entering directory '/home/dario/Projects/freenet/fred-deb/fred'
cat /tmp/fred-build/seeds/seedrefs-master/* > debian/seednodes.fref
./gradlew jar; \
./gradlew copyRuntimeLibs
  • This is the success message from building fred with gradle.
BUILD SUCCESSFUL in 7s
4 actionable tasks: 4 executed
SHA-256 of freenet.jar: 490599ffb91bfae2f877dbf7f3d1ac9eb8c650a7069d26b2b488f40d2d938dee
  • These are the directories that will be created once the package in installed. We'll explore these configuration later on.
   dh_installdirs
        install -d debian/freenet/etc/freenet/noderef debian/freenet/usr/share/java debian/freenet/usr/share/freenet debian/freenet/var/log/freenet debian/freenet/var/lib/freenet
  • Similarly this is where freenet.jar will be located when the package is installed:
jh_installlibs /tmp/fred-build/libs/freenet.jar
        install -p -m0644 /tmp/fred-build/libs/freenet.jar debian/freenet/usr/share/java/freenet-0.7.5\+1493.jar
        rm -f debian/freenet/usr/share/java/freenet.jar
        ln -s freenet-0.7.5\+1493.jar debian/freenet/usr/share/java/freenet.jar
  • This is the step responsibly for creating the approapriate configuration to integrate the package with the init.d or systemd.
   dh_installinit
        install -d debian/freenet/etc/default
        install -p -m0644 debian/freenet.default debian/freenet/etc/default/freenet
        install -d debian/freenet/etc/init.d
        install -p -m0755 debian/freenet.init debian/freenet/etc/init.d/freenet
        [META] Append autosnippet "postinst-init-restart" to postinst [debian/.debhelper/generated/freenet/postinst.service]
        [META] Append autosnippet "prerm-init-norestart" to prerm [debian/.debhelper/generated/freenet/prerm.service]
        [META] Append autosnippet "postrm-init" to postrm [debian/.debhelper/generated/freenet/postrm.service]
  • This step copies the multiple fred dependencies as jar into the target system once installed:
jh_installlibs /tmp/fred-build/output/freenet-ext-29.jar
        install -p -m0644 /tmp/fred-build/output/freenet-ext-29.jar debian/freenet/usr/share/java/freenet-ext-29-0.7.5\+1493.jar
        rm -f debian/freenet/usr/share/java/freenet-ext-29.jar
        ln -s freenet-ext-29-0.7.5\+1493.jar debian/freenet/usr/share/java/freenet-ext-29.jar
jh_installlibs /tmp/fred-build/output/jna-4.5.2.jar
        install -p -m0644 /tmp/fred-build/output/jna-4.5.2.jar debian/freenet/usr/share/java/jna-4.5.2-0.7.5\+1493.jar
        rm -f debian/freenet/usr/share/java/jna-4.5.2.jar
        ln -s jna-4.5.2-0.7.5\+1493.jar debian/freenet/usr/share/java/jna-4.5.2.jar
jh_installlibs /tmp/fred-build/output/jna-platform-4.5.2.jar
        install -p -m0644 /tmp/fred-build/output/jna-platform-4.5.2.jar debian/freenet/usr/share/java/jna-platform-4.5.2-0.7.5\+1493.jar
        rm -f debian/freenet/usr/share/java/jna-platform-4.5.2.jar
        ln -s jna-platform-4.5.2-0.7.5\+1493.jar debian/freenet/usr/share/java/jna-platform-4.5.2.jar
jh_installlibs /tmp/fred-build/output/bcprov-jdk15on-1.59.jar
        install -p -m0644 /tmp/fred-build/output/bcprov-jdk15on-1.59.jar debian/freenet/usr/share/java/bcprov-jdk15on-1.59-0.7.5\+1493.jar
        rm -f debian/freenet/usr/share/java/bcprov-jdk15on-1.59.jar
        ln -s bcprov-jdk15on-1.59-0.7.5\+1493.jar debian/freenet/usr/share/java/bcprov-jdk15on-1.59.jar
  • The errors and warnings down below come from the lintian tool. This tool checks for common errors in packages, we've a few still.
Now running lintian freenet_0.7.5+1493-1_amd64.changes ...
E: freenet changes: bad-distribution-in-changes-file unstable
E: freenet: init.d-script-does-not-implement-required-option etc/init.d/freenet force-reload
E: freenet: init.d-script-does-not-implement-required-option etc/init.d/freenet restart
E: freenet: init.d-script-does-not-implement-required-option etc/init.d/freenet start
E: freenet: init.d-script-does-not-implement-required-option etc/init.d/freenet stop
E: freenet: init.d-script-missing-dependency-on-local_fs etc/init.d/freenet: required-stop
E: freenet: init.d-script-should-always-start-service etc/default/freenet (line 10)
E: freenet source: temporary-debhelper-file freenet.debhelper.log
W: freenet source: custom-compression-in-debian-rules dh_builddeb -- -Zgzip (line 42)
W: freenet: init.d-script-does-not-source-init-functions etc/init.d/freenet
W: freenet: initial-upload-closes-no-bugs
W: freenet: missing-systemd-service-for-init.d-script freenet
W: freenet source: package-needs-versioned-debhelper-build-depends 11
W: freenet source: source-contains-debian-substvars debian/freenet.substvars
W: freenet: unknown-field freenet_0.7.5+1493-1_amd64.deb Tag
N: 26 hints overridden (26 errors)
Finished running lintian.

Your directory structure should look as the following now:

 › tree -L 1
fred-pkg
.
├── fred
│   ├── AUTHORS
│   ├── build.gradle
│   ├── build-offline.sh
│   ├── CONTRIBUTING.md
│   ├── debian
│   ├── dependencies.properties
│   ├── devnotes
│   ├── generator
│   ├── gradle
│   ├── gradlew
│   ├── gradlew.bat
│   ├── lib
│   ├── LICENSE
│   ├── NEWS.md
│   ├── README.md
│   ├── SECURITY.md
│   ├── src
│   ├── stats
│   ├── test
│   └── test-offline.sh
├── freenet_0.7.5+1493-1_amd64.build
├── freenet_0.7.5+1493-1_amd64.buildinfo
├── freenet_0.7.5+1493-1_amd64.changes
├── freenet_0.7.5+1493-1_amd64.deb
├── freenet_0.7.5+1493-1.debian.tar.xz
├── freenet_0.7.5+1493-1.dsc
└── freenet_0.7.5+1493.orig.tar.gz

Building using act (for GH actions)

You can use act to execute the GH actions locally, used to test and build the package in a CI fashion. Follow the install instructions on https://github.com/nektos/act.

Once installed you can do as follow:

$ act

Running that command on the project root (fred-pkg/fred) you'll run the default GH action locally.

Testing package installation

Once having a package built you can test its installation in a VM, another system you have or in docker. I don't recommend using your everyday system for it. I'll show you how to test the package via docker.

$ cd path-to-fred-pkg
$ docker run -it -v "$PWD:/pkg" debian:bookworm bash
$ apt update
[...]
$ dpkg -i /pkg/freenet_0.7.5*.deb
[...]
dpkg: error processing package freenet (--install):
 dependency problems - leaving unconfigured
Errors were encountered while processing:
 freenet
$ apt install --fix-broken
[...]
Adding debian:Comodo_AAA_Services_root.pem
Adding debian:emSign_ECC_Root_CA_-_C3.pem
done.
Setting up freenet (0.7.5+1493-1) ...
invoke-rc.d: could not determine current runlevel
invoke-rc.d: policy-rc.d denied execution of start.
Processing triggers for libc-bin (2.33-7) ...
Processing triggers for man-db (2.10.2-1) ...
Processing triggers for ca-certificates (20211016) ...
Updating certificates in /etc/ssl/certs...
0 added, 0 removed; done.
Running hooks in /etc/ca-certificates/update.d...

done.
done.

Then you can start and stop freenet via the service command:

$ service freenet status
Freenet 0.7.5 build 1493 (experimental release) (installed with init.d) is not running.
$ service freenet start
Starting Freenet 0.7.5 build 1493 (experimental release)...
Waiting for Freenet 0.7.5 build 1493 (experimental release).....
running: PID:9093
$ service freenet stop
Stopping Freenet 0.7.5 build 1493 (experimental release)...
Stopped Freenet 0.7.5 build 1493 (experimental release).

You can change debian:bookworm in the command above to run different distributions and versions, such as the following:

  • debian:buster
  • debian:bullseye
  • ubuntu:impish
  • ubuntu:focal

Testing package with piuparts

You can test the package installation via piuparts without having to run a docker container or risking breaking your system.

Install piuparts then execute the following:

$ piuparts freenet_0.7.5+1493-1_amd64.deb  -d kinetic

Testing on VM

You can test the package via VirtualBox. In this section I'll show you how to test the package via vagrant + packagecloud.

  1. First you'll need to install vagrant, see vagrantup.com

  2. Create a directory to store your vagrant configuration, let's say fred-pkg-vagrant/ubuntu-focal

  3. Initialize vagrant in the path from step 2 and start the VM

In this step vagrant will download the VM image and start the VM.

$ vagrant init ubuntu/focal64
$ vagrant up
  1. SSH into the VM and proceedd to install the package.
$ vagrant ssh
$ curl -s https://packagecloud.io/install/repositories/desyncr/freenet/script.deb.sh | sudo bash
$ sudo apt install freenet
  1. Test the service starts and stops
vagrant@ubuntu-focal:~$ systemctl stop freenet
vagrant@ubuntu-focal:~$ systemctl start freenet
vagrant@ubuntu-focal:~$ systemctl status freenet
● freenet.service - LSB: Freenet 0.7.5 build 1493 (experimental release)
     Loaded: loaded (/etc/init.d/freenet; generated)
     Active: active (exited) since Mon 2022-06-27 14:05:29 UTC; 38s ago
       Docs: man:systemd-sysv-generator(8)
      Tasks: 0 (limit: 1131)
     Memory: 0B
     CGroup: /system.slice/freenet.service
vagrant@ubuntu-focal:~$
  • Setup local repository
  • Common errors

Updating package

Updating the package only consist of updating the local branch that's release (master, tag), generating a proper changelog and finally building the package.

  1. Pull fred tag/branch
  2. Create changelog
  • dch -v 0.7.5+-1
  • Put a message and author
  • Commit changes
  • gbp tag --ignore-branch
  1. Build package
  • gbp buildpackage
  1. Upload package

In the scenario the package has to be updated for some reason (e.g. missing or wrong configuration, general error in packaging) the last suffix has to be updated in the version number, i.e. -1 has to be -2, and so on. This number track changes in the package itself, not in fred.

Package cloud

Packagecloud (https://packagecloud.io/) is a free solution for hosting and distributing debian/fedora etc packages. I’m using it as it eases the installation process. Once the package is ready for prime time we may choose another solution.

Freenet packages:

These packages are all the same, but packagecloud requires to upload the packages per OS/version.

Package details:

General install instructions with Packagecloud:

  1. Install the required gpg keys from packagecloud, in order to install packages from them
$ curl -s https://packagecloud.io/install/repositories/desyncr/freenet/script.deb.sh | sudo bash

Note: you can see the script source in https://packagecloud.io/desyncr/freenet/install or download it and inspect it. Doing the steps manully.

  1. Install the package
$ apt install freenet

File structure & important files

Here's a brief description of the most important files for packaging:

  • debian (directory): Every configuration required for packaging is inside this directory.
  • debian/control: The package metadata is defined in this file, including description, dependencies etc.
  • debian/rules: This is the packaging script that runs when creating the package. It's essentially a Makefile that builds the package via various helper scripts.
  • debian/source/lintian-overrides: The lintian tool check for common errors in the package. Some overrides (ignore rules) are set up in this file.
  • debian/freenet: This directory contains the structure that will be replicated once the package is installed in the target system.

Additionally the following files are default configurations:

  • debian/wrapper.conf: Default configuration for the wrapper, responsible for running fred.
  • debian/seednodes.fref: This file is created during the package build and contains the seednodes from https://github.com/freenet/seedrefs.
  • debian/freenet.ini: Default fred configuration, including directory layout, logging verbosity, updater configuration among other things.

Installation directory setup

The following files and directories will be present when the package is installed:

  • /etc/default/freenet: Default freenet deamon config

  • /etc/init.d/freenet: Init script.

  • /etc/freenet/noderef/: Seed nodes configuration: seednodes.fref

/etc/freenet/noderef/
`-- seednodes.fref

  • /usr/share/doc/freenet: Freenet included docs, readmes etc.
/usr/share/doc/freenet/
|-- AUTHORS
|-- README.md
|-- changelog.Debian.gz
`-- copyright

  • /usr/share/freenet/: Common configurations, including freenet.ini, wrapper.conf
/usr/share/freenet/
|-- freenet.ini
|-- seednodes.fref
`-- wrapper.conf

  • /usr/share/java/: Packaged dependencies (bouncycastle, jna, freenet-ext) as jars.
/usr/share/java
|-- bcprov-jdk15on-1.59-0.7.5+1493.jar
|-- bcprov-jdk15on-1.59.jar -> bcprov-jdk15on-1.59-0.7.5+1493.jar
|-- freenet-0.7.5+1493.jar
|-- freenet-ext-29-0.7.5+1493.jar
|-- freenet-ext-29.jar -> freenet-ext-29-0.7.5+1493.jar
|-- freenet.jar -> freenet-0.7.5+1493.jar
|-- gettext.jar
|-- java_defaults.mk
|-- jna-4.5.2-0.7.5+1493.jar
|-- jna-4.5.2.jar -> jna-4.5.2-0.7.5+1493.jar
|-- jna-platform-4.5.2-0.7.5+1493.jar
|-- jna-platform-4.5.2.jar -> jna-platform-4.5.2-0.7.5+1493.jar
|-- libintl-0.21.jar
|-- libintl.jar -> libintl-0.21.jar
`-- wrapper.jar
  • /var/lib/freenet/: Node directory including state, master keys, plugins.
/var/lib/freenet
|-- complete
|-- master.keys
|-- plugin-data
|-- plugins
|   `-- UPnP.jar-1656206590461
|-- startssl.pem
|-- state
|   |-- bookmarks.dat
|   |-- completed.list.downloads
|   |-- completed.list.uploads
|   |-- extra-peer-data
|   |-- persistent-temp
|   |   |-- legacy-freenet-jar-1481.fblob12414501825949476670.updater.fblob.tmp
|   |   `-- legacy-freenet-jar-1481.fblob17042949505089054093.updater.fblob.tmp
|   `-- prng.seed
`-- store
    |-- CHK-cache.config
    |-- CHK-cache.hd
    |-- CHK-cache.metadata
    |-- CHK-cache.slotfilter
    |-- CHK-clientcache.config
    |-- CHK-clientcache.hd
    |-- CHK-clientcache.metadata
    |-- CHK-clientcache.slotfilter
    |-- CHK-store.config
    |-- CHK-store.hd
    |-- CHK-store.metadata
    |-- CHK-store.slotfilter
    |-- PUBKEY-cache.config
    |-- PUBKEY-cache.hd
    |-- PUBKEY-cache.metadata
    |-- PUBKEY-cache.slotfilter
    |-- PUBKEY-clientcache.config
    |-- PUBKEY-clientcache.hd
    |-- PUBKEY-clientcache.metadata
    |-- PUBKEY-clientcache.slotfilter
    |-- PUBKEY-store.config
    |-- PUBKEY-store.hd
    |-- PUBKEY-store.metadata
    |-- PUBKEY-store.slotfilter
    |-- SSK-cache.config
    |-- SSK-cache.hd
    |-- SSK-cache.metadata
    |-- SSK-cache.slotfilter
    |-- SSK-clientcache.config
    |-- SSK-clientcache.hd
    |-- SSK-clientcache.metadata
    |-- SSK-clientcache.slotfilter
    |-- SSK-store.config
    |-- SSK-store.hd
    |-- SSK-store.metadata
    `-- SSK-store.slotfilter
  • /var/log/freenet/: Execution logs.
/var/log/freenet/
|-- freenet-1494-2022-06-26-00-1.log.gz
|-- freenet-1494-2022-06-26-00-2.log.gz
|-- freenet-1494-2022-06-26-00.log.gz
|-- freenet-1494-2022-06-26-01-1.log.gz
|-- freenet-1494-2022-06-26-01.log.gz
|-- freenet-latest.log
|-- freenet-previous.log
`-- wrapper.log

Default configuration

  • Default freenet configuration (freenet.ini)

You can find the freenet configuration file in /usr/share/freenet/freenet.ini.

node.install.nodeDir=/etc/freenet/noderef
node.install.cfgDir=/etc/freenet
node.install.userDir=/var/lib/freenet/state
node.install.runDir=/var/run/freenet
node.install.storeDir=/var/lib/freenet/store
node.install.pluginDir=/var/lib/freenet/plugins
node.install.tempDir=/tmp/freenet
node.downloadsDir=/var/lib/freenet/complete
logger.dirname=/var/log/freenet
logger.priority=NORMAL
node.updater.enabled=false
node.updater.autoupdate=false
node.updater.updateInstallers=false
  • Default wrapper configuration (wrapper.conf)

You can find the wrapper configuration oin /usr/share/freenet/wrapper.conf

encoding=UTF-8
#include /usr/share/wrapper/wrapper.conf

wrapper.java.command=java
wrapper.working.dir=/var/lib/freenet
wrapper.java.classpath.1=/usr/share/java/freenet.jar
wrapper.java.classpath.2=/usr/share/java/freenet-ext-29.jar
wrapper.java.classpath.3=/usr/share/java/jna-4.5.2.jar
wrapper.java.classpath.4=/usr/share/java/jna-platform-4.5.2.jar
wrapper.java.classpath.5=/usr/share/java/bcprov-jdk15on-1.59.jar
wrapper.java.library.path.1=/usr/lib/jni
wrapper.java.mainclass=freenet.node.NodeStarter
wrapper.java.additional.1=-Dnetworkaddress.cache.ttl=0
wrapper.java.additional.2=-Dnetworkaddress.cache.negative.ttl=0
#wrapper.java.additional.3=-enableassertions:freenet
# You might want to set the following line if you have changed java.maxmemory
#wrapper.java.additional.4=-XX:MaxPermSize=
wrapper.app.parameter.1=/etc/freenet/freenet.ini
wrapper.logfile=/var/log/freenet/wrapper.log
Clone this wiki locally