Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add more clear reproducible builds instructions/section/script and mention disorderfs at README #895

Open
emanuelb opened this issue Dec 12, 2022 · 10 comments

Comments

@emanuelb
Copy link

Currently the mention of reproducibility in repo are:

in README.md

  1. Apart from the missing signature and checksums in `META-INF/`, it should be identical to the APKs

in changelog in CHANGES file

  1. * The app now builds reproducible.
  2. This means it doesn't build reproducably without external help like 'disorderfs'.
    See https://issuetracker.google.com/issues/110237303

Suggestion are:

  1. Use the term reproducible builds in README.md
  2. Mention the need to use disorderfs for RB.
  3. Add instructions for RB in text (specific pinned versions need to be used, like java 11, gradle 4.4-5.6.4, and debian/ubuntu base image) and in script such as the Containerfile
FROM docker.io/debian:bullseye-slim

RUN set -ex; \
    apt-get update; \
    DEBIAN_FRONTEND=noninteractive apt-get install --yes -o APT::Install-Suggests=false --no-install-recommends \
        git \
        wget \
        unzip \
        disorderfs \
        openjdk-11-jdk-headless ; \
    rm -rf /var/lib/apt/lists/*; \
    useradd -ms /bin/bash appuser;
    
USER appuser

ENV ANDROID_SDK_ROOT="/home/appuser/app/sdk/" \
    ANDROID_HOME="/home/appuser/app/sdk/"

RUN set -ex; \
    mkdir -p "/home/appuser/app/sdk/licenses" "/home/appuser/app/schildbachBitcoinWallet/" "/home/appuser/app/schildbachBitcoin" "/home/appuser/gradle"; \
    printf "\n24333f8a63b6825ea9c5514f83c2829b004d1fee" > "/home/appuser/app/sdk/licenses/android-sdk-license"; \
    cd "/home/appuser/gradle/"; \
    wget https://services.gradle.org/distributions/gradle-5.6.4-bin.zip; \
    echo "1f3067073041bc44554d0efe5d402a33bc3d3c93cc39ab684f308586d732a80d  gradle-5.6.4-bin.zip" | sha256sum -c ; \        
    unzip gradle-5.6.4-bin.zip; \
    rm gradle-5.6.4-bin.zip; \
    cd /home/appuser/app/schildbachBitcoin; \
    git clone https://github.com/bitcoin-wallet/bitcoin-wallet; \
    cd bitcoin-wallet; \
    git checkout v9.26;
    
WORKDIR /home/appuser/app/schildbachBitcoinWallet/

Run:
podman run --device /dev/fuse --cap-add SYS_ADMIN --rm --name schildbach_bitcoin_build_apk -ti schildbach_bitcoin_build_apk

And run inside the shell of the container:

disorderfs --sort-dirents=yes --reverse-dirents=no /home/appuser/app/schildbachBitcoin/bitcoin-wallet/ /home/appuser/app/schildbachBitcoinWallet/;
cd /home/appuser/app/schildbachBitcoinWallet/;
/home/appuser/gradle/gradle-5.6.4/bin/gradle --no-build-cache --no-daemon --no-parallel clean :wallet:assembleRelease
@schildbach
Copy link
Collaborator

schildbach commented Dec 12, 2022

Thanks for working out the Containerfile / Podman support. I have a similar thing under development, but for Docker, and currently not in version control. For reference, I'll paste the Dockerfile here:

FROM debian:bookworm-slim as build-stage
WORKDIR /root

# install debian packages
ENV DEBIAN_FRONTEND noninteractive
RUN /usr/bin/apt-get update && \
    /usr/bin/apt-get --yes upgrade && \
    /usr/bin/apt-get --yes install openjdk-11-jdk-headless gradle sdkmanager && \
    /usr/bin/apt-get --yes autoremove && \
    /usr/bin/apt-get clean && \
    /bin/rm -rf /var/lib/apt/lists/* && \
    /bin/ln -fs /usr/share/zoneinfo/CET /etc/localtime && \
    /usr/sbin/dpkg-reconfigure --frontend noninteractive tzdata

# accept SDK licenses
ENV ANDROID_HOME /opt/android-sdk
RUN yes | /usr/bin/sdkmanager --licenses >/dev/null

# copy source code
ENV PROJECT_DIR /root/bitcoin-wallet
COPY / $PROJECT_DIR

# build
RUN /usr/bin/gradle -v && \
    /usr/bin/gradle --project-dir $PROJECT_DIR --no-build-cache --no-daemon --no-parallel clean test :wallet:assembleRelease

#
FROM scratch AS export-stage
COPY --from=build-stage /root/bitcoin-wallet/wallet/build/outputs/apk/*/release/bitcoin-wallet-*-release-unsigned.apk /

Use DOCKER_BUILDKIT=1 docker build -f Dockerfile -o build . and find the unsigned APKs in the build folder.

Disorderfs is still on the todo list for this "reference build", as I call it. (Interestingly, I didn't have any build reproducibility issue even though I wasn't using disorderfs.)

I think the main difference to yours is it uses the standard Gradle 4.4.1 that comes packaged with Debian, and it doesn't require any --cap-add SYS_ADMIN (is that related to disorderfs?).

@emanuelb
Copy link
Author

emanuelb commented Dec 12, 2022

The reason I pinned the gradle version is that I had build failures with using too new gradle version, thus a specific version will deal with it and better for reproducibility (as same version is used)

did you try building/running in rootless docker https://docs.docker.com/engine/security/rootless/ maybe it will require the fuse and SYS_ADMIN addition as well.

I add the --device /dev/fuse --cap-add SYS_ADMIN for disorderfs, I run it in rootless podman (user who run podman is not root or have root alike permissions like belong to special group such as docker as common in non rootless docker usage) on Fedora 37 on regular user (no root/sudo permissions).
it was suggest instead of using sudo in WS at: https://gitlab.com/walletscrutiny/walletScrutinyCom/-/issues/216#note_559837616

edit: never managed to reproduce this app without disorderfs, guess it might be a "flaky" issue as disorderfs always fix it but the diff wont appear without using it in all invocations (even if diff occur usually, such as in my compilations and Leo at: #713 (comment) )

@schildbach
Copy link
Collaborator

Well, by pinning the Debian version to bullseye (in your case) or bookworm (in my case) we implicitly pin the Debian-based Gradle version. That is because in general – except for security/maintenance fixes – Debian packages are pinned per distribution.

It's also worth noting that the Gradle versions downloaded from gradle.org are neither free software nor entirely open source, so I'd rather not depend the "reference build" on it.

Finally, the current build for Google Play and the reproducible build for F-Droid are using the Debian/Ubuntu-version of Gradle 4.4.1. It might be a good idea for the "reference build" to stay close to it so the risk for breaking the reproducibility when comparing APKs from different builds stays low.

Then again, if the Gradle 5.x and 6.x versions produce bit-identical results to Gradle 4.4.1, I guess building with various different Gradle versions can also be a good thing.

@Giszmo
Copy link

Giszmo commented Dec 12, 2022

For what it's worth, with Emanuel's build script fix I do get a huge diff in resources.arsc. With disorderfs added to the mix as such, I got reproducibility.

@schildbach
Copy link
Collaborator

schildbach commented Dec 12, 2022

I suspect that btrfs behaves more deterministic than ext4 (which I assume most people are using). But I'll keep in mind that disorderfs is needed for the time being – thanks!

@Giszmo
Copy link

Giszmo commented Dec 12, 2022

Tools should not rely on the file system using this sorting or the other. If btrfs deterministically sorts by date and ext4 by file name, nothing is gained. Rant is not for you but for those tool providers that don't care about RB :(

@schildbach
Copy link
Collaborator

I agree.

@schildbach
Copy link
Collaborator

Afaik the bug causing the difference in resources.arsc has been fixed by Google long ago. However I'm forced to still use the old version of the android-gradle-plugin as long Debian is still on Gradle 4.4.1.

@schildbach
Copy link
Collaborator

Either that, or I switch to a non-free, non-distro-maintained version of Gradle.

@emanuelb
Copy link
Author

Either that, or I switch to a non-free, non-distro-maintained version of Gradle.

Or use another distro maintained gradle, such as from nixos or alpine:
which support gradle 6 & gradle 7.
https://search.nixos.org/packages?type=packages&query=gradle

Also worth to contact Debian and encourage them to upgrade the gradle version as it's old, it's 4.4.1 in debian and ubuntu:

https://packages.ubuntu.com/kinetic/gradle
https://packages.debian.org/sid/gradle

Someone posted work in progress to update gradle to 6.4.1 for debian at https://lists.debian.org/debian-java/2020/05/msg00051.html https://lists.debian.org/debian-outreach/2020/08/msg00023.html

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants