leosac / access-control

Leosac Access Control - Open Source Physical Access Control System
https://leosac.com
GNU Affero General Public License v3.0
240 stars 40 forks source link

HOWTO: Simplified amd64/armhf deb package generation with Docker #116

Closed knight-of-ni closed 2 years ago

knight-of-ni commented 6 years ago

This is an ongoing work in progress, with many possibilities, but I thought I would document the progress I've made, since it is currently useful on an individual user level.

For the End User - Easily build a Leosac deb package

I have created a repository on Dockerhub with a set of images that greatly simplify the process of generating a deb package from the latest Leosac develop branch. See: https://hub.docker.com/r/knnniggett/leosac/

Assuming Docker is installed and working and qemu emulation is configured, you can generate a Leosac armhf deb package, on any modern amd64 based machine, with just a single command: docker run -e DEB_BUILD_OPTIONS="parallel=4" -v /mnt:/tmp knnniggett/leosac:build-leosac-deb-armhf

See the link to my repo for additional details on how to set the -e and -v parameters and to set up qemu on the host machine properly.

Note the build is still a rather slow process. Qemu emulation is not quick by any means.

For the Development Team - Auto-build and (eventual) Auto-deploy

I have taken this a step further, enabled Travis CI in my own Leosac fork, and have it building leosac after each commit, all from just a single .travis.yml file: https://github.com/knnniggett/leosac/blob/travis-ci/.travis.yml

Here is the build status from one of the builds: https://travis-ci.org/knnniggett/leosac/builds/342772148?utm_source=github_status&utm_medium=notification

If you look into the build details, you can see the amd64 build succeeds, but the armhf build took too long and timed out. Building an armf package from Travis CI may be a no-go due to the time it takes. I don't think it is possible to speed the build up sufficiently so I will continue to look for an alternate solution. Worst case I've got my own hardware, which can build and deploy packages to some place.

So this is where I am at currently. I'm just having a bit of fun working on a solution to get packages available automatically, after a commit is pushed to the Leosac github repo.

As a bonus, the Travis CI integration lets one know if a particular Pull Request breaks the build, which gives one the opporunity to fix the problem prior to merge.

Feedback is requested. I would like to hear if the developers are even interested in going down this path. It will eventually require their coordination to enable Travis CI and then agree on some place to deploy the resultant packages. Feel free to tell me no or point me in a different direction.

knight-of-ni commented 6 years ago

I can't spell today, apparently.

Maxhy commented 3 years ago

Sorry for being so long to review. Logically speaking this match continuous delivery vision so I'm for sure a sponsor of any solution we could have. It has been years now, is that still your recommended approach today (that's what I have done as well on another project using docker, but still I prefer to ask)? Thanks.

Maxhy commented 2 years ago

@knight-of-ni I would like to go with this approach but with GitHub Actions now. Can you share your thoughts and source of these Dockerfile (otherwise I will go by creating new ones)? Thanks.

knight-of-ni commented 2 years ago

Trying to remember what I did back on 2018...

What I used for my initial inspiration is this blog here: http://blog.guiraudet.com/raspberrypi/2016/03/03/raspbian-image-for-docker.html

I used it to build arm packages for Leosac and for the upstream project I am part of, ZoneMinder.... all on x86 architecture.

Hopefully it still works with a recent release of Raspbian. The cool thing is qemu is used transparently. You don't have to do anything different once the container is created.

You are on the right track with using Github actions. That's how I would do it, today.

Also, a few moths back, I started down the path of trying to build leosac on newer debian with gcc 9 and ran into issues. If memory serves, I had to make these two commits: https://github.com/knight-of-ni/leosac/commit/479b55471ec3f7dc44631a6b1da9be9c3f5d0128 https://github.com/knight-of-ni/leosac/commit/c5aed4d6f67c406d1175c154919a10cfdcf6e36d

And that's where I stopped. I think there is still more work to do to get leosac to build on a recent version of deian/raspbian.

Hope this helps.

Maxhy commented 2 years ago

Ok thanks, I will come with something related later on.

Maxhy commented 2 years ago

@knight-of-ni build should now be fixed for latest gcc and latest debian systems. I also bumped a few dependencies (not all yet) to latest release. Feel free to give a try when you want as I want to be sure the build is working properly for most environments before moving on to automation and then to proper tag/release.

knight-of-ni commented 2 years ago

There have been some changes to Debian packaging. I had to make these changes to get deb.sh to work: https://github.com/knight-of-ni/leosac/commit/479b55471ec3f7dc44631a6b1da9be9c3f5d0128 https://github.com/knight-of-ni/leosac/commit/cb26410e007fb1b1a1583b47091eff993e06686f https://github.com/knight-of-ni/leosac/commit/0169b3cff831073c076f94b05d0ff4dd28665171

knight-of-ni commented 2 years ago

Ran into another missing include problem:

In file included from /tmp/tmp.vEfW8QqG9u/leosac_0.7.0/src/hardware/Device.hpp:22,
                 from /tmp/tmp.vEfW8QqG9u/leosac_0.7.0/src/hardware/RFIDReader.hpp:22:
/tmp/tmp.vEfW8QqG9u/leosac_0.7.0/src/hardware/HardwareFwd.hpp:52:24: error: ‘shared_ptr’ in namespace ‘std’ does not name a template type
   52 | using DevicePtr = std::shared_ptr<Device>;
      |                        ^~~~~~~~~~
/tmp/tmp.vEfW8QqG9u/leosac_0.7.0/src/hardware/HardwareFwd.hpp:23:1: note: ‘std::shared_ptr’ is defined in header ‘<memory>’; did you forget to ‘#include <memory>’?
   22 | #include "tools/Uuid.hpp"
  +++ |+#include <memory>
   23 | 

fixed in this commit: https://github.com/knight-of-ni/leosac/commit/faa85bcf384b6d74ce2fe5a6fbd4c3918c8a1587

For reference, I am building on Debian Buster.

UPDATE This fixes another build failure: https://github.com/knight-of-ni/leosac/commit/8a6ab73cb90195956e4c60e7cab2ed9e6b0283cd

knight-of-ni commented 2 years ago

I have reached a stopping point for today. This is the latest build issue that I am up against:

In file included from /tmp/tmp.Tq8AEHVN0t/leosac_0.7.0/src/core/config/ConfigManager.hpp:23,
                 from /tmp/tmp.Tq8AEHVN0t/leosac_0.7.0/src/modules/BaseModule.hpp:24,
                 from /tmp/tmp.Tq8AEHVN0t/leosac_0.7.0/src/modules/AsioModule.hpp:20,
                 from /tmp/tmp.Tq8AEHVN0t/leosac_0.7.0/src/modules/AsioModule.cpp:20:
/tmp/tmp.Tq8AEHVN0t/leosac_0.7.0/src/modules/AsioModule.cpp: In member function ‘void Leosac::Module::AsioModule::AsyncReactorPoller::wait_handler(const boost::system::error_code&)’:
/tmp/tmp.Tq8AEHVN0t/leosac_0.7.0/src/modules/AsioModule.cpp:89:19: error: no match for ‘operator==’ (operand types are ‘const boost::system::error_code’ and ‘int’)
   89 |     ASSERT_LOG(ec == 0, "Error while processing wait_handler: " << ec.message());
      |                ~~ ^~ ~
      |                |     |
      |                |     int
      |                const boost::system::error_code
/tmp/tmp.Tq8AEHVN0t/leosac_0.7.0/src/tools/log.hpp:187:22: note: in definition of macro ‘ASSERT_LOG’
  187 |         (void)sizeof(cond);                                                         \
      |                      ^~~~
/tmp/tmp.Tq8AEHVN0t/leosac_0.7.0/src/modules/AsioModule.cpp:89:19: note: candidate: ‘operator==(int, int)’ (built-in)
   89 |     ASSERT_LOG(ec == 0, "Error while processing wait_handler: " << ec.message());
      |                ~~~^~~~
/tmp/tmp.Tq8AEHVN0t/leosac_0.7.0/src/tools/log.hpp:187:22: note: in definition of macro ‘ASSERT_LOG’
  187 |         (void)sizeof(cond);                                                         \
      |                      ^~~~
/tmp/tmp.Tq8AEHVN0t/leosac_0.7.0/src/modules/AsioModule.cpp:89:19: note:   no known conversion for argument 1 from ‘const boost::system::error_code’ to ‘int’
   89 |     ASSERT_LOG(ec == 0, "Error while processing wait_handler: " << ec.message());
      |                ~~~^~~~
/tmp/tmp.Tq8AEHVN0t/leosac_0.7.0/src/tools/log.hpp:187:22: note: in definition of macro ‘ASSERT_LOG’
  187 |         (void)sizeof(cond);                                                         \
      |                      ^~~~
Maxhy commented 2 years ago

@knight-of-ni thanks for the review. Yes I've only taken care of the app build process for now, not the deb packaging. Tbh your help is appreciated for deb packaging here as I haven't done it myself since a decade. Thanks a lot, I've integrated your fixes directly on my commit, hope it is ok to you (was easier with my local changes for tests...). About https://github.com/knight-of-ni/leosac/commit/faa85bcf384b6d74ce2fe5a6fbd4c3918c8a1587 and https://github.com/knight-of-ni/leosac/commit/8a6ab73cb90195956e4c60e7cab2ed9e6b0283cd, these commits are already part of current develop branch. I guess you have some local changes issues here, can you try to clean and retry?

I've been testing the build on both ubuntu and debian bullseye (not buster yet), amd64 and arm64/arm without issue. FYI I've got the inspiration from what you did on travis few years ago and created some GitHub actions. It's still a work in progress on my side but the use of docker buildx simplify a lot arm building (arm is enabled only for releases/tags/pr for now and not on develop branch as this takes a while to build).

knight-of-ni commented 2 years ago

Hi @Maxhy - After pulling from the latest develop branch, the deb package build script works fine now. Thank you. Apparently I had previously upgraded to Debian Bullseye and didn't realize it.

Maxhy commented 2 years ago

Great @knight-of-ni 😃! I guess some work is still required about systemd here.

I'm currently focused on the CI activity to clean things up. For now deb files (amd64, arm64, arm/v7) are temporary archived as part of the Release workflow (for tagged versions, weekly builds and manually triggered snapshots), see example: https://github.com/leosac/leosac/actions/runs/1944476766 (at the bottom of the page)

A docker image should also be published automatically to docker hub and deb files will also be archived on a debian repo (jfrog for now).

knight-of-ni commented 2 years ago

Thanks. I'll take a look at that as time permits. I am travelling for work this week so there will be a delay.

I don't remember if leosac includes a systemd service file, or if I wrote the one I am currently using. I can look into that and add a PR if needed. I'll also make sure the Debian packaging scripts are up to date. I think the rules file needs to be updated to reflect latest systemd changes.

Maxhy commented 2 years ago

I have added arm/v6 and Debian Buster (thanks Raspberry Pi 1 😆) as part of the release workflow, see https://github.com/leosac/leosac/actions/runs/2033277353 for an example list of artifacts output of a release workflow (.deb files).

Once Debian packing will be cleaned up we then should be close to tag Leosac v0.8.0 ^^.

knight-of-ni commented 2 years ago

I ran deb.sh on amd64 arch this morning, using the latest develop branch. I then installed the resulting deb package. Everything seemed to go as expected.

I went through the entire build output and did not see any errors or warnings related to systemd. If we ever bump compat > 10, there will be some systemd related work to do with the debian build scripts. Debian deprecated some things with newer compat levels.

The package does contain a valid systemd service file, which gets put into the right spot when the package is installed.

The leosac service won't start until the administrator creates a kernel.xml (or just copies the default one into place), but that is by design.

Once kernel.xml is in place, the leosac service fires right up.

Perhaps I missed something. Did you notice anything on your end, that might still need looking into?

Maxhy commented 2 years ago

Thanks for taking a look. Mhhh it may be related to the way .deb files are created on Github Actions. During a weekly/snapshot/release we are using https://github.com/leosac/leosac/blob/develop/docker_scripts/makepkg.sh instead of deb.sh. I believe we should avoid duplicate anyway but that's the current logic (it was easier for automation test). Can you quickly check that resulting .deb files from such workflow (eg. https://github.com/leosac/leosac/actions/runs/2033277353) looks fine to you as well?

knight-of-ni commented 2 years ago

I'm looking at how the deb package version gets set. It comes from $VERSION here: https://github.com/leosac/leosac/blob/develop/.github/workflows/release.yml#L30

Having a major, minor, patch of 0.0.0 seems strange.

deb.sh gets the version by grep'ing the cmakelists.txt file: https://github.com/leosac/leosac/blob/develop/deb.sh#L93

The way I've seen the version string get built for nightly builds is: {date}~{version}


The finished deb package from the workflow is indeed missing the systemd service file. I believe this is because not all of the debian packaging files are copied into the /debian subfolder during build here: https://github.com/leosac/leosac/blob/develop/docker_scripts/makepkg.sh#L17

Deb.sh copies everything: https://github.com/leosac/leosac/blob/develop/deb.sh#L105

I think that should fix it.

Maxhy commented 2 years ago

Mhh indeed. I was thinking about something more complicated ^^. Thanks again for the review, I never took time to learn properly about debian packaging, I always outsourced that part :grin:

For versioning, I agree we should first extract and parse the version from CMakeList.txt. I just pushed a commit to do so. See https://github.com/leosac/leosac/actions/runs/2079726646 for an example of deb outputs. @knight-of-ni do you see any further improvement required for deb packaging here (which was the purpose of this ticket)? Thanks!

Maxhy commented 2 years ago

@knight-of-ni does it looks good to you now? Any other improvement you would like to have on deb packaging and automation with docker (and github actions now) or should we close it? (after so long ahah)

Maxhy commented 2 years ago

I will close this ticket as the targeted automation improvement has been reached. Thanks for having driven this forward originally @knight-of-ni.