Skip to content

Commit

Permalink
Add everything as is
Browse files Browse the repository at this point in the history
  • Loading branch information
antichris committed May 12, 2021
1 parent 162af8a commit 9d7f8c3
Show file tree
Hide file tree
Showing 14 changed files with 1,137 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/build/
/home/
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Changelog

This project adheres to [Semantic Versioning][semver2].


## 0.1.0

Initial release


[semver2]: https://semver.org/spec/v2.0.0.html
373 changes: 373 additions & 0 deletions LICENSE

Large diffs are not rendered by default.

149 changes: 149 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
# LeDoBE

## Ledger Live Dockerized Build Environment

Build [Ledger Live][ledger] components in an isolated Docker environment with persistence between sessions.

A GNU Make `Makefile` with a number of [targets] is included to simplify building some of the Ledger components, but be aware that the supported component range is very limited at the moment. Truth to be told, this entire project began with the goal of building just the Ledger Live [desktop application][tg-desktop] for a Raspberry Pi 4, which is an ARM64 device that did not get any official support from [@LedgerHQ][ledgerhq] at the time.

### Supported platforms

At this point only ARM64 Linux is supported out of the box.

With some tinkering you should be able to make it work for other platforms. Consider submitting a pull request, if you manage to also come up with a good workflow for multiple platforms.


## Installation

### Requirements

- Docker (tested with v18.09.1+)

#### Recommended

- A POSIX compliant shell


### Process

Once you have the LeDoBE source code (that is available at <https://github.com/antichris/ledobe>), either

- run

```sh
bin/build
```

- or build an image from the included `docker` directory:

```sh
docker build -t ledobe docker
```

You can replace `ledobe` with a tag of your choosing, just be consistent in all invocations from here on.


## Operation

### TL;DR

```sh
bin/run make
```

If you find that your builds are taking a flippin' forever, have a look-see at the [section on jobs][jobs].


### Details

#### Starting Containers

The `bin/run` creates directories to persist your build data and spins up and attaches to a container. You can also do this manually:

```sh
mkdir home build
docker run -it --rm \
-v"$(readlink -f home):/mnt/ledobe" \
-v"$(readlink -f build):/build" \
ledobe
```

#### Building stuff

Containers run bash shell by default, which is where you would execute

```sh
make
```

to start building Ledger Live components. A bunch of make [targets] have recipes to make it way easier to build them, see the relevant section below.


#### Jobs

Concurrent execution can speed up things tremendously. If you have sufficient memory (both physical and swap), you should increase `make` jobs up to the max threads that your device can handle. On a Raspberry Pi 4B that would be 4:

```sh
make -j4
```

If you don't have enough memory, but you decide to run with increased jobs anyway, expect crashes as the kernel OOM killer kicks in.

Here is an article on [increasing the swap size on a Raspberry Pi][rpi-swap].


## `make` Targets

[targets]: #make-targets (`make` Targets)

By default `make` is going to build the Ledger Live desktop application, but you can specify it a different target to build, e.g.:

```sh
make coreNPM
```

The following sections contain a brief overview of the explicit targets currently supported by the included `Makefile`.

1. ### `desktop`

[tg-desktop]: #desktop (Target `desktop`)

The Ledger Live desktop application. ([GitHub][gh-desktop])

This is likely the one you are most interested in building. It having no official binaries for ARM64 (and ARM in general) served as the primary motivation for this project.


2. ### `coreLib`

Ledger Core Library used by Ledger applications. ([GitHub][gh-core])


3. ### `coreNPM`

Ledger Core Library cross-platform C++ bindings for NodeJS. ([GitHub][gh-coreNPM])


## License

The source code of this project is released under [Mozilla Public License Version 2.0][mpl]. See [LICENSE](LICENSE).

[ledger]: https://www.ledger.com/ledger-live
"Ledger Live: Most trusted & secure crypto wallet | Ledger"
[ledgerhq]: https://github.com/LedgerHQ
"Ledger"

[jobs]: #jobs
"Operation ❭ Details ❭ Jobs"

[gh-desktop]: https://github.com/LedgerHQ/ledger-live-desktop
"LedgerHQ/ledger-live-desktop: Ledger Live (Desktop) - GitHub"
[gh-coreNPM]: https://github.com/LedgerHQ/lib-ledger-core-node-bindings
"LedgerHQ/lib-ledger-core-node-bindings - GitHub"
[gh-core]: https://github.com/LedgerHQ/lib-ledger-core
"LedgerHQ/lib-ledger-core - GitHub"

[rpi-swap]: https://nebl.io/neblio-university/enabling-increasing-raspberry-pi-swap/
"Enabling & Increasing Raspberry Pi Swap - Neblio"

[mpl]: https://www.mozilla.org/en-US/MPL/2.0/
"Mozilla Public License, version 2.0"
14 changes: 14 additions & 0 deletions bin/build
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/bin/sh

## This Source Code Form is subject to the terms of the Mozilla Public
## License, v. 2.0. If a copy of the MPL was not distributed with this
## file, You can obtain one at https://mozilla.org/MPL/2.0/.

repo=ledobe

selfPath=$(readlink -f "$(command -v "$0")") || exit
basePath=$(dirname "$(dirname "$selfPath")")

docker build \
-t $repo \
"${basePath}/docker"
48 changes: 48 additions & 0 deletions bin/run
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#!/bin/sh

## This Source Code Form is subject to the terms of the Mozilla Public
## License, v. 2.0. If a copy of the MPL was not distributed with this
## file, You can obtain one at https://mozilla.org/MPL/2.0/.

## Outputs the absolute path when dirname exists, returns with error otherwise.
resolve() { readlink -f "$1"; } ## (relative_path)
## Outputs value of variable referenced by name.
ref() { eval echo "\$${1}"; } ## (name)
## Sets value of variable referenced by name.
refSet() { eval "${1}='$( printf %s "$2" | sed "s/'/'\\\\''/g")'"; } ## (name value)

selfDir=$(dirname "$(resolve "$(command -v "$0")")")
: "${LEDOBE_DIR_BASE:="$(dirname "$selfDir")"}"

: "${LEDOBE_DIR_HOME:="${LEDOBE_DIR_BASE}/home"}"
: "${LEDOBE_DIR_BUILD:="${LEDOBE_DIR_BASE}/build"}"

: "${LEDOBE_ID_USER:=$(id -u "$(logname)")}"
: "${LEDOBE_ID_GROUP:=$(id -g "$(logname)")}"

mustChown=$(test "$LEDOBE_ID_USER" = "$(id -u)" || printf uh-huh)
for dir in BASE HOME BUILD; do
path=$(ref "LEDOBE_DIR_${dir}" )
if ! resolved=$(resolve "$path"); then
printf 'Could not resolve the %s directory "%s"\n' "$dir" "$path"
exit 1
fi
if [ ! -d "$resolved" ]; then
mkdir "$resolved" || exit
if [ "$mustChown" ]; then
chown "${LEDOBE_ID_USER}:${LEDOBE_ID_GROUP}" "$resolved"
fi
fi
refSet "resolved_${dir}" "$resolved"
done

## The `resolved_*` variables get set above procedurally.
# shellcheck disable=SC2154
docker run -it --rm \
-v "${resolved_HOME}:/mnt/home" \
-v "${resolved_BUILD}:/build" \
-e "TERM=${TERM}" \
-e "USER_ID=${LEDOBE_ID_USER}" \
-e "GROUP_ID=${LEDOBE_ID_GROUP}" \
ledobe:latest \
"$@"
155 changes: 155 additions & 0 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
## This Source Code Form is subject to the terms of the Mozilla Public
## License, v. 2.0. If a copy of the MPL was not distributed with this
## file, You can obtain one at https://mozilla.org/MPL/2.0/.

##
## Pre-download stage (common to all download stages).
##
FROM ubuntu:20.04 AS pre-dl

## Download stages depend on package info to continue installing stuff.
# hadolint ignore=DL3009
RUN set -x \
&& apt-get update \
&& apt-get install -y --no-install-suggests --no-install-recommends \
ca-certificates=20210119~20.04.1 \
wget=1.20.3-1ubuntu1

ENV OPTDIR=/usr/local/lib

WORKDIR /tmp

##
## SBT download stage.
##
FROM pre-dl AS sbt-dl

ENV PATH="${PATH}:${OPTDIR}/sbt/bin"

RUN apt-get install -y --no-install-suggests --no-install-recommends \
openjdk-8-jre-headless=8u292-b10-0ubuntu1~20.04

ARG SBT_VER=1.4.9

ENV ARCHIVE="sbt-${SBT_VER}.tgz"
RUN wget --progress=dot:giga "https://github.com/sbt/sbt/releases/download/v${SBT_VER}/${ARCHIVE}"

ARG SBT_SHA=95468119f7641499367330a60a4b8a6211e6ea7f8bde7d647c67b19dd8fddb6e

## printf can't fail and even if, sha256sum would immediately follow.
# hadolint ignore=DL4006
RUN set -x \
&& printf '%s %s' "$SBT_SHA" "$ARCHIVE" | sha256sum -c \
&& tar -C "$OPTDIR" -xf "$ARCHIVE" \
&& sbt -V

##
## Node.js download stage.
##
FROM pre-dl AS node-dl

ENV PATH="${PATH}:${OPTDIR}/node/bin"

RUN apt-get install -y --no-install-suggests --no-install-recommends \
xz-utils=5.2.4-1ubuntu1

ARG NODE_VER=12.22.1
ARG NODE_ARCH=arm64

ENV DIR="node-v${NODE_VER}-linux-${NODE_ARCH}"
ENV ARCHIVE="${DIR}.tar.xz"
RUN wget --progress=dot:giga "https://nodejs.org/dist/v${NODE_VER}/${ARCHIVE}"

ARG NODE_SHA=65145e6c2aa047ee5f83aadf9546116a6da70c21a649ed5f24dce412d2c202dc

## printf can't fail and even if, sha256sum would immediately follow.
## The pre-dl stage already set WORKDIR.
# hadolint ignore=DL3003,DL4006
RUN set -x \
&& printf '%s %s' "$NODE_SHA" "$ARCHIVE" | sha256sum -c \
&& tar -C "$OPTDIR" -xf "$ARCHIVE" \
&& ( \
cd "$OPTDIR" \
&& mv "$DIR" "node" \
)

## XXX Enable after react is bumped to ^17.0.1 in @ledgerhq/live-common.
# RUN npm install --global npm
RUN npm install --global yarn@1.22.10

##
## Prompt setup stage.
##
FROM ubuntu:20.04 AS prompt-setup

COPY prompt-setup /
RUN /prompt-setup /etc/skel/.bashrc

##
## Aggregate stage (aggregates files for copying into the final image).
##
FROM scratch AS aggregate

ENV OPTDIR=/usr/local/lib \
HOME=/home/.ledobe

COPY --from=node-dl --chown=0:0 "$OPTDIR" "$OPTDIR"
COPY --from=sbt-dl --chown=0:0 "$OPTDIR" "$OPTDIR"
COPY --from=sbt-dl /root/.sbt "${HOME}/.sbt"
COPY --from=sbt-dl /root/.ivy2 "${HOME}/.ivy2"
COPY --from=sbt-dl /root/.cache/coursier "${HOME}/.cache/coursier"

COPY --from=prompt-setup /etc/skel/.bashrc /etc/skel/
COPY --chown=0:0 npmrc /etc/skel/.npmrc
COPY --chown=0:0 home-npm.sh /etc/profile.d/

COPY build "${HOME}/build"
COPY entrypoint /usr/bin/entrypoint

FROM ubuntu:20.04 AS final

RUN set -x \
&& apt-get update \
&& DEBIAN_FRONTEND="noninteractive" \
TZ="Etc/UTC" \
apt-get install -y --no-install-suggests --no-install-recommends \
## Essential build tools.
cmake=3.16.3-1ubuntu1 \
g++=4:9.3.0-1ubuntu2 \
git=1:2.25.1-1ubuntu3.1 \
make=4.2.1-1.2 \
openjdk-8-jre-headless=8u292-b10-0ubuntu1~20.04 \
pkg-config=0.29.1-0ubuntu4 \
python-is-python3=3.8.2-4 \
## Ledger Live build dependecies.
libqt5websockets5-dev=5.12.8-0ubuntu1 \
libudev-dev=245.4-4ubuntu3.6 \
libusb-1.0-0-dev=2:1.0.23-2build1 \
qtbase5-dev=5.12.8+dfsg-0ubuntu1 \
## Convenience utils specific to this Docker environment.
bash-completion=1:2.10-1ubuntu1 \
gosu=1.10-1ubuntu0.20.04.1 \
openssh-client=1:8.2p1-4ubuntu0.2 \
&& rm -rf /var/lib/apt/lists/* \
&& git config -f /etc/skel/.gitconfig \
user.name 'Ledger DoBE' \
&& git config -f /etc/skel/.gitconfig \
user.email 'ledobe@example.com' \
&& ssh-keyscan \
github.com \
>> /etc/ssh/ssh_known_hosts \
&& :

COPY --from=aggregate / /

ENV PATH="${PATH}:/usr/local/lib/sbt/bin:/usr/local/lib/node/bin"

WORKDIR /build

CMD ["/bin/bash"]

VOLUME \
/build \
/mnt/home

ENTRYPOINT ["entrypoint"]
Loading

0 comments on commit 9d7f8c3

Please sign in to comment.