VDR4Arch / vdr4arch

VDR PKGBUILDs for Arch Linux
33 stars 22 forks source link

Enable Travis CI #219

Closed tmn505 closed 4 years ago

tmn505 commented 4 years ago

Hi Manuel. These are the changes that piqued Your interest in my repo. As explained, this allows to test the current state of repository for build failures and a bonus to create repository with built packages. Since You last saw it I cleaned it up a bit, removed other architectures, as that didn't work, dropped arch-chroot wrapper and switched to straight chroot usage.

If privacy is the concern (for allowing Travis CI to access repository), it's still safe to commit these changes, as without connecting to CI provider, other users forking this repository could do that and have their own VDR4Arch repository and build tests.

On the side note. I You will decide to subscribe to Travis CI, initial build could fail few times because of source download issues and it would need a restart in CI provider dashboard. After first success the packages source will be cached and restored on each build so those type of fallouts won't occur very frequently.

M-Reimer commented 4 years ago

I was particularly interested in building for ARM based devices as we already have a CI system up and running for AMD64.

Build logs: https://c-reimer.de/vdr4arch/repos/vdr4arch/os/

But I'll keep this for later review. Before accepting this I would have to do quite some reading to understand what exactly happens here and how secure the whole chain would be. This is pretty much code with many aspects that aren't clear at first glance.

tmn505 commented 4 years ago

BTW, what they are witting about security: https://docs.travis-ci.com/legal/security and more specifically what concerns us: https://docs.travis-ci.com/legal/security#how-does-travis-access-my-github-account

tmn505 commented 4 years ago

W dniu 27.02.2020 o 16:02, Manuel Reimer pisze:

M-Reimer commented on this pull request.

+printf "[${reponame}]\nSigLevel = Never TrustAll\nServer = file:///home/${builduser}/repo/\$arch\n" >> ${alchroot}/etc/pacman.conf +printf "MAKEFLAGS='-j2'\nPACKAGER=\"${reponame} build bot\"\nSRCDEST=/home/${builduser}/src\n" >> ${alchroot}/etc/makepkg.conf +if [ ! -f ${alchroot}/home/${builduser}/repo/${alarch}/${reponame}.db.tar.gz ]; then

  • chroot ${alchroot} /bin/bash -c "/usr/bin/repo-add /home/${builduser}/repo/${alarch}/${reponame}.db.tar.gz" +fi

I wonder why you need this. "repo-make" expects direct local access to the packages and will install them using "pacman -U" and not "pacman -S". So no "local repository" should be needed. It won't be used by repo-make anyway as everything which is in "repo-make.conf" is expected to be accessible directly.

Good to know, I didn't inspect "repo-make" fully, these are remnants from previous implementation. I switched to "repo-make" from "arch-nspawn+makechrootpkg" from "devtools" since recreating chroot for each package takes time, so sometime the job on Travis servers would timeout (failed). Guess I can remove the addition of local repo to pacman.conf and creation of empty database.

-- TMN

tmn505 commented 4 years ago

BTW, does repo-make handle uninstallation of dependencies (depends and makedepends) after building the package? After changing to zst extension I wanted to check the archives and after looking at .BUILDINFO I saw unnecessary packages installed. Seems like all dependencies installed for previous package builds are kept (https://tmn505.github.io/vdr4arch/x86_64/vdr-wirbelscan-2018.11.04-1-x86_64.pkg.tar.zst). I compared that with package in Your repository (https://c-reimer.de/vdr4arch/repos/vdr4arch/os/x86_64/vdr-wirbelscan-2018.11.04-1-x86_64.pkg.tar.xz) and .BUILDINFO states that there was kodi installed, which is not a dependency of that package. Looks like repo-make keeps those dependencies installed for whole run of repository build. Is that by design or a bug?

Forgot to mention, Would that be a culprit: https://travis-ci.org/tmn505/vdr4arch/builds/656935718#L598 ?

M-Reimer commented 4 years ago

Add "-V" parameter when calling repo-make. This makes repo-make uninstall unneeded dependencies. This feature still needs some improvement but most of the time it works.

tmn505 commented 4 years ago

Add "-V" parameter when calling repo-make. This makes repo-make uninstall unneeded dependencies. This feature still needs some improvement but most of the time it works.

Thanks, that helped for some packages but for example, VDR ended with kodi-bin in dependencies in .BUILDINFO. I tried to replace "-Rs" with "-Rss" bu that removed sometimes essential packages and build failed (https://travis-ci.org/tmn505/vdr4arch/builds/657014184#L4366). In my local branch I replaced repo-make usage with "for" loop in bash (https://github.com/tmn505/vdr4arch/blob/tmn505/.ci/mkrepo.sh#L56). Given the "makepkg" switches, the packages ended with specified set of dependencies. You can check the build log for vdr-xineliboutput between https://travis-ci.org/tmn505/vdr4arch/builds/657471887#L37552 and https://travis-ci.org/tmn505/vdr4arch/builds/657471887#L38355 how it went in ending stage of building repository and resulting package https://tmn505.github.io/vdr4arch/x86_64/vdr-xineliboutput-2.2.0-1-x86_64.pkg.tar.zst. If that implementation would be preferred, I'll update this PR.

PS I also saw few mishaps in current PR an will push fixes.

M-Reimer commented 4 years ago

What is this ".BUILDINFO" actually? Never really used this. Aren't the dependencies effectively defined by the "depends" array in the PKGBUILD?

In fact it is difficult to get rid of all unused dependencies. But there is still a "hole" in this uninstall feature which keeps some things that could easily be removed. I get this sometimes if I build "wine-lol" with repo-make. It installs pretty much dependencies and not all of them are successfully removed afterwards. I'll fix this as soon as possible. The reason is that uninstalling some unused dependencies may free other dependencies. So this part has to be in a loop which runs as long as it finds more stuff to uninstall. I'll let you know when I've added the fix and then we'll see if this fixes your case.

But it will always be possible that repo-make keeps some things installed. It was meant as some easy to use autobuild tool. I wanted something that anyone can use to just call "repo-make" in a repository of PKGBUILD's without setting anything up. Even the build user creation is done by repo-make automatically. In the first versions it didn't uninstall dependencies at all as it usually speeds up builds of several packages if dependencies are not uninstalled. Especially if they are needed again by later builds.

Your "for loop solution" looks nice, but I wonder if it catches all "edge cases". While creating repo-make I found that there are several cases where things may get complicated. For example you have no way of "removing" something from the repository again. What if a package gets commented as it is no longer meant to be compiled or if it even gets deleted altogether?

M-Reimer commented 4 years ago

repo-make fix is on git: https://github.com/M-Reimer/repo-make I hope this helps. I now remove orphans as long as there are some found.

M-Reimer commented 4 years ago

Found the problem with "kodi". It can never get "unused" because of a dependency loop in the Arch packages:

https://bugs.archlinux.org/task/65744

This is actually a bug in pacman which probably never will receive a fix. If there is a dependency loop between unrequired dependencies, then they are not listed by "pacman -Qdtt" as both are "required" by each other.

If they don't fix their loop, I'll add Kodi to some kind of "blacklist" to repo-make and forcefully uninstall it between builds. That's the only way to get rid of such packages. In the past they had something similar with "ffmpeg" but this seems to be fixed. With latest versions "ffmpeg" actually can get unused.

M-Reimer commented 4 years ago

Proper fix is online: https://github.com/M-Reimer/repo-make/commit/d1a5a7345a4af23a7d0ea11642cefc48c84db55a I've added code to detect orphan dependency cycles properly. This should finally make the uninstallation routine work in all common cases.

tmn505 commented 4 years ago

Thanks and sorry for the long silence, had to fix storage problems on my server and laptop. Will test this tomorrow.

M-Reimer commented 4 years ago

No need to hurry. I just thought it may be interesting to find a fix for this problem as I use repo-make for my local building anyway (in a dedicated build VM running in VirtualBox). With time "repo-make" got a pretty big beast. Would be actually a good idea to split the program into some modules, but I always wanted to keep the convenience of just copying one single script file. And one of my goals was to never call anything from a PKGBUILD as root. A PKGBUILD with some kind of maliciously written code may still be dangerous for the build system, but I at least didn't want to make it too easy for a PKGBUILD to cause damage. That's why I run makepkg to create the ".SRCINFO" file in context of the build user and then just parse the .SRCINFO in my script.

I'm wondering how you managed the "clean up process" in your "for loop and chroot" solution. Maybe I miss the place where you reset the chroot environment between builds.

tmn505 commented 4 years ago

To not left some questions unanswered.

What is this ".BUILDINFO" actually? Never really used this. Aren't the dependencies effectively defined by the "depends" array in the PKGBUILD?

It's created during package creation and is part of the package. It stores some package information for example build system information like installed packages during building.

But it will always be possible that repo-make keeps some things installed. It was meant as some easy to use autobuild tool. I wanted something that anyone can use to just call "repo-make" in a repository of PKGBUILD's without setting anything up. Even the build user creation is done by repo-make automatically. In the first versions it didn't uninstall dependencies at all as it usually speeds up builds of several packages if dependencies are not uninstalled. Especially if they are needed again by later builds.

This is fine if dependencies are well defined, but if testing some new packages, sometime the resulting binary can be linked to unwanted/unknown library or even upstream could introduce some bug which would do that. Arch Linux devs always suggest to build packages in clean chroot, we don't do that, so it's always better to clean all installed dependencies before creating next packages. As bonus, most people run "makepkg" on their main system so if they'll open PR for new package it should catch this error, meaning the Travis build should fail.

Your "for loop solution" looks nice, but I wonder if it catches all "edge cases".

Probably not.

While creating repo-make I found that there are several cases where things may get complicated. For example you have no way of "removing" something from the repository again. What if a package gets commented as it is no longer meant to be compiled or if it even gets deleted altogether?

This should be trivial, as to remove file names not in array before build and recreating package database.

And one of my goals was to never call anything from a PKGBUILD as root. A PKGBUILD with some kind of maliciously written code may still be dangerous for the build system, but I at least didn't want to make it too easy for a PKGBUILD to cause damage. That's why I run makepkg to create the ".SRCINFO" file in context of the build user and then just parse the .SRCINFO in my script.

That is what I like about Your approach, it sometimes can be difficult sourcing PKGBUILD and not clobbering build system. That is what happened when I used the "for loop and chroot", it failed with "dvbsky-firmware". It didn't like redefinition of DLAGENTS variable an failed abruptly without any error printed. I solved that with sourcing PKGBUILD in subshell. Who knows how many problems can occur with my solution, so lets keep "repo-make" as default build mechanism.

I'm wondering how you managed the "clean up process" in your "for loop and chroot" solution. Maybe I miss the place where you reset the chroot environment between builds.

That responsibility is moved to "makepkg", it has --rmdeps (-r) and I used --asdeps flag which is passed to pacman.

tmn505 commented 4 years ago

Which application needs /run/shm?

To be fair, I don't remember exactly, it was probably docker which I used in the beginning, on which I had this problem:https://wiki.archlinux.org/index.php/Install_Arch_Linux_from_existing_Linux#/dev/shm.

M-Reimer commented 4 years ago

I've removed some more lines that I think that are not needed. We'll see how this goes.

Deployment will not work for now as I still have to set up this access key and I won't give Travis access to my own account. Tomorrow I'll set up a dedicated bot account for this which gets access to the VDR4Arch organization.

I've also started to look a bit into how Travis works and started to create a CI script which has the goal to be testable in a virtual machine. This would really help with developing and improving a solution like this. My solution will also include more caching and SHA1SUM check of the downloaded Arch image.

M-Reimer commented 4 years ago

And before I forget. Thanks for the interesting idea and for bringing this to my attention. Really an interesting topic.

tmn505 commented 4 years ago

YW. P. S. For example in Circle CI You pull environment with Dockerfiles which might be more convenient for You. I chose Travis because of future ARM64 build machines.

tmn505 commented 4 years ago

And the same failure for VDR as in this PR build

Warning: Transient problem: FTP error Will retry in 3 seconds. 1 retries left.

  0  918k    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0

curl: (19) RETR response: 425

I wish Klaus would enable https transfer.

M-Reimer commented 4 years ago

ARM64 so far does not work for my primary target (Raspberry Pi 4). Here I would need ARM32. But I think once we have ARM64 it is easy to "cross build" to 32 bit from there. We'll see.

With the way I'm creating the script it no more matters where it is executed. I'll test in my VM which is frozen at a specific point for the case I kill the whole system while testing :stuck_out_tongue:

It just has to be called with root permissions and the source code to be built has to be at a specific location. All is configured with environment variables, so it would be possible to put the whole config into this .travis.yml file.

tmn505 commented 4 years ago

That would be nice improvement over mine plebeian bash skills.

M-Reimer commented 4 years ago

Building and deploying worked. But I have no clue how to set up the GitHub page now...

tmn505 commented 4 years ago

The current travis.yml deploys the packages to vdr4arch repository in gh-pages branch. GitHub automatically serves page contents if it's under gh-pages branch. You can change this behaviour in repository settings. With current setup, the thing You could do is set access token to this repository in profile settings and paste that token in Travis CI dashboard (https://docs.travis-ci.com/user/environment-variables/#defining-variables-in-repository-settings) as GITHUB_TOKEN variable. With that all build artefacts will be uploaded to gh-branch and will be visible under http://vdr4arch.github.io/vdr4arch. There is also another way, I'll write that in another comment.

Edit I see You did set-up the token already. Go to repository setting and enable the GitHub pages, might be that for organisations it's disabled by default. Mine looks like this: Screenshot_20200316_152748

tmn505 commented 4 years ago

If You don't want Travis to have write access to vdr4arch repository, you can set up additional repository called VDR4Arch.github.io. The contents of master branch from that repo will be published under http://VDR4Arch.github.io. Then adjust travis.yml to deploy to different repository. https://docs.travis-ci.com/user/deployment/pages#further-configuration

M-Reimer commented 4 years ago

Seems to work now. My CI build script is also nearly finished. After some more tests I'll try this out here.

M-Reimer commented 4 years ago

Done and is part of repo-make now: https://github.com/M-Reimer/repo-make/releases This, of course, needs more work once more architectures are set up but for now it seems to work well. I have added the following:

Added caching for the bootstrap image file and for all downloaded packages (pacman cache).

With the added checksum checks the build chains integrity should now be verified properly.

It is possible to debug this script with just minimal setup in a virtual machine (place PKGBUILD's to /var/tmp/pkgbuilds) and executing the script with root privileges.