This commit is contained in:
AbcSxyZ 2021-09-30 04:17:03 +02:00 committed by GitHub
commit eb0740bd3c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
36 changed files with 433 additions and 757 deletions

643
contrib/gitian-build.sh Executable file → Normal file
View file

@ -1,406 +1,389 @@
#!/bin/bash
# Copyright (c) 2016 The Bitcoin Core developers
# Copyright (c) 2021 The Dogecoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
# Systems to build
DESCRIPTORS=('osx' 'win' 'linux')
SIGN_DESCRIPTORS=('win-signed' 'osx-signed')
# Gitian properties
export USE_DOCKER=0
export USE_LXC=0
# Dependencies
ossPatchUrl="https://bitcoincore.org/cfields/osslsigncode-Backports-to-1.7.1.patch"
ossPatchHash="a8c4e9cafba922f89de0df1f2152e7be286aba73f78505169bc351a7938dd911"
ossTarUrl="https://launchpad.net/ubuntu/+archive/primary/+sourcefiles/osslsigncode/1.7.1-1/osslsigncode_1.7.1.orig.tar.gz"
ossTarHash="f9a8cdb38b9c309326764ebc937cba1523a3a751a7ab05df3ecc99d18ae466c9"
macosSdkUrl="https://bitcoincore.org/depends-sources/sdks/MacOSX10.11.sdk.tar.gz"
macosSdkHash="bec9d089ebf2e2dd59b1a811a38ec78ebd5da18cbbcd6ab39d1e59f64ac5033f"
# What to do
sign=false
verify=false
build=false
setupenv=false
# Systems to build
linux=true
windows=true
osx=true
buildSigned=false
commit=false
test=false
enableCache=false
# Other Basic variables
SIGNER=
VERSION=
commit=false
url=https://github.com/dogecoin/dogecoin
proc=2
mem=2000
lxc=true
osslTarUrl=https://launchpad.net/ubuntu/+archive/primary/+sourcefiles/osslsigncode/1.7.1-1/osslsigncode_1.7.1.orig.tar.gz
osslPatchUrl=https://bitcoincore.org/cfields/osslsigncode-Backports-to-1.7.1.patch
scriptName=$(basename -- "$0")
signProg="gpg --detach-sign"
commitFiles=true
outputDir=$(pwd)/gitian-output
# Help Message
read -d '' usage <<- EOF
Usage: $scriptName [-c|u|v|b|s|B|o|h|j|m|] signer version
# Help message
read -r -d '' usage <<-EOF
Usage: $scriptName [options] version
Run this script from the directory containing the dogecoin, gitian-builder, gitian.sigs, and dogecoin-detached-sigs.
Standalone script to perform the gitian build of Dogecoin Core. Perform
deterministic build for multiples Operating System, using Docker, LXC or
KVM for virtualization. Sign binaries using PGP.
Use https://github.com/devrandom/gitian-builder to manage the process.
Arguments:
signer GPG signer to sign each build assert file
version Version number, commit, or branch to build. If building a commit or branch, the -c option must be specified
version Version number, commit, or branch to build. If building a
commit or branch, the -c option must be specified
Options:
-c|--commit Indicate that the version argument is for a commit or branch
-u|--url Specify the URL of the repository. Default is https://github.com/dogecoin/dogecoin
-v|--verify Verify the gitian build
-b|--build Do a gitian build
-s|--sign Make signed binaries for Windows and Mac OSX
-B|--buildsign Build both signed and unsigned binaries
-o|--os Specify which Operating Systems the build is for. Default is lwx. l for linux, w for windows, x for osx
-j Number of processes to use. Default 2
-m Memory to allocate in MiB. Default 2000
--kvm Use KVM instead of LXC
--setup Setup the gitian building environment. Uses KVM. If you want to use lxc, use the --lxc option. Only works on Debian-based systems (Ubuntu, Debian)
--detach-sign Create the assert file for detached signing. Will not commit anything.
--no-commit Do not commit anything to git
-h|--help Print this help message
--setup Setup the gitian building environment.
-b|--build Do the gitian build
-B|--build-signed Build signed binaries for MacOS and Windows
-s|--sign name Sign builded executables with GPG using user ID
-v|--verify Verify the gitian build
--lxc Use LXC instead of KVM
--docker Use Docker instead of KVM
-o|--os lwx Specify which Operating Systems the build is for. Default is lwx,
l for Linux, w for Windows, x for MacOS
-j proc Number of processes to use. Default $proc
-m n Memory to allocate in MiB. Default $mem
--enable-cache Use local apt-cacher server. If you need to specify host, use
MIRROR_HOST environment variable
-c|--commit Indicate that the version argument is for a commit or branch
-u|--url repo Specify the URL of the repository. Default is https://github.com/dogecoin/dogecoin
--test CI TEST. Uses Docker
-h|--help Print this help message
EOF
# Get options and arguments
while :; do
case $1 in
# Verify
-v|--verify)
verify=true
-v | --verify)
verify=true
;;
# Build
-b|--build)
build=true
-b | --build)
build=true
;;
# Sign binaries
-s|--sign)
sign=true
;;
# Build then Sign
-B|--buildsign)
sign=true
build=true
# Build signed binaries
-B | --build-signed)
buildSigned=true
;;
# PGP Signer
-S|--signer)
if [ -n "$2" ]
then
SIGNER=$2
shift
else
echo 'Error: "--signer" requires a non-empty argument.'
exit 1
fi
;;
-s | --sign)
if [ -n "$2" ]; then
SIGNER=$2
shift
else
echo 'Error: "--sign" requires a PGP signer.'
exit 1
fi
;;
# Operating Systems
-o|--os)
if [ -n "$2" ]
then
linux=false
windows=false
osx=false
if [[ "$2" = *"l"* ]]
then
linux=true
fi
if [[ "$2" = *"w"* ]]
then
windows=true
fi
if [[ "$2" = *"x"* ]]
then
osx=true
fi
shift
else
echo 'Error: "--os" requires an argument containing an l (for linux), w (for windows), or x (for Mac OSX)\n'
exit 1
fi
;;
# Help message
-h|--help)
echo "$usage"
exit 0
;;
# Commit or branch
-c|--commit)
commit=true
;;
# Number of Processes
-j)
if [ -n "$2" ]
then
proc=$2
shift
else
echo 'Error: "-j" requires an argument'
exit 1
fi
;;
# Memory to allocate
-m)
if [ -n "$2" ]
then
mem=$2
shift
else
echo 'Error: "-m" requires an argument'
exit 1
fi
;;
# URL
-u)
if [ -n "$2" ]
then
url=$2
shift
else
echo 'Error: "-u" requires an argument'
exit 1
fi
;;
# kvm
--kvm)
lxc=false
-o | --os)
if [ -n "$2" ]; then
DESCRIPTORS=()
SIGN_DESCRIPTORS=()
if [[ "$2" == *"l"* ]]; then
DESCRIPTORS+=('linux')
fi
if [[ "$2" == *"w"* ]]; then
DESCRIPTORS+=('win')
SIGN_DESCRIPTORS+=('win-signed')
fi
if [[ "$2" == *"x"* ]]; then
DESCRIPTORS+=('osx')
SIGN_DESCRIPTORS+=('osx-signed')
fi
shift
else
echo 'Error: "--os" specify os: l (linux), w (windows), or x (Mac OSX)'
exit 1
fi
;;
# Detach sign
--detach-sign)
signProg="true"
commitFiles=false
# Help message
-h | --help)
echo "$usage"
exit 0
;;
# Commit files
--no-commit)
commitFiles=false
# Commit or branch
-c | --commit)
commit=true
;;
# Number of Processes
-j)
if [ -n "$2" ]; then
proc=$2
shift
else
echo 'Error: "-j" requires an argument'
exit 1
fi
;;
# Memory to allocate
-m)
if [ -n "$2" ]; then
mem=$2
shift
else
echo 'Error: "-m" requires an argument'
exit 1
fi
;;
# lxc
--lxc)
USE_LXC=1
;;
# docker
--docker)
USE_DOCKER=1
;;
# apt cacher
--enable-cache)
enableCache=true
;;
# URL
-u)
if [ -n "$2" ]; then
url=$2
shift
else
echo 'Error: "-u" requires an argument'
exit 1
fi
;;
# Setup
--setup)
setup=true
;;
*) # Default case: If no more options then break out of the loop.
break
--test)
test=true
;;
*) # Default case: If no more options then break out of the loop.
break ;;
esac
shift
done
# Set up LXC
if [[ $lxc = true ]]
then
export USE_LXC=1
export LXC_BRIDGE=br0
# Download specific file and verify hash
function download_file () {
local filename=$(basename $1)
if [ ! -f $filename ]; then
wget $1
fi
# Verify file signature
echo "$2 $filename" | sha256sum -c --status
if [ $? != 0 ]; then
echo "$scriptName: Signature for $filename don't match."
exit 1
fi
}
function move_build_files() {
find build/out -type f -exec mv '{}' $outputDir/dogecoin-binaries/${VERSION}/ \;
}
function download_descriptor() {
if [[ ! $1 == 'test' ]]; then
uri="${url/github.com/raw.githubusercontent.com}"/"$2"/contrib/gitian-descriptors/gitian-"$1".yml
echo "Downloading descriptor ${1} ${uri}"
wget $uri -O gitian-"$1".yml || exit 1
else
# CI tests
cp ../ci/descriptor/"$1".yml gitian-"$1".yml || exit 1
fi
}
### Test configuration ###
if [[ $test == true ]]; then
if [[ $commit == true ]]; then
VERSION="f80bfe9068ac1a0619d48dad0d268894d926941e"
else
VERSION="1.14.3"
fi
DESCRIPTORS=('test')
SIGN_DESCRIPTORS=()
COMMIT=$VERSION
SIGNER="signer"
SHA256SUM="0d519f6ade0e601617a7c44b764eeae35a8784070c3e44f542011956f1743459"
fi
# Check for OSX SDK
if [[ ! -e "gitian-builder/inputs/MacOSX10.11.sdk.tar.gz" && $osx == true ]]
then
echo "Cannot build for OSX, SDK does not exist. Will build for other OSes"
osx=false
### Arguments checks ####
echo "Using ${proc} CPU and ${mem} RAM"
# Control the selection of a single virtualisation software
if [ $(($USE_LXC + $USE_DOCKER)) -ge 2 ]; then
echo "$scriptName: Specify a single virtualisation solution between Docker, LXC or KVM."
exit
fi
# Get signer
if [[ -n"$1" ]]
then
SIGNER=$1
shift
if [ -n "$SIGNER" ]; then
echo "Testing GPG Keys available..."
result=$(gpg --list-secret-keys --keyid-format=long | grep sec | grep -v revoked | grep "" -c)
if [[ $result == "" ]]; then
echo "No GPG keys available..."
echo "Please follow this documentation: https://docs.github.com/en/github/authenticating-to-github/managing-commit-signature-verification/generating-a-new-gpg-key"
exit 1
fi
mkdir -p $outputDir/sigs
fi
# Get version
if [[ -n "$1" ]]
then
if [ -n "$1" ]; then
VERSION=$1
COMMIT=$VERSION
shift
fi
# Check that a signer is specified
if [[ $SIGNER == "" ]]
then
echo "$scriptName: Missing signer."
echo "Try $scriptName --help for more information"
exit 1
fi
# Check that a version is specified
if [[ $VERSION == "" ]]
then
echo "$scriptName: Missing version."
echo "Try $scriptName --help for more information"
exit 1
fi
# Add a "v" if no -c
if [[ $commit = false ]]
then
COMMIT="v${VERSION}"
fi
echo ${COMMIT}
# Setup build environment
if [[ $setup = true ]]
then
sudo apt-get install ruby apache2 git apt-cacher-ng python-vm-builder qemu-kvm qemu-utils
# GIT --date=format-local support
MIN_GIT_VERSION=2.7.0
LASTEST_GIT_VERSION=2.32.0
if ! (echo a version ${MIN_GIT_VERSION}; git --version) | sort -Vk3 | tail -1 | grep -q git; then
sudo apt-get install build-essential make libssl-dev libghc-zlib-dev libcurl4-gnutls-dev libexpat1-dev gettext unzip
wget https://github.com/git/git/archive/v${LASTEST_GIT_VERSION}.zip -O v${LASTEST_GIT_VERSION}.zip
unzip v${LASTEST_GIT_VERSION}.zip
pushd ./git-${LASTEST_GIT_VERSION}
make -j "${proc}" prefix=/usr/local all
make -j "${proc}" prefix=/usr/local install
popd
# Use tag or commit within repository
if [[ $commit == false ]]; then
COMMIT=v$VERSION
else
COMMIT=$VERSION
fi
else
echo "$scriptName: Missing version, see --help for more information."
exit 1
fi
# GIT CLONE
### Setup ###
if [[ $setup == true ]]; then
git clone https://github.com/dogecoin/gitian.sigs.git
git clone https://github.com/dogecoin/dogecoin-detached-sigs.git
git clone https://github.com/devrandom/gitian-builder.git
pushd ./gitian-builder
if [[ -n "$USE_LXC" ]]
#Download dependencies
mkdir -p inputs
pushd inputs
download_file $ossPatchUrl $ossPatchHash
download_file $ossTarUrl $ossTarHash
download_file $macosSdkUrl $macosSdkHash
popd
#Check if apt-cacher should be enabled
if [ -z "$MIRROR_HOST" ] && [[ $enableCache = false ]]; then
cacher_option="--disable-apt-cacher"
fi
#Prepare containers depending of virtualization solution: lxc, docker, kvm
if [ "$USE_LXC" -eq 1 ]
then
sudo apt-get install lxc
bin/make-base-vm --suite trusty --arch amd64 --lxc
sudo apt-get install -y lxc
bin/make-base-vm --suite trusty --arch amd64 --lxc $(echo $cacher_option)
elif [ "$USE_DOCKER" -eq 1 ]; then
bin/make-base-vm --suite trusty --arch amd64 --docker $(echo $cacher_option)
else
bin/make-base-vm --suite trusty --arch amd64
bin/make-base-vm --suite trusty --arch amd64 $(echo $cacher_option)
fi
popd
fi
# Set up build
pushd ./dogecoin
git fetch
git checkout ${COMMIT}
# Download descriptors
mkdir -p ./gitian-descriptors/
pushd gitian-descriptors || exit 1
if [[ $build == true || $verify == true ]]; then
for descriptor in "${DESCRIPTORS[@]}"; do
download_descriptor "$descriptor" "$COMMIT"
done
fi
if [[ $buildSigned == true ]]; then
for sign_descriptor in "${SIGN_DESCRIPTORS[@]}"; do
download_descriptor "$sign_descriptor" "$COMMIT"
done
fi
popd
# Build
if [[ $build = true ]]
then
# Make output folder
mkdir -p ./dogecoin-binaries/${VERSION}
# Build Dependencies
echo ""
echo "Building Dependencies"
echo ""
pushd ./gitian-builder
mkdir -p inputs
wget -N -P inputs $osslPatchUrl
wget -N -P inputs $osslTarUrl
make -j "${proc}" -C ../dogecoin/depends download SOURCES_PATH=`pwd`/cache/common
### Build ###
# Linux
if [[ $linux = true ]]
then
echo ""
echo "Compiling ${VERSION} Linux"
echo ""
./bin/gbuild -j ${proc} -m ${mem} --commit dogecoin=${COMMIT} --url dogecoin=${url} ../dogecoin/contrib/gitian-descriptors/gitian-linux.yml
./bin/gsign -p $signProg --signer $SIGNER --release ${VERSION}-linux --destination ../gitian.sigs/ ../dogecoin/contrib/gitian-descriptors/gitian-linux.yml
mv build/out/dogecoin-*.tar.gz build/out/src/dogecoin-*.tar.gz ../dogecoin-binaries/${VERSION}
fi
# Windows
if [[ $windows = true ]]
then
echo ""
echo "Compiling ${VERSION} Windows"
echo ""
./bin/gbuild -j ${proc} -m ${mem} --commit dogecoin=${COMMIT} --url dogecoin=${url} ../dogecoin/contrib/gitian-descriptors/gitian-win.yml
./bin/gsign -p $signProg --signer $SIGNER --release ${VERSION}-win-unsigned --destination ../gitian.sigs/ ../dogecoin/contrib/gitian-descriptors/gitian-win.yml
mv build/out/dogecoin-*-win-unsigned.tar.gz inputs/dogecoin-win-unsigned.tar.gz
mv build/out/dogecoin-*.zip build/out/dogecoin-*.exe ../dogecoin-binaries/${VERSION}
fi
# Mac OSX
if [[ $osx = true ]]
then
echo ""
echo "Compiling ${VERSION} Mac OSX"
echo ""
./bin/gbuild -j ${proc} -m ${mem} --commit dogecoin=${COMMIT} --url dogecoin=${url} ../dogecoin/contrib/gitian-descriptors/gitian-osx.yml
./bin/gsign -p $signProg --signer $SIGNER --release ${VERSION}-osx-unsigned --destination ../gitian.sigs/ ../dogecoin/contrib/gitian-descriptors/gitian-osx.yml
mv build/out/dogecoin-*-osx-unsigned.tar.gz inputs/dogecoin-osx-unsigned.tar.gz
mv build/out/dogecoin-*.tar.gz build/out/dogecoin-*.dmg ../dogecoin-binaries/${VERSION}
fi
popd
if [[ $build == true ]]; then
# Make output folder
mkdir -p $outputDir/dogecoin-binaries/"$VERSION"
if [[ $commitFiles = true ]]
then
# Commit to gitian.sigs repo
echo ""
echo "Committing ${VERSION} Unsigned Sigs"
echo ""
pushd gitian.sigs
git add ${VERSION}-linux/${SIGNER}
git add ${VERSION}-win-unsigned/${SIGNER}
git add ${VERSION}-osx-unsigned/${SIGNER}
git commit -a -m "Add ${VERSION} unsigned sigs for ${SIGNER}"
popd
pushd ./gitian-builder || exit 1
# Clean dogecoin git directory because of old caching
if [ -d inputs/dogecoin/ ]; then
echo "Cleaning Dogecoin directory..."
rm -rf inputs/dogecoin/
fi
for descriptor in "${DESCRIPTORS[@]}"; do
echo ""
echo "Compiling ${VERSION} ${descriptor}"
echo ""
./bin/gbuild -j "$proc" -m "$mem" --commit dogecoin="$COMMIT" --url dogecoin="$url" ../gitian-descriptors/gitian-"$descriptor".yml || exit 1
if [ -n "$SIGNER" ]; then
./bin/gsign --signer "$SIGNER" --release "$VERSION"-"$descriptor" \
--destination $outputDir/sigs/ ../gitian-descriptors/gitian-"$descriptor".yml
fi
move_build_files
done
popd || exit 1
fi
# Verify the build
if [[ $verify = true ]]
then
# Linux
pushd ./gitian-builder
echo ""
echo "Verifying v${VERSION} Linux"
echo ""
./bin/gverify -v -d ../gitian.sigs/ -r ${VERSION}-linux ../dogecoin/contrib/gitian-descriptors/gitian-linux.yml
# Windows
echo ""
echo "Verifying v${VERSION} Windows"
echo ""
./bin/gverify -v -d ../gitian.sigs/ -r ${VERSION}-win-unsigned ../dogecoin/contrib/gitian-descriptors/gitian-win.yml
# Mac OSX
echo ""
echo "Verifying v${VERSION} Mac OSX"
echo ""
./bin/gverify -v -d ../gitian.sigs/ -r ${VERSION}-osx-unsigned ../dogecoin/contrib/gitian-descriptors/gitian-osx.yml
# Signed Windows
echo ""
echo "Verifying v${VERSION} Signed Windows"
echo ""
./bin/gverify -v -d ../gitian.sigs/ -r ${VERSION}-osx-signed ../dogecoin/contrib/gitian-descriptors/gitian-osx-signer.yml
# Signed Mac OSX
echo ""
echo "Verifying v${VERSION} Signed Mac OSX"
echo ""
./bin/gverify -v -d ../gitian.sigs/ -r ${VERSION}-osx-signed ../dogecoin/contrib/gitian-descriptors/gitian-osx-signer.yml
popd
fi
# Build signed binaries
if [[ $buildSigned == true ]]; then
pushd gitian-builder || exit 1
# Sign binaries
if [[ $sign = true ]]
then
pushd ./gitian-builder
# Sign Windows
if [[ $windows = true ]]
then
echo ""
echo "Signing ${VERSION} Windows"
echo ""
./bin/gbuild -i --commit signature=${COMMIT} ../dogecoin/contrib/gitian-descriptors/gitian-win-signer.yml
./bin/gsign -p $signProg --signer $SIGNER --release ${VERSION}-win-signed --destination ../gitian.sigs/ ../dogecoin/contrib/gitian-descriptors/gitian-win-signer.yml
mv build/out/dogecoin-*win64-setup.exe ../dogecoin-binaries/${VERSION}
mv build/out/dogecoin-*win32-setup.exe ../dogecoin-binaries/${VERSION}
fi
# Sign Mac OSX
if [[ $osx = true ]]
then
echo ""
echo "Signing ${VERSION} Mac OSX"
echo ""
./bin/gbuild -i --commit signature=${COMMIT} ../dogecoin/contrib/gitian-descriptors/gitian-osx-signer.yml
./bin/gsign -p $signProg --signer $SIGNER --release ${VERSION}-osx-signed --destination ../gitian.sigs/ ../dogecoin/contrib/gitian-descriptors/gitian-osx-signer.yml
mv build/out/dogecoin-osx-signed.dmg ../dogecoin-binaries/${VERSION}/dogecoin-${VERSION}-osx.dmg
fi
popd
if [[ $commitFiles = true ]]
then
# Commit Sigs
pushd gitian.sigs
echo ""
echo "Committing ${VERSION} Signed Sigs"
echo ""
git add ${VERSION}-win-signed/${SIGNER}
git add ${VERSION}-osx-signed/${SIGNER}
git commit -a -m "Add ${VERSION} signed binary sigs for ${SIGNER}"
popd
for sign_descriptor in "${SIGN_DESCRIPTORS[@]}"; do
echo ""
echo "Compiling Binary ${VERSION} ${sign_descriptor}"
echo ""
./bin/gbuild --skip-image --upgrade --commit signature="$COMMIT" ../gitian-descriptors/gitian-"$sign_descriptor".yml || exit 1
if [ -n "$SIGNER" ]; then
./bin/gsign --signer "$SIGNER" --release "$VERSION"-"$sign_descriptor" \
--destination $outputDir/sigs/ ../gitian-descriptors/gitian-"$sign_descriptor".yml
fi
move_build_files
done
popd || exit 1
fi
### Signatures Verification ###
if [[ $verify == true ]]; then
pushd ./gitian-builder || exit 1
for descriptor in "${DESCRIPTORS[@]}"; do
echo ""
echo "Verifying v${VERSION} ${descriptor}"
echo ""
./bin/gverify -v -d ../gitian.sigs/ -r "${VERSION}"-"$descriptor" ../gitian-descriptors/gitian-"$descriptor".yml
done
popd || exit 1
fi

View file

@ -1,466 +1,159 @@
Gitian building
================
*Setup instructions for a Gitian build of Dogecoin Core using a Debian VM or physical system.*
# Gitian building
Gitian is the deterministic build process that is used to build the Dogecoin
Core executables. It provides a way to be reasonably sure that the
executables are really built from the source on GitHub. It also makes sure that
the same, tested dependencies are used and statically built into the executable.
> *Gitian is a secure source-control oriented software distribution method. This means you can download trusted binaries that are verified by multiple builders.*
Source : [Gitian.org](https://gitian.org/)
Multiple developers build the source code by following a specific descriptor
("recipe"), cryptographically sign the result, and upload the resulting signature.
These results are compared and only if they match, the build is accepted and uploaded
to dogecoin.com.
Gitian is a deterministic build process that is used to release Dogecoin Core executables. It use same dependencies in a virtualized environment to build binaries. This let independent builders compare binaries hashes to verify and sign released executables.
More independent Gitian builders are needed, which is why this guide exists.
It is preferred you follow these steps yourself instead of using someone else's
VM image to avoid 'contaminating' the build.
To reduce probability of compromised binaries during releases, more independent gitian builders are needed !
Table of Contents
------------------
Participate and help to secure the process by following this guide.
- [Create a new VirtualBox VM](#create-a-new-virtualbox-vm)
- [Connecting to the VM](#connecting-to-the-vm)
- [Setting up Debian for Gitian building](#setting-up-debian-for-gitian-building)
- [Installing Gitian](#installing-gitian)
- [Setting up the Gitian image](#setting-up-the-gitian-image)
- [Getting and building the inputs](#getting-and-building-the-inputs)
- [Building Dogecoin Core](#building-dogecoin-core)
- [Building an alternative repository](#building-an-alternative-repository)
- [Signing externally](#signing-externally)
- [Uploading signatures](#uploading-signatures)
### Table of contents
Preparing the Gitian builder host
---------------------------------
1. [Install dependencies](#install-dependencies)
* [Common dependencies](#common-dependencies)
* [Docker](#docker)
* [LXC](#lxc)
* [KVM](#kvm)
* [Apt-cacher](#apt-cacher)
2. [Usage](#usage)
* [Syntax](#syntax)
* [Example](#example)
* [Signing externally](#signing-externally)
3. [Publish signatures](#publish-signatures)
The first step is to prepare the host environment that will be used to perform the Gitian builds.
This guide explains how to set up the environment, and how to start the builds.
## Install dependencies
Debian Linux was chosen as the host distribution because it has a lightweight install (in contrast to Ubuntu) and is readily available.
Any kind of virtualization can be used, for example:
- [VirtualBox](https://www.virtualbox.org/) (covered by this guide)
- [KVM](http://www.linux-kvm.org/page/Main_Page)
- [LXC](https://linuxcontainers.org/), see also [Gitian host docker container](https://github.com/gdm85/tenku/tree/master/docker/gitian-bitcoin-host/README.md).
To perform a gitian build, you can use different virtualization software : Docker, KVM or LXC. Dependencies will change according to your choice.
You can also install Gitian on actual hardware instead of using virtualization.
You need to install some required dependencies whatever you will choose.
Create a new VirtualBox VM
---------------------------
In the VirtualBox GUI click "New" and choose the following parameters in the wizard:
Use your packet manager to install them : `apt`, `brew`, `dnf`, `pacman`...
![](gitian-building/create_new_vm.png)
- Type: Linux, Debian (64-bit)
![](gitian-building/create_vm_memsize.png)
- Memory Size: at least 3000MB, anything less and the build might not complete.
![](gitian-building/create_vm_hard_disk.png)
- Hard Disk: Create a virtual hard disk now
![](gitian-building/create_vm_hard_disk_file_type.png)
- Hard Disk file type: Use the default, VDI (VirtualBox Disk Image)
![](gitian-building/create_vm_storage_physical_hard_disk.png)
- Storage on physical hard disk: Dynamically Allocated
![](gitian-building/create_vm_file_location_size.png)
- File location and size: at least 40GB; as low as 20GB *may* be possible, but better to err on the safe side
- Click `Create`
After creating the VM, we need to configure it.
- Click the `Settings` button, then go to the `Network` tab. Adapter 1 should be attached to `NAT`.
![](gitian-building/network_settings.png)
- Click `Advanced`, then `Port Forwarding`. We want to set up a port through which we can reach the VM to get files in and out.
- Create a new rule by clicking the plus icon.
![](gitian-building/port_forwarding_rules.png)
- Set up the new rule the following way:
- Name: `SSH`
- Protocol: `TCP`
- Leave Host IP empty
- Host Port: `22222`
- Leave Guest IP empty
- Guest Port: `22`
- Click `Ok` twice to save.
Get the [Debian 8.x net installer](http://cdimage.debian.org/mirror/cdimage/archive/8.5.0/amd64/iso-cd/debian-8.5.0-amd64-netinst.iso) (a more recent minor version should also work, see also [Debian Network installation](https://www.debian.org/CD/netinst/)).
This DVD image can be [validated](https://www.debian.org/CD/verify) using a SHA256 hashing tool, for example on
Unixy OSes by entering the following in a terminal:
echo "ad4e8c27c561ad8248d5ebc1d36eb172f884057bfeb2c22ead823f59fa8c3dff debian-8.5.0-amd64-netinst.iso" | sha256sum -c
# (must return OK)
Then start the VM. On the first launch you will be asked for a CD or DVD image. Choose the downloaded ISO.
![](gitian-building/select_startup_disk.png)
Installing Debian
------------------
This section will explain how to install Debian on the newly created VM.
- Choose the non-graphical installer. We do not need the graphical environment; it will only increase installation time and disk usage.
![](gitian-building/debian_install_1_boot_menu.png)
**Note**: Navigating in the Debian installer:
To keep a setting at the default and proceed, just press `Enter`.
To select a different button, press `Tab`.
- Choose locale and keyboard settings (doesn't matter, you can just go with the defaults or select your own information)
![](gitian-building/debian_install_2_select_a_language.png)
![](gitian-building/debian_install_3_select_location.png)
![](gitian-building/debian_install_4_configure_keyboard.png)
- The VM will detect network settings using DHCP, this should all proceed automatically
- Configure the network:
- Hostname `debian`.
- Leave domain name empty.
![](gitian-building/debian_install_5_configure_the_network.png)
- Choose a root password and enter it twice (remember it for later)
![](gitian-building/debian_install_6a_set_up_root_password.png)
- Name the new user `debian` (the full name doesn't matter, you can leave it empty)
- Set the account username as `debian`
![](gitian-building/debian_install_7_set_up_user_fullname.png)
![](gitian-building/debian_install_8_set_up_username.png)
- Choose a user password and enter it twice (remember it for later)
![](gitian-building/debian_install_9_user_password.png)
- The installer will set up the clock using a time server; this process should be automatic
- Set up the clock: choose a time zone (depends on the locale settings that you picked earlier; specifics don't matter)
![](gitian-building/debian_install_10_configure_clock.png)
- Disk setup
- Partitioning method: Guided - Use the entire disk
![](gitian-building/debian_install_11_partition_disks.png)
- Select disk to partition: SCSI1 (0,0,0)
![](gitian-building/debian_install_12_choose_disk.png)
- Partition Disks -> *All files in one partition*
![](gitian-building/all_files_in_one_partition.png)
- Finish partitioning and write changes to disk -> *Yes* (`Tab`, `Enter` to select the `Yes` button)
![](gitian-building/debian_install_14_finish.png)
![](gitian-building/debian_install_15_write_changes.png)
- The base system will be installed, this will take a minute or so
- Choose a mirror (any will do)
![](gitian-building/debian_install_16_choose_a_mirror.png)
- Enter proxy information (unless you are on an intranet, leave this empty)
![](gitian-building/debian_install_18_proxy_settings.png)
- Wait a bit while 'Select and install software' runs
- Participate in popularity contest -> *No*
- Choose software to install. We need just the base system.
- Make sure only 'SSH server' and 'Standard System Utilities' are checked
- Uncheck 'Debian Desktop Environment' and 'Print Server'
![](gitian-building/debian_install_19_software_selection.png)
- Install the GRUB boot loader to the master boot record? -> Yes
![](gitian-building/debian_install_20_install_grub.png)
- Device for boot loader installation -> ata-VBOX_HARDDISK
![](gitian-building/debian_install_21_install_grub_bootloader.png)
- Installation Complete -> *Continue*
- After installation, the VM will reboot and you will have a working Debian VM. Congratulations!
![](gitian-building/debian_install_22_finish_installation.png)
After Installation
-------------------
The next step in the guide involves logging in as root via SSH.
SSH login for root users is disabled by default, so we'll enable that now.
Login to the VM using username `root` and the root password you chose earlier.
You'll be presented with a screen similar to this.
![](gitian-building/debian_root_login.png)
Type:
### Common dependencies
Following dependencies are required to run `gitian-build.sh`:
```
sed -i 's/^PermitRootLogin.*/PermitRootLogin yes/' /etc/ssh/sshd_config
git ruby wget
```
and press enter. Then,
Optionally, to sign or verify binaries :
```
/etc/init.d/ssh restart
pgp
```
and enter to restart SSH. Logout by typing 'logout' and pressing 'enter'.
*To create a PGP key to sign files, see : https://gnupg.org/gph/en/manual.html#INTRO.
You will need to specify your [user ID](https://www.gnupg.org/documentation/manuals/gnupg/Specify-a-User-ID.html), find it using `gpg -k`.*
Connecting to the VM
----------------------
### Docker
After the VM has booted you can connect to it using SSH, and files can be copied from and to the VM using a SFTP utility.
Connect to `localhost`, port `22222` (or the port configured when installing the VM).
On Windows you can use [putty](http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html) and [WinSCP](http://winscp.net/eng/index.php).
Follow [Docker official documentation](https://docs.docker.com/engine/install/) to install it for your operating system.
For example, to connect as `root` from a Linux command prompt use
Make sure your user can run `docker` command without root privilege by being in the docker group :
```bash
$ sudo usermod -aG docker $(whoami)
$ ssh root@localhost -p 22222
The authenticity of host '[localhost]:22222 ([127.0.0.1]:22222)' can't be established.
RSA key fingerprint is ae:f5:c8:9f:17:c6:c7:1b:c2:1b:12:31:1d:bb:d0:c7.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '[localhost]:22222' (RSA) to the list of known hosts.
root@localhost's password: (enter root password configured during install)
# Enable group without logging out
$ newgrp docker
```
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Then use `--docker` option with `gitian-build.sh`.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
root@debian:~#
### LXC
Install the following package :
```
lxc
```
Replace `root` with `debian` to log in as user.
Then use `--lxc` option with `gitian-build.sh`.
Setting up Debian for Gitian building
--------------------------------------
### KVM
In this section we will be setting up the Debian installation for Gitian building.
[Documentation not available, help is welcome]
First we need to log in as `root` to set up dependencies and make sure that our
user can use the sudo command. Type/paste the following in the terminal:
### Apt-cacher
Disabled by default, `apt-cacher` enable to cache locally downloaded dependencies to save resources.
You will need the following package :
```
apache2 apt-cacher-ng
```
You can use your local server by using `--enable-apt-cacher`, or define `MIRROR_HOST` if you need to specify the server address.
> **Be nice:** Please use cache for intensive ressource usage to save mirrors bandwith.
## Usage
`gitian-build.sh` is a standalone script, it can be downloaded and run outside of Dogecoin Core repository.
It can download dependency files for the [Gitian](https://github.com/devrandom/gitian-builder), build and optionally sign binaries, or verify signatures.
Binaries and signatures will be created in folder `gitian-output/`.
### Syntax
```bash
apt-get install git ruby sudo apt-cacher-ng qemu-utils debootstrap lxc python-cheetah parted kpartx bridge-utils make ubuntu-archive-keyring curl
adduser debian sudo
$ ./gitian-build.sh [options] version
# See help menu for available options
$ ./gitian-build.sh --help
Arguments:
version Version number, commit, or branch to build. If building a
commit or branch, the -c option must be specified
Options:
--setup Setup dependencies for the gitian building environment. Uses Docker
-b|--build Do the gitian build
-B|--build-signed Build signed binaries for MacOS and Windows
-s|--sign name Sign builded executables with GPG
-v|--verify Verify the gitian build
--lxc Use LXC instead of KVM
--docker Use Docker instead of KVM
-o|--os lwx Specify which Operating Systems the build is for. Default is lwx,
l for Linux, w for Windows, x for MacOS
-j proc Number of processes to use. Default 2
-m n Memory to allocate in MiB. Default 2000
--enable-cache Use local apt-cacher server. If you need to specify host, use
MIRROR_HOST environment variable
-c|--commit Indicate that the version argument is for a commit or branch
-u|--url repo Specify the URL of the repository. Default is https://github.com/dogecoin/dogecoin
--test CI TEST. Uses Docker
-h|--help Print this help message
```
Then set up LXC and the rest with the following, which is a complex jumble of settings and workarounds:
### Example
The entire gitian flow can be performed step by step, example using docker :
```bash
# the version of lxc-start in Debian needs to run as root, so make sure
# that the build script can execute it without providing a password
echo "%sudo ALL=NOPASSWD: /usr/bin/lxc-start" > /etc/sudoers.d/gitian-lxc
echo "%sudo ALL=NOPASSWD: /usr/bin/lxc-execute" >> /etc/sudoers.d/gitian-lxc
# make /etc/rc.local script that sets up bridge between guest and host
echo '#!/bin/sh -e' > /etc/rc.local
echo 'brctl addbr br0' >> /etc/rc.local
echo 'ifconfig br0 10.0.3.2/24 up' >> /etc/rc.local
echo 'iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE' >> /etc/rc.local
echo 'echo 1 > /proc/sys/net/ipv4/ip_forward' >> /etc/rc.local
echo 'exit 0' >> /etc/rc.local
# make sure that USE_LXC is always set when logging in as debian,
# and configure LXC IP addresses
echo 'export USE_LXC=1' >> /home/debian/.profile
echo 'export GITIAN_HOST_IP=10.0.3.2' >> /home/debian/.profile
echo 'export LXC_GUEST_IP=10.0.3.5' >> /home/debian/.profile
reboot
# Download Gitian dependencies
$ ./gitian-build.sh --docker --setup 1.14.4
# Build & sign executables
$ ./gitian-build.sh --docker --build --sign SIGNER 1.14.4
# Verify signatures
$ ./gitian-build.sh --verify 1.14.4
```
At the end the VM is rebooted to make sure that the changes take effect. The steps in this
section only need to be performed once.
Installing Gitian
------------------
Re-login as the user `debian` that was created during installation.
The rest of the steps in this guide will be performed as that user.
There is no `python-vm-builder` package in Debian, so we need to install it from source ourselves,
Or to do everything at once :
```bash
wget http://archive.ubuntu.com/ubuntu/pool/universe/v/vm-builder/vm-builder_0.12.4+bzr494.orig.tar.gz
echo "76cbf8c52c391160b2641e7120dbade5afded713afaa6032f733a261f13e6a8e vm-builder_0.12.4+bzr494.orig.tar.gz" | sha256sum -c
# (verification -- must return OK)
tar -zxvf vm-builder_0.12.4+bzr494.orig.tar.gz
cd vm-builder-0.12.4+bzr494
sudo python setup.py install
cd ..
$ ./gitian-build.sh --docker --setup --build --sign SIGNER --verify 1.14.4
```
**Note**: When sudo asks for a password, enter the password for the user *debian* not for *root*.
Clone the git repositories for dogecoin and Gitian.
```bash
git clone https://github.com/devrandom/gitian-builder.git
git clone https://github.com/dogecoin/dogecoin.git
git clone https://github.com/dogecoin/gitian.sigs.git
```
Setting up the Gitian image
-------------------------
Gitian needs a virtual image of the operating system to build in.
Currently this is Ubuntu Trusty x86_64.
This image will be copied and used every time that a build is started to
make sure that the build is deterministic.
Creating the image will take a while, but only has to be done once.
Execute the following as user `debian`:
```bash
cd gitian-builder
bin/make-base-vm --lxc --arch amd64 --suite trusty
```
There will be a lot of warnings printed during the build of the image. These can be ignored.
**Note**: When sudo asks for a password, enter the password for the user *debian* not for *root*.
Getting and building the inputs
--------------------------------
At this point you have two options, you can either use the automated script (found in [contrib/gitian-build.sh](/contrib/gitian-build.sh)) or you could manually do everything by following this guide. If you're using the automated script, then run it with the "--setup" command. Afterwards, run it with the "--build" command (example: "contrib/gitian-building.sh -b signer 0.13.0"). Otherwise ignore this.
Follow the instructions in [doc/release-process.md](release-process.md#fetch-and-create-inputs-first-time-or-when-dependency-versions-change)
in the dogecoin repository under 'Fetch and create inputs' to install sources which require
manual intervention. Also optionally follow the next step: 'Seed the Gitian sources cache
and offline git repositories' which will fetch the remaining files required for building
offline.
Building Dogecoin Core
----------------
To build Dogecoin Core (for Linux, OS X and Windows) just follow the steps under 'perform
Gitian builds' in [doc/release-process.md](release-process.md#perform-gitian-builds) in the dogecoin repository.
This may take some time as it will build all the dependencies needed for each descriptor.
These dependencies will be cached after a successful build to avoid rebuilding them when possible.
At any time you can check the package installation and build progress with
```bash
tail -f var/install.log
tail -f var/build.log
```
Output from `gbuild` will look something like
Initialized empty Git repository in /home/debian/gitian-builder/inputs/dogecoin/.git/
remote: Counting objects: 57959, done.
remote: Total 57959 (delta 0), reused 0 (delta 0), pack-reused 57958
Receiving objects: 100% (57959/57959), 53.76 MiB | 484.00 KiB/s, done.
Resolving deltas: 100% (41590/41590), done.
From https://github.com/dogecoin/dogecoin
... (new tags, new branch etc)
--- Building for trusty amd64 ---
Stopping target if it is up
Making a new image copy
stdin: is not a tty
Starting target
Checking if target is up
Preparing build environment
Updating apt-get repository (log in var/install.log)
Installing additional packages (log in var/install.log)
Grabbing package manifest
stdin: is not a tty
Creating build script (var/build-script)
lxc-start: Connection refused - inotify event with no name (mask 32768)
Running build script (log in var/build.log)
Building an alternative repository
-----------------------------------
If you want to do a test build of a pull on GitHub it can be useful to point
the Gitian builder at an alternative repository, using the same descriptors
and inputs.
For example:
```bash
URL=https://github.com/laanwj/dogecoin.git
COMMIT=2014_03_windows_unicode_path
./bin/gbuild --commit dogecoin=${COMMIT} --url dogecoin=${URL} ../dogecoin/contrib/gitian-descriptors/gitian-linux.yml
./bin/gbuild --commit dogecoin=${COMMIT} --url dogecoin=${URL} ../dogecoin/contrib/gitian-descriptors/gitian-win.yml
./bin/gbuild --commit dogecoin=${COMMIT} --url dogecoin=${URL} ../dogecoin/contrib/gitian-descriptors/gitian-osx.yml
```
Building fully offline
-----------------------
For building fully offline including attaching signatures to unsigned builds, the detached-sigs repository
and the dogecoin git repository with the desired tag must both be available locally, and then gbuild must be
told where to find them. It also requires an apt-cacher-ng which is fully-populated but set to offline mode, or
manually disabling gitian-builder's use of apt-get to update the VM build environment.
To configure apt-cacher-ng as an offline cacher, you will need to first populate its cache with the relevant
files. You must additionally patch target-bin/bootstrap-fixup to set its apt sources to something other than
plain archive.ubuntu.com: us.archive.ubuntu.com works.
So, if you use LXC:
```bash
export PATH="$PATH":/path/to/gitian-builder/libexec
export USE_LXC=1
cd /path/to/gitian-builder
./libexec/make-clean-vm --suite trusty --arch amd64
LXC_ARCH=amd64 LXC_SUITE=trusty on-target -u root apt-get update
LXC_ARCH=amd64 LXC_SUITE=trusty on-target -u root \
-e DEBIAN_FRONTEND=noninteractive apt-get --no-install-recommends -y install \
$( sed -ne '/^packages:/,/[^-] .*/ {/^- .*/{s/"//g;s/- //;p}}' ../dogecoin/contrib/gitian-descriptors/*|sort|uniq )
LXC_ARCH=amd64 LXC_SUITE=trusty on-target -u root apt-get -q -y purge grub
LXC_ARCH=amd64 LXC_SUITE=trusty on-target -u root -e DEBIAN_FRONTEND=noninteractive apt-get -y dist-upgrade
```
And then set offline mode for apt-cacher-ng:
```
/etc/apt-cacher-ng/acng.conf
[...]
Offlinemode: 1
[...]
service apt-cacher-ng restart
```
Then when building, override the remote URLs that gbuild would otherwise pull from the Gitian descriptors::
```bash
cd /some/root/path/
git clone https://github.com/dogecoin/dogecoin-detached-sigs.git
BTCPATH=/some/root/path/dogecoin
SIGPATH=/some/root/path/dogecoin-detached-sigs
./bin/gbuild --url dogecoin=${BTCPATH},signature=${SIGPATH} ../dogecoin/contrib/gitian-descriptors/gitian-win-signer.yml
```
Signing externally
-------------------
### Signing externally
If you want to do the PGP signing on another device, that's also possible; just define `SIGNER` as mentioned
and follow the steps in the build process as normal.
gpg: skipped "laanwj": secret key not available
```bash
$ gpg: skipped "laanwj": secret key not available
```
When you execute `gsign` you will get an error from GPG, which can be ignored. Copy the resulting `.assert` files
in `gitian.sigs` to your signing machine and do
When you execute `gsign` you will get an error from GPG, which can be ignored. Copy the resulting `.assert` files in `gitian.sigs` to your signing machine and do
```bash
gpg --detach-sign ${VERSION}-linux/${SIGNER}/dogecoin-linux-build.assert
@ -468,12 +161,12 @@ in `gitian.sigs` to your signing machine and do
gpg --detach-sign ${VERSION}-osx-unsigned/${SIGNER}/dogecoin-osx-build.assert
```
This will create the `.sig` files that can be committed together with the `.assert` files to assert your
Gitian build.
This will create the `.sig` files that can be committed together with the `.assert` files to assert your Gitian build.
Uploading signatures
---------------------
## Publish signatures
After building and signing you can push your signatures (both the `.assert` and `.assert.sig` files) to the
[dogecoin/gitian.sigs](https://github.com/dogecoin/gitian.sigs/) repository, or if that's not possible create a pull
request. You can also mail the files to Wladimir (laanwj@gmail.com) and he will commit them.
Gitian signatures for each release are added to https://github.com/dogecoin/gitian.sigs.
`gitian-build.sh` will create signatures inside `gitian-output/sigs/` folder. Create a pull request to [dogecoin/gitian.sigs](https://github.com/dogecoin/gitian.sigs) to publish your signatures, the `.assert` and `.assert.sig` files.
**When your PR is merged, you will officially be a *Gitian Builder of Dogecoin* !**

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 166 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 177 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 71 KiB