Merge branch 'rust'

This commit is contained in:
Jeremy Soller 2020-05-25 21:52:43 -06:00
commit c1676c3856
No known key found for this signature in database
GPG Key ID: E988B49EE78A7FB1
71 changed files with 8866 additions and 733 deletions

10
.gitignore vendored
View File

@ -1,9 +1,12 @@
build
repo
source
source.tmp
source-new
source.tar
source.tar.tmp
stage
stage.tmp
stage.pkg
stage.pkgar
stage.sig
@ -11,4 +14,11 @@ stage.tar
stage.tar.gz
stage.toml
sysroot
sysroot.tmp
xargo
#Added by cargo
/target
**/*.rs.bk

1477
Cargo.lock generated Normal file

File diff suppressed because it is too large Load Diff

31
Cargo.toml Normal file
View File

@ -0,0 +1,31 @@
[package]
name = "redox_cookbook"
version = "0.1.0"
authors = ["Jeremy Soller <jackpot51@gmail.com>"]
edition = "2018"
default-run = "cook"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[[bin]]
name = "cook"
path = "src/bin/cook.rs"
[[bin]]
name = "cookbook_redoxer"
path = "src/bin/cookbook_redoxer.rs"
[lib]
name = "cookbook"
path = "src/lib.rs"
[dependencies]
blake3 = "0.3.4"
pbr = "1.0.2"
pkgar = "0.1.6"
redoxer = "0.2.19"
serde = { version = "1.0.110", features = ["derive"] }
sha2 = "0.8.2"
termion = "1.5.5"
toml = "0.5.6"
walkdir = "2.3.1"

5
recipes/acid/recipe.toml Normal file
View File

@ -0,0 +1,5 @@
[source]
git = "https://gitlab.redox-os.org/redox-os/acid.git"
[build]
template = "cargo"

View File

@ -0,0 +1,5 @@
[source]
git = "https://gitlab.redox-os.org/redox-os/audiod.git"
[build]
template = "cargo"

View File

@ -0,0 +1,14 @@
[source]
git = "https://gitlab.redox-os.org/redox-os/bootloader.git"
[build]
template = "custom"
script = """
ARCH="$(echo "${TARGET}" | cut -d - -f1)"
nasm \
-f bin \
-o "${COOKBOOK_STAGE}/bootloader" \
-D "ARCH_${ARCH}" \
-i"${COOKBOOK_SOURCE}/${ARCH}/" \
"${COOKBOOK_SOURCE}/${ARCH}/disk.asm"
"""

View File

@ -1,732 +0,0 @@
#!/usr/bin/env bash
# Begin /usr/sbin/make-ca.sh
#
# Script to create OpenSSL certs directory, GnuTLS certificate bundle, NSS
# shared DB, and Java cacerts from upstream certdata.txt and local sources
#
# Authors: DJ Lucas
# Bruce Dubbs
#
# Changes:
#
# 20170425 - Use p11-kit format anchors
# - Add CKA_NSS_MOZILLA_CA_POLICY attribute for p11-kit anchors
# - Add clientAuth OpenSSL attribute and (currently unused) NSS
# CKA_TRUST_CLIENT_AUTH
# 20170119 - Show trust bits on local certs
# - Add version output for help2man
# 20161210 - Add note about --force swich when same version
# 20161126 - Add -D/--destdir switch
# 20161124 - Add -f/--force switch to bypass version check
# - Add multiple switches to allow for alternate localtions
# - Add help text
# 20161118 - Drop make-cert.pl script
# - Add support for Java and NSSDB
# Set defaults
VERSION="20170425"
CERTDATA="certdata.txt"
PKIDIR="/etc/pki"
SSLDIR="/etc/ssl"
CERTUTIL="certutil"
KEYTOOL="keytool"
OPENSSL="openssl"
ANCHORDIR="${PKIDIR}/anchors"
CABUNDLE="${SSLDIR}/ca-bundle.crt"
CERTDIR="${SSLDIR}/certs"
KEYSTORE="${SSLDIR}/java/cacerts"
NSSDB="${PKIDIR}/nssdb"
LOCALDIR="${SSLDIR}/local"
DESTDIR=""
# Some data in the certs have UTF-8 characters
export LANG=en_US.utf8
TEMPDIR=$(mktemp -d)
WORKDIR="${TEMPDIR}/work"
WITH_NSS=1
WITH_JAVA=1
FORCE=0
function get_args(){
while test -n "${1}" ; do
case "${1}" in
-C | --certdata)
check_arg $1 $2
CERTDATA="${2}"
shift 2
;;
-D | --destdir)
check_arg $1 $2
DESTDIR="${2}"
shift 2
;;
-P | --pkidir)
check_arg $1 $2
PKIDIR="${2}"
ANCHORDIR="${PKIDIR}/anchors"
NSSDB="${PKIDIR}/nssdb"
echo "${@}" | grep -e "-a " -e "--anchordir" \
-e "-n " -e "--nssdb" > /dev/null
if test "${?}" == "0"; then
echo "Error! ${1} cannot be used with the -a/--anchordir or -n/--nssdb switches."
echo ""
exit 3
fi
shift 2
;;
-S | --ssldir)
check_arg $1 $2
SSLDIR="${2}"
CABUNDLE="${SSLDIR}/ca-bundle.crt"
CERTDIR="${SSLDIR}/certs"
KEYSTORE="${SSLDIR}/java/cacerts"
LOCALDIR="${SSLDIR}/local"
echo "${@}" | grep -e "-c " -e "--cafile" \
-e "-d " -e "--cadir" \
-e "-j " -e "--javacerts" > /dev/null
if test "${?}" == "0"; then
echo "Error! ${1} cannot be used with the -c/--cafile, -d/--cadir, or"
echo "-j/--javacerts switches."
echo ""
exit 3
fi
shift 2
;;
-a | --anchordir)
check_arg $1 $2
ANCHORDIR="${2}"
echo "${@}" | grep -e "-P " -e "--pkidir" > /dev/null
if test "${?}" == "0"; then
echo "Error! ${1} cannot be used with the -P/--pkidir switch."
echo ""
exit 3
fi
shift 2
;;
-c | --cafile)
check_arg $1 $2
CABUNDLE="${2}"
echo "${@}" | grep -e "-S " -e "--ssldir" > /dev/null
if test "${?}" == "0"; then
echo "Error! ${1} cannot be used with the -S/--ssldir switch."
echo ""
exit 3
fi
shift 2
;;
-d | --cadir)
check_arg $1 $2
CADIR="${2}"
if test "${?}" == "0"; then
echo "Error! ${1} cannot be used with the -S/--ssldir switch."
echo ""
exit 3
fi
shift 2
;;
-j | --javacerts)
check_arg $1 $2
KEYSTORE="${2}"
if test "${?}" == "0"; then
echo "Error! ${1} cannot be used with the -S/--ssldir switch."
echo ""
exit 3
fi
shift 2
;;
-l | --localdir)
check_arg $1 $2
LOCALDIR="${2}"
shift 2
;;
-n | --nssdb)
check_arg $1 $2
NSSDB="${2}"
echo "${@}" | grep -e "-P " -e "--pkidir" > /dev/null
if test "${?}" == "0"; then
echo "Error! ${1} cannot be used with the -P/--pkidir switch."
echo ""
exit 3
fi
shift 2
;;
-k | --keytool)
check_arg $1 $2
KEYTOOL="${2}"
shift 2
;;
-s | --openssl)
check_arg $1 $2
OPENSSL="${2}"
shift 2
;;
-t | --certutil)
check_arg $1 $2
CERTUTIL="${2}"
shift 2
;;
-f | --force)
FORCE="1"
shift 1
;;
-h | --help)
showhelp
exit 0
;;
-v | --version)
echo -e "$(basename ${0}) ${VERSION}\n"
exit 0
;;
*)
showhelp
exit 1
;;
esac
done
}
function check_arg(){
echo "${2}" | grep -v "^-" > /dev/null
if [ -z "$?" -o ! -n "$2" ]; then
echo "Error: $1 requires a valid argument."
exit 1
fi
}
function showhelp(){
echo ""
echo "`basename ${0}` converts certdata.txt (provided by the Mozilla Foundation)"
echo "into a complete PKI distribution for use with LFS or like distributions."
echo ""
echo " -C --certdata The certdata.txt file (provided by Mozilla)"
echo " Default: ./certdata.txt"
echo ""
echo " -D --destdir Change the output directory and use relative"
echo " paths for all other values."
echo " Default: unset"
echo ""
echo " -P --pkidir The output PKI directory - Cannot be used with"
echo " the -a/--anchordir or -n/--nssdb switches"
echo " Default: /etc/pki"
echo ""
echo " -S --ssldir The output SSL root direcotry - Cannot be used"
echo " with the -c/--cafile, -d/--cadir, or"
echo " -j/--javacerts switches"
echo " Defualt: /etc/ssl"
echo ""
echo " -a --anchordir The output directory for OpenSSL trusted"
echo " CA certificates used as trust anchors."
echo " Default: \$PKIDIR/anchors"
echo ""
echo " -c --cafile The output filename for the PEM formated bundle"
echo " Default: \$SSLDIR/ca-bundle.crt"
echo ""
echo " -d --cadir The output directory for the OpenSSL trusted"
echo " CA certificates"
echo " Deault: \$SSLDIR/certs/"
echo ""
echo " -j --javacerts The output path for the Java cacerts file"
echo " Default: \$SSLDIR/java/cacerts"
echo ""
echo " -l --localdir The path to a local set of OpenSSL trusted"
echo " certificates to include in the output"
echo " Default: \$SSLDIR/local"
echo ""
echo " -n --nssdb The output path for the shared NSS DB"
echo " Default: \$PKIDIR/nssdb"
echo ""
echo " -k --keytool The path to the java keytool utility"
echo ""
echo " -s --openssl The path to the openssl utility"
echo ""
echo " -t --certutil The path the certutil utility"
echo ""
echo " -f --force Force run, even if source is not newer"
echo ""
echo " -h --help Show this help message and exit"
echo ""
echo " -v --version Show version information and exit"
echo ""
echo "Example: `basename ${0}` -f -C ~/certdata.txt"
echo ""
}
# Convert CKA_TRUST values to trust flags for certutil
function convert_trust(){
case $1 in
CKT_NSS_TRUSTED_DELEGATOR)
echo "C"
;;
CKT_NSS_NOT_TRUSTED)
echo "p"
;;
CKT_NSS_MUST_VERIFY_TRUST)
echo ""
;;
esac
}
function convert_trust_arg(){
case $1 in
C)
case $2 in
sa)
echo "-addtrust serverAuth"
;;
sm)
echo "-addtrust emailProtection"
;;
cs)
echo "-addtrust codeSigning"
;;
ca)
echo "-addtrust clientAuth"
;;
esac
;;
p)
case $2 in
sa)
echo "-addreject serverAuth"
;;
sm)
echo "-addreject emailProtection"
;;
cs)
echo "-addreject codeSigning"
;;
ca)
echo "-addreject clientAuth"
;;
esac
;;
*)
echo ""
;;
esac
}
# Define p11-kit ext value constants (see p11-kit API documentation)
get-p11-val() {
case $1 in
p11sasmcs)
p11value="0%2a%06%03U%1d%25%01%01%ff%04 0%1e%06%08%2b%06%01%05%05%07%03%04%06%08%2b%06%01%05%05%07%03%01%06%08%2b%06%01%05%05%07%03%03"
;;
p11sasm)
p11value="0 %06%03U%1d%25%01%01%ff%04%160%14%06%08%2b%06%01%05%05%07%03%04%06%08%2b%06%01%05%05%07%03%01"
;;
p11sacs)
p11value="0 %06%03U%1d%25%01%01%ff%04%160%14%06%08%2b%06%01%05%05%07%03%01%06%08%2b%06%01%05%05%07%03%03"
;;
p11sa)
p11value="0%16%06%03U%1d%25%01%01%ff%04%0c0%0a%06%08%2b%06%01%05%05%07%03%01"
;;
p11smcs)
p11value="0 %06%03U%1d%25%01%01%ff%04%160%14%06%08%2b%06%01%05%05%07%03%04%06%08%2b%06%01%05%05%07%03%03"
;;
p11sm)
p11value="0%16%06%03U%1d%25%01%01%ff%04%0c0%0a%06%08%2b%06%01%05%05%07%03%04"
;;
p11cs)
p11value="0%16%06%03U%1d%25%01%01%ff%04%0c0%0a%06%08%2b%06%01%05%05%07%03%03"
;;
p11)
p11value="0%18%06%03U%1d%25%01%01%ff%04%0e0%0c%06%0a%2b%06%01%04%01%99w%06%0a%10"
;;
esac
}
# Process command line arguments
get_args $@
if test ! -r "${CERTDATA}"; then
echo "${CERTDATA} was not found. The certdata.txt file must be in the local"
echo "directory, or speficied with the --certdata switch."
exit 1
fi
test -f "${CERTUTIL}" || WITH_NSS=0
test -f "${KEYTOOL}" || WITH_JAVA=0
VERSION=$(grep CVS_ID "${CERTDATA}" | cut -d " " -f 8)
if test "${VERSION}x" == "x"; then
echo "WARNING! ${CERTDATA} has no 'Revision' in CVS_ID"
echo "Will run conversion unconditionally."
sleep 2
VERSION="$(date -u +%Y%m%d-%H%M)"
else
if test "${FORCE}" == "1"; then
echo "Output forced. Will run conversion unconditionally."
sleep 2
elif test "${DESTDIR}x" == "x"; then
test -f "${CABUNDLE}" &&
OLDVERSION=$(grep "^VERSION:" "${CABUNDLE}" | cut -d ":" -f 2)
fi
fi
if test "${OLDVERSION}x" == "${VERSION}x"; then
echo "No update required! Use --force to update anyway."
exit 0
fi
mkdir -p "${TEMPDIR}"/{certs,ssl/{certs,java},pki/{nssdb,anchors},work}
cp "${CERTDATA}" "${WORKDIR}/certdata.txt"
pushd "${WORKDIR}" > /dev/null
if test "${WITH_NSS}" == "1"; then
# Create a blank NSS DB
"${CERTUTIL}" -N --empty-password -d "sql:${TEMPDIR}/pki/nssdb"
fi
# Get a list of starting lines for each cert
CERTBEGINLIST=`grep -n "^# Certificate" "${WORKDIR}/certdata.txt" | \
cut -d ":" -f1`
# Dump individual certs to temp file
for certbegin in ${CERTBEGINLIST}; do
awk "NR==$certbegin,/^CKA_TRUST_STEP_UP_APPROVED/" "${WORKDIR}/certdata.txt" \
> "${TEMPDIR}/certs/${certbegin}.tmp"
done
unset CERTBEGINLIST certbegin
for tempfile in ${TEMPDIR}/certs/*.tmp; do
# Get a name for the cert
certname="$(grep "^# Certificate" "${tempfile}" | cut -d '"' -f 2)"
# Determine certificate trust values for SSL/TLS, S/MIME, and Code Signing
satrust="$(convert_trust `grep '^CKA_TRUST_SERVER_AUTH' ${tempfile} | \
cut -d " " -f 3`)"
smtrust="$(convert_trust `grep '^CKA_TRUST_EMAIL_PROTECTION' ${tempfile} | \
cut -d " " -f 3`)"
cstrust="$(convert_trust `grep '^CKA_TRUST_CODE_SIGNING' ${tempfile} | \
cut -d " " -f 3`)"
# Not currently included in NSS certdata.txt
#catrust="$(convert_trust `grep '^CKA_TRUST_CLIENT_AUTH' ${tempfile} | \
# cut -d " " -f 3`)"
# Get args for OpenSSL trust settings
saarg="$(convert_trust_arg "${satrust}" sa)"
smarg="$(convert_trust_arg "${smtrust}" sm)"
csarg="$(convert_trust_arg "${cstrust}" cs)"
# Not currently included in NSS certdata.txt
#caarg="$(convert_trust_arg "${catrust}" ca)"
# Convert to a PEM formated certificate
printf $(awk '/^CKA_VALUE/{flag=1;next}/^END/{flag=0}flag{printf $0}' \
"${tempfile}") | "${OPENSSL}" x509 -text -inform DER -fingerprint \
> tempfile.crt
# Get individual values for certificates
certkey="$(${OPENSSL} x509 -in tempfile.crt -noout -pubkey)"
certcer="$(${OPENSSL} x509 -in tempfile.crt)"
certtxt="$(${OPENSSL} x509 -in tempfile.crt -noout -text)"
# Get p11-kit label, oid, and values
p11label="$(grep -m1 "Issuer" ${tempfile} | grep -o CN=.*$ | \
cut -d ',' -f 1 | sed 's@CN=@@')"
# if distrusted at all, x-distrusted
if test "${satrust}" == "p" -o "${smtrust}" == "p" -o "${cstrust}" == "p"
then
# if any distrusted, x-distrusted
p11trust="x-distrusted: true"
p11oid="1.3.6.1.4.1.3319.6.10.1"
p11value="0.%06%0a%2b%06%01%04%01%99w%06%0a%01%04 0%1e%06%08%2b%06%01%05%05%07%03%04%06%08%2b%06%01%05%05%07%03%01%06%08%2b%06%01%05%05%07%03%03"
else
p11trust="trusted: true"
p11oid="2.5.29.37"
trustp11="p11"
if test "${satrust}" == "C"; then
trustp11="${trustp11}sa"
fi
if test "${smtrust}" == "C"; then
trustp11="${trustp11}sm"
fi
if test "${cstrust}" == "C"; then
trustp11="${trustp11}cs"
fi
get-p11-val "${trustp11}"
fi
# Get a hash for the cert
keyhash=$("${OPENSSL}" x509 -noout -in tempfile.crt -hash)
# Print information about cert
echo "Certificate: ${certname}"
echo "Keyhash: ${keyhash}"
# Place certificate into trust anchors dir
anchorfile="${TEMPDIR}/pki/anchors/${keyhash}.pem"
echo "[p11-kit-object-v1]" >> "${anchorfile}"
echo "label: \"${p11label}\"" >> "${anchorfile}"
echo "class: x-certificate-extension" >> "${anchorfile}"
echo "object-id: ${p11oid}" >> "${anchorfile}"
echo "value: \"${p11value}\"" >> "${anchorfile}"
echo "modifiable: false" >> "${anchorfile}"
echo "${certkey}" >> "${anchorfile}"
echo "" >> "${anchorfile}"
echo "[p11-kit-object-v1]" >> "${anchorfile}"
echo "label: \"${p11label}\"" >> "${anchorfile}"
echo "${p11trust}" >> "${anchorfile}"
echo "nss-mozilla-ca-policy: true" >> "${anchorfile}"
echo "modifiable: false" >> "${anchorfile}"
echo "${certcer}" >> "${anchorfile}"
echo "${certtxt}" | sed 's@^@#@' >> "${anchorfile}"
echo "Added to p11-kit anchor directory with trust '${satrust},${smtrust},${cstrust}'."
# Import certificates trusted for SSL/TLS into the Java keystore and
# GnuTLS certificate bundle
if test "${satrust}x" == "Cx"; then
# Java keystore
if test "${WITH_JAVA}" == "1"; then
"${KEYTOOL}" -import -noprompt -alias "${certname}" \
-keystore "${TEMPDIR}/ssl/java/cacerts" \
-storepass 'changeit' -file tempfile.crt \
2>&1> /dev/null | \
sed -e 's@Certificate was a@A@' -e 's@keystore@Java keystore.@'
fi
# GnuTLS certificate bundle
cat tempfile.crt >> "${TEMPDIR}/ssl/ca-bundle.crt.tmp"
echo "Added to GnuTLS ceritificate bundle."
fi
# Import certificate into the temporary certificate directory with
# trust arguments
"${OPENSSL}" x509 -in tempfile.crt -text -fingerprint \
-setalias "${certname}" ${saarg} ${smarg} ${csarg} \
> "${TEMPDIR}/ssl/certs/${keyhash}.pem"
echo "Added to OpenSSL certificate directory with trust '${satrust},${smtrust},${cstrust}'."
# Import all certificates with trust args to the temporary NSS DB
if test "${WITH_NSS}" == "1"; then
"${CERTUTIL}" -d "sql:${TEMPDIR}/pki/nssdb" -A \
-t "${satrust},${smtrust},${cstrust}" \
-n "${certname}" -i tempfile.crt
echo "Added to NSS shared DB with trust '${satrust},${smtrust},${cstrust}'."
fi
# Clean up the directory and environment as we go
rm -f tempfile.crt
unset keyhash subject certname
unset satrust smtrust cstrust catrust sarg smarg csarg caarg
unset p11trust p11oid p11value trustp11 certkey certcer certtxt
echo -e "\n"
done
unset tempfile
# Sanity check
count=$(ls "${TEMPDIR}"/ssl/certs/*.pem | wc -l)
# Historically there have been between 152 and 165 certs
# A minimum of 140 should be safe for a rudimentry sanity check
if test "${count}" -lt "140" ; then
echo "Error! Only ${count} certificates were generated!"
echo "Exiting without update!"
echo ""
echo "${TEMPDIR} is the temporary working directory"
exit 2
fi
unset count
# Generate the bundle
bundlefile=`basename "${CABUNDLE}"`
bundledir=`echo "${CABUNDLE}" | sed "s@/${bundlefile}@@"`
install -vdm755 "${DESTDIR}${bundledir}" 2>&1>/dev/null
test -f "${DESTDIR}${CABUNDLE}" && mv "${DESTDIR}${CABUNDLE}" \
"${DESTDIR}${CABUNDLE}.old"
echo "VERSION:${VERSION}" > "${DESTDIR}${CABUNDLE}"
cat "${TEMPDIR}/ssl/ca-bundle.crt.tmp" >> "${DESTDIR}${CABUNDLE}" &&
rm -f "${DESTDIR}${CABUNDLE}.old"
unset bundlefile bundledir
# Install Java Cacerts
if test "${WITH_JAVA}" == "1"; then
javafile=`basename "${KEYSTORE}"`
javadir=`echo "${KEYSTORE}" | sed "s@/${javafile}@@"`
install -vdm755 "${DESTDIR}${javadir}" 2>&1>/dev/null
test -f "${DESTDIR}${KEYSTORE}" && mv "${DESTDIR}${KEYSTORE}" \
"${DESTDIR}${KEYSTORE}.old"
install -m644 "${TEMPDIR}/ssl/java/cacerts" "${DESTDIR}${KEYSTORE}" &&
rm -f "${DESTDIR}${KEYSTORE}.old"
unset javafile javadir
fi
# Install NSS Shared DB
if test "${WITH_NSS}" == "1"; then
sed -e "s@${TEMPDIR}/pki/nssdb@${NSSDB}@" \
-e 's/library=/library=libnsssysinit.so/' \
-e 's/Flags=internal/Flags=internal,moduleDBOnly/' \
-i "${TEMPDIR}/pki/nssdb/pkcs11.txt"
test -d "${DESTDIR}${NSSDB}" && mv "${DESTDIR}${NSSDB}" \
"${DESTDIR}${NSSDB}.old"
install -dm755 "${DESTDIR}${NSSDB}" 2>&1>/dev/null
install -m644 "${TEMPDIR}"/pki/nssdb/{cert9.db,key4.db,pkcs11.txt} \
"${DESTDIR}${NSSDB}" &&
rm -rf "${DESTDIR}${NSSDB}.old"
fi
# Install anchors in $ANCHORDIR
test -d "${DESTDIR}${ANCHORDIR}" && mv "${DESTDIR}${ANCHORDIR}"\
"${DESTDIR}${ANCHORDIR}.old"
install -dm755 "${DESTDIR}${ANCHORDIR}" 2>&1>/dev/null
install -m644 "${TEMPDIR}"/pki/anchors/*.pem "${DESTDIR}${ANCHORDIR}" &&
rm -rf "${DESTDIR}${ANCHORDIR}.old"
# Install certificates in $CERTDIR
test -d "${DESTDIR}${CERTDIR}" && mv "${DESTDIR}${CERTDIR}" \
"${DESTDIR}${CERTDIR}.old"
install -dm755 "${DESTDIR}${CERTDIR}" 2>&1>/dev/null
install -m644 "${TEMPDIR}"/ssl/certs/*.pem "${DESTDIR}${CERTDIR}" &&
rm -rf "${DESTDIR}${CERTDIR}.old"
# Import any certs in $LOCALDIR
# Don't do any checking, just trust the admin
if test -d "${LOCALDIR}"; then
for cert in `find "${LOCALDIR}" -name "*.pem"`; do
# Get some information about the certificate
keyhash=$("${OPENSSL}" x509 -noout -in "${cert}" -hash)
subject=$("${OPENSSL}" x509 -noout -in "${cert}" -subject)
count=1
while test "${count}" -lt 10; do
echo "${subject}" | cut -d "/" -f "${count}" | grep "CN=" >/dev/null \
&& break
let count++
done
certname=$(echo "${subject}" | cut -d "/" -f "${count}" | sed 's@CN=@@')
echo "Certificate: ${certname}"
echo "Keyhash: ${keyhash}"
# Get trust information
trustlist=$("${OPENSSL}" x509 -in "${cert}" -text -trustout | \
grep -A1 "Trusted Uses")
satrust=""
smtrust=""
cstrust=""
catrust=""
satrust=$(echo "${trustlist}" | \
grep "TLS Web Server" 2>&1> /dev/null && echo "C")
smtrust=$(echo "${trustlist}" | \
grep "E-mail Protection" 2>&1 >/dev/null && echo "C")
cstrust=$(echo "${trustlist}" | \
grep "Code Signing" 2>&1 >/dev/null && echo "C")
catrust=$(echo "${trustlist}" | \
grep "Client Auth" 2>&1 >/dev/null && echo "C")
# Get reject information
rejectlist=$("${OPENSSL}" x509 -in "${cert}" -text -trustout | \
grep -A1 "Rejected Uses")
if test "${satrust}" == ""; then satrust=$(echo "${rejectlist}" | \
grep "TLS Web Server" 2>&1> /dev/null && echo "p"); fi
if test "${smtrust}" == ""; then smtrust=$(echo "${rejectlist}" | \
grep "E-mail Protection" 2>&1> /dev/null && echo "p"); fi
if test "${cstrust}" == ""; then cstrust=$(echo "${rejectlist}" | \
grep "Code Signing" 2>&1> /dev/null && echo "p"); fi
if test "${catrust}" == ""; then catrust=$(echo "${rejectlist}" | \
grep "Client Auth" 2>&1> /dev/null && echo "p"); fi
# Place certificate into trust anchors dir
p11label="$(grep -m1 "Issuer" ${cert} | grep -o CN=.*$ | \
cut -d ',' -f 1 | sed 's@CN=@@')"
# if distrusted at all, x-distrusted
if test "${satrust}" == "p" -o "${smtrust}" == "p" -o "${cstrust}" == "p"
then
# if any distrusted, x-distrusted
p11trust="x-distrusted: true"
p11oid="1.3.6.1.4.1.3319.6.10.1"
p11value="0.%06%0a%2b%06%01%04%01%99w%06%0a%01%04 0%1e%06%08%2b%06%01%05%05%07%03%04%06%08%2b%06%01%05%05%07%03%01%06%08%2b%06%01%05%05%07%03%03"
else
p11trust="trusted: true"
p11oid="2.5.29.37"
trustp11="p11"
if test "${satrust}" == "C"; then
trustp11="${trustp11}sa"
fi
if test "${smtrust}" == "C"; then
trustp11="${trustp11}sm"
fi
if test "${cstrust}" == "C"; then
trustp11="${trustp11}cs"
fi
get-p11-val "${trustp11}"
fi
anchorfile="${DESTDIR}${ANCHORDIR}/${keyhash}.pem"
echo "[p11-kit-object-v1]" >> "${anchorfile}"
echo "label: \"${p11label}\"" >> "${anchorfile}"
echo "class: x-certificate-extension" >> "${anchorfile}"
echo "object-id: ${p11oid}" >> "${anchorfile}"
echo "value: \"${p11value}\"" >> "${anchorfile}"
echo "modifiable: false" >> "${anchorfile}"
echo "${certkey}" >> "${anchorfile}"
echo "" >> "${anchorfile}"
echo "[p11-kit-object-v1]" >> "${anchorfile}"
echo "label: \"${p11label}\"" >> "${anchorfile}"
echo "${p11trust}" >> "${anchorfile}"
echo "modifiable: false" >> "${anchorfile}"
echo "${certcer}" >> "${anchorfile}"
echo "${certtxt}" | sed 's@^@#@' >> "${anchorfile}"
echo "Added to p11-kit anchor directory with trust '${satrust},${smtrust},${cstrust}'."
# Install in Java keystore
if test "${WITH_JAVA}" == "1" -a "${satrust}x" == "Cx"; then
"${KEYTOOL}" -import -noprompt -alias "${certname}" \
-keystore "${DESTDIR}${KEYSTORE}" \
-storepass 'changeit' -file "${cert}" 2>&1> /dev/null | \
sed -e 's@Certificate was a@A@' -e 's@keystore@Java keystore.@'
fi
# Append to the bundle - source should have trust info, process with
# openssl x509 to strip
if test "${satrust}x" == "Cx"; then
"${OPENSSL}" x509 -in "${cert}" -text -fingerprint \
>> "${DESTDIR}${CABUNDLE}"
echo "Added to GnuTLS certificate bundle."
fi
# Install into OpenSSL certificate store
"${OPENSSL}" x509 -in "${cert}" -text -fingerprint \
-setalias "${certname}" \
>> "${DESTDIR}${CERTDIR}/${keyhash}.pem"
echo "Added to OpenSSL certificate directory with trust '${satrust},${smtrust},${cstrust},${catrust}'."
# Add to Shared NSS DB
if test "${WITH_NSS}" == "1"; then
"${OPENSSL}" x509 -in "${cert}" -text -fingerprint | \
"${CERTUTIL}" -d "sql:${DESTDIR}${NSSDB}" -A \
-t "${satrust},${smtrust},${cstrust}" \
-n "${certname}"
echo "Added to NSS shared DB with trust '${satrust},${smtrust},${cstrust}'."
fi
unset keyhash subject count certname
unset trustlist rejectlist satrust smtrust cstrust catrust
unset p11trust p11oid p11value trustp11 certkey certcer certtxt
echo ""
done
unset cert
fi
c_rehash "${DESTDIR}${CERTDIR}" 2>&1>/dev/null
popd > /dev/null
# Clean up the mess
rm -rf "${TEMPDIR}"
# End /usr/sbin/make-ca.sh

View File

@ -0,0 +1,13 @@
[source]
git = "https://gitlab.redox-os.org/redox-os/ca-certificates.git"
[build]
template = "custom"
script = """
curl \
-o certdata.txt \
--time-cond certdata.txt \
https://hg.mozilla.org/releases/mozilla-release/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt
"${COOKBOOK_SOURCE}/make-ca.sh" -D "${COOKBOOK_BUILD}"
cp -rv "${COOKBOOK_BUILD}/etc/ssl/certs" "${COOKBOOK_STAGE}/ssl"
"""

View File

@ -0,0 +1,5 @@
[source]
git = "https://gitlab.redox-os.org/redox-os/contain.git"
[build]
template = "cargo"

View File

@ -0,0 +1,5 @@
[source]
git = "https://gitlab.redox-os.org/redox-os/coreutils.git"
[build]
template = "cargo"

39
recipes/curl/recipe.toml Normal file
View File

@ -0,0 +1,39 @@
[source]
git = "https://gitlab.redox-os.org/redox-os/curl.git"
branch = "redox"
[build]
template = "custom"
dependencies = [
"nghttp2",
"openssl",
"zlib"
]
script = """
rsync -av --delete "${COOKBOOK_SOURCE}/" ./
wget -O config.sub http://git.savannah.gnu.org/cgit/config.git/plain/config.sub
autoreconf -i
COOKBOOK_CONFIGURE="./configure"
COOKBOOK_CONFIGURE_FLAGS=(
--build="$(cc -dumpmachine)"
--host="${TARGET}"
--prefix=""
--disable-ftp
--disable-ipv6
--disable-ntlm-wb
--disable-shared
--disable-tftp
--disable-threaded-resolver
--enable-static
--with-ca-path=/ssl/certs
--with-nghttp2="${COOKBOOK_SYSROOT}"
--with-ssl="${COOKBOOK_SYSROOT}"
--with-zlib="${COOKBOOK_SYSROOT}"
)
cookbook_configure
"""
[package]
dependencies = [
"ca-certificates"
]

21
recipes/dash/recipe.toml Normal file
View File

@ -0,0 +1,21 @@
[source]
git = "https://gitlab.redox-os.org/redox-os/dash.git"
branch = "redox"
[build]
template = "custom"
script = """
rsync -av --delete "${COOKBOOK_SOURCE}/" ./
./autogen.sh
./configure \
--host="${TARGET}" \
--prefix="" \
--enable-static \
cross_compiling=yes
# See https://stackoverflow.com/questions/4247068/sed-command-with-i-option-failing-on-mac-but-works-on-linux.
sed -i'' -e 's|#define HAVE_GETRLIMIT 1|/* #undef HAVE_GETRLIMIT */|g' config.h
# Skip configure
COOKBOOK_CONFIGURE="true"
COOKBOOK_CONFIGURE_FLAGS=()
cookbook_configure
"""

View File

@ -0,0 +1,27 @@
[source]
git = "https://gitlab.redox-os.org/redox-os/drivers.git"
[build]
template = "custom"
script = """
redoxer build --release \
--manifest-path "${COOKBOOK_SOURCE}/Cargo.toml" \
--workspace
mkdir -pv "${COOKBOOK_STAGE}/bin"
find "target/${TARGET}/release" \
-maxdepth 1 \
-executable \
-type f \
-exec cp -v {} "${COOKBOOK_STAGE}/bin/" ';'
mkdir -pv "${COOKBOOK_STAGE}/etc/pcid"
cp -v "${COOKBOOK_SOURCE}/initfs.toml" "${COOKBOOK_STAGE}/etc/pcid/initfs.toml"
mkdir -pv "${COOKBOOK_STAGE}/etc/pcid.d"
find "${COOKBOOK_SOURCE}" -maxdepth 2 -type f -name 'config.toml' | while read conf
do
driver="$(basename "$(dirname "$conf")")"
cp -v "$conf" "${COOKBOOK_STAGE}/etc/pcid.d/$driver.toml"
done
"""

View File

@ -0,0 +1,5 @@
[source]
git = "https://gitlab.redox-os.org/redox-os/exampled.git"
[build]
template = "cargo"

View File

@ -0,0 +1,5 @@
[source]
tar = "https://github.com/libexpat/libexpat/releases/download/R_2_2_6/expat-2.2.6.tar.bz2"
[build]
template = "configure"

View File

@ -0,0 +1,8 @@
[source]
git = "https://gitlab.redox-os.org/redox-os/extrautils.git"
[build]
template = "cargo"
dependencies = [
"xz"
]

View File

@ -0,0 +1,11 @@
[source]
git = "https://gitlab.redox-os.org/redox-os/findutils.git"
[build]
template = "custom"
script = """
COOKBOOK_CARGO_FLAGS+=(
--bin find
)
cookbook_cargo
"""

View File

@ -0,0 +1,9 @@
[source]
tar = "https://download.savannah.gnu.org/releases/freetype/freetype-2.9.1.tar.gz"
[build]
template = "configure"
dependencies = [
"libpng",
"zlib"
]

5
recipes/init/recipe.toml Normal file
View File

@ -0,0 +1,5 @@
[source]
git = "https://gitlab.redox-os.org/redox-os/init.git"
[build]
template = "cargo"

View File

@ -0,0 +1,5 @@
[source]
git = "https://gitlab.redox-os.org/redox-os/installer.git"
[build]
template = "cargo"

5
recipes/ion/recipe.toml Normal file
View File

@ -0,0 +1,5 @@
[source]
git = "https://gitlab.redox-os.org/redox-os/ion.git"
[build]
template = "cargo"

5
recipes/ipcd/recipe.toml Normal file
View File

@ -0,0 +1,5 @@
[source]
git = "https://gitlab.redox-os.org/redox-os/ipcd.git"
[build]
template = "cargo"

View File

@ -0,0 +1,8 @@
[source]
tar = "https://sourceware.org/pub/libffi/libffi-3.2.1.tar.gz"
patches = [
"redox.patch"
]
[build]
template = "configure"

2820
recipes/libffi/redox.patch Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,14 @@
[source]
tar = "https://ftp.gnu.org/pub/gnu/libiconv/libiconv-1.15.tar.gz"
patches = [
"01_redox.patch"
]
[build]
template = "custom"
script = """
COOKBOOK_CONFIGURE_FLAGS+=(
ac_cv_have_decl_program_invocation_name=no
)
cookbook_configure
"""

View File

@ -0,0 +1,5 @@
[source]
tar = "http://ijg.org/files/jpegsrc.v9c.tar.gz"
[build]
template = "configure"

View File

@ -0,0 +1,9 @@
[source]
tar = "http://downloads.xiph.org/releases/ogg/libogg-1.3.3.tar.xz"
blake3 = "8220c0e4082fa26c07b10bfe31f641d2e33ebe1d1bb0b20221b7016bc8b78a3a"
patches = [
"redox.patch"
]
[build]
template = "configure"

2833
recipes/libogg/redox.patch Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,10 @@
[source]
git = "https://gitlab.redox-os.org/redox-os/liborbital.git"
[build]
template = "custom"
script = """
rsync -av --delete "${COOKBOOK_SOURCE}/" ./
"${COOKBOOK_CARGO}" build --release
"${COOKBOOK_MAKE}" install HOST="${TARGET}" DESTDIR="${COOKBOOK_STAGE}"
"""

View File

@ -0,0 +1,13 @@
[source]
tar = "https://github.com/glennrp/libpng/archive/v1.6.36.tar.gz"
script = """
chmod +w config.sub
wget -O config.sub http://git.savannah.gnu.org/cgit/config.git/plain/config.sub
"""
[build]
template = "configure"
dependencies = [
"zlib"
]

View File

@ -0,0 +1,9 @@
[source]
tar = "https://github.com/jedisct1/libsodium/archive/1.0.16.tar.gz"
patches = [
"random.patch"
]
script = "./autogen.sh"
[build]
template = "configure"

View File

@ -0,0 +1,9 @@
[source]
tar = "http://downloads.xiph.org/releases/vorbis/libvorbis-1.3.6.tar.xz"
sha256 = "af00bb5a784e7c9e69f56823de4637c350643deedaf333d0fa86ecdba6fcb415"
[build]
template = "configure"
dependencies = [
"libogg"
]

View File

@ -0,0 +1,15 @@
[source]
tar = "ftp://xmlsoft.org/libxml2/libxml2-2.9.9.tar.gz"
[build]
template = "custom"
dependencies = [
"xz",
"zlib"
]
script = """
COOKBOOK_CONFIGURE_FLAGS+=(
--without-python
)
cookbook_configure
"""

5
recipes/logd/recipe.toml Normal file
View File

@ -0,0 +1,5 @@
[source]
git = "https://gitlab.redox-os.org/redox-os/logd.git"
[build]
template = "cargo"

5
recipes/nasm/recipe.toml Normal file
View File

@ -0,0 +1,5 @@
[source]
tar = "http://www.nasm.us/pub/nasm/releasebuilds/2.14.02/nasm-2.14.02.tar.gz"
[build]
template = "configure"

View File

@ -0,0 +1,8 @@
[source]
git = "https://gitlab.redox-os.org/redox-os/netdb.git"
[build]
template = "custom"
script = """
cp -rv "${COOKBOOK_SOURCE}/"* "${COOKBOOK_STAGE}"
"""

View File

@ -0,0 +1,5 @@
[source]
git = "https://gitlab.redox-os.org/redox-os/netstack.git"
[build]
template = "cargo"

View File

@ -0,0 +1,6 @@
[source]
git = "https://gitlab.redox-os.org/redox-os/netutils.git"
branch = "redox-unix"
[build]
template = "cargo"

View File

@ -0,0 +1,11 @@
[source]
tar = "https://github.com/nghttp2/nghttp2/releases/download/v1.37.0/nghttp2-1.37.0.tar.xz"
[build]
template = "custom"
script = """
COOKBOOK_CONFIGURE_FLAGS+=(
--enable-lib-only
)
cookbook_configure
"""

View File

@ -0,0 +1,5 @@
[source]
git = "https://gitlab.redox-os.org/redox-os/nulld.git"
[build]
template = "cargo"

View File

@ -0,0 +1,18 @@
[source]
git = "https://gitlab.redox-os.org/redox-os/openssl.git"
branch = "redox"
[build]
template = "custom"
script = """
ARCH="${TARGET%%-*}"
COOKBOOK_CONFIGURE="${COOKBOOK_SOURCE}/Configure"
COOKBOOK_CONFIGURE_FLAGS=(
no-shared
no-dgram
"redox-${ARCH}"
--prefix="/"
)
cookbook_configure
rm -rfv "${COOKBOOK_STAGE}/"{share,ssl}
"""

View File

@ -0,0 +1,9 @@
[source]
git = "https://gitlab.redox-os.org/redox-os/orbdata.git"
[build]
template = "custom"
script = """
mkdir -pv "${COOKBOOK_STAGE}/ui"
cp -rv "${COOKBOOK_SOURCE}/"* "${COOKBOOK_STAGE}/ui"
"""

View File

@ -0,0 +1,10 @@
[source]
git = "https://gitlab.redox-os.org/redox-os/orbital.git"
[build]
template = "cargo"
[package]
dependencies = [
"orbdata"
]

View File

@ -0,0 +1,17 @@
[source]
git = "https://gitlab.redox-os.org/redox-os/orbterm.git"
[build]
template = "custom"
script = """
COOKBOOK_CARGO_FLAGS=(
--path "${COOKBOOK_SOURCE}"
--root "${COOKBOOK_STAGE}/ui"
)
cookbook_cargo
"""
[package]
depends = [
"orbital"
]

View File

@ -0,0 +1,17 @@
[source]
git = "https://gitlab.redox-os.org/redox-os/orbutils.git"
[build]
template = "custom"
script = """
COOKBOOK_CARGO_FLAGS=(
--path "${COOKBOOK_SOURCE}"
--root "${COOKBOOK_STAGE}/ui"
)
cookbook_cargo
"""
[package]
depends = [
"orbital"
]

8
recipes/pcre/recipe.toml Normal file
View File

@ -0,0 +1,8 @@
[source]
tar = "https://ftp.pcre.org/pub/pcre/pcre-8.42.tar.bz2"
patches = [
"redox.patch"
]
[build]
template = "configure"

View File

@ -0,0 +1,5 @@
[source]
git = "https://gitlab.redox-os.org/redox-os/pkgar.git"
[build]
template = "cargo"

View File

@ -0,0 +1,5 @@
[source]
git = "https://gitlab.redox-os.org/redox-os/pkgutils.git"
[build]
template = "cargo"

5
recipes/ptyd/recipe.toml Normal file
View File

@ -0,0 +1,5 @@
[source]
git = "https://gitlab.redox-os.org/redox-os/ptyd.git"
[build]
template = "cargo"

View File

@ -0,0 +1,5 @@
[source]
git = "https://gitlab.redox-os.org/redox-os/ramfs.git"
[build]
template = "cargo"

View File

@ -0,0 +1,12 @@
[source]
git = "https://gitlab.redox-os.org/redox-os/redoxer.git"
[build]
template = "custom"
script = """
COOKBOOK_CARGO_FLAGS=(
--path "${COOKBOOK_SOURCE}/daemon"
--root "${COOKBOOK_STAGE}"
)
cookbook_cargo
"""

View File

@ -0,0 +1,5 @@
[source]
git = "https://gitlab.redox-os.org/redox-os/redoxfs.git"
[build]
template = "cargo"

View File

@ -0,0 +1,5 @@
[source]
git = "https://github.com/jackpot51/ripgrep.git"
[build]
template = "cargo"

23
recipes/sdl/recipe.toml Normal file
View File

@ -0,0 +1,23 @@
[source]
tar = "https://www.libsdl.org/release/SDL-1.2.15.tar.gz"
patches = [
"redox.patch"
]
script = "./autogen.sh"
[build]
template = "custom"
dependencies = [
"liborbital"
]
script = """
COOKBOOK_CONFIGURE_FLAGS+=(
--disable-pulseaudio
--disable-video-x11
--disable-loadso
--enable-redoxaudio
--enable-clock_gettime
--enable-video-orbital
)
cookbook_configure
"""

8
recipes/sed/recipe.toml Normal file
View File

@ -0,0 +1,8 @@
[source]
tar = "http://ftp.gnu.org/gnu/sed/sed-4.4.tar.xz"
patches = [
"sed.patch"
]
[build]
template = "configure"

View File

@ -0,0 +1,5 @@
[source]
git = "https://gitlab.redox-os.org/redox-os/shellstorm.git"
[build]
template = "cargo"

View File

@ -0,0 +1,5 @@
[source]
git = "https://gitlab.redox-os.org/redox-os/Smith.git"
[build]
template = "cargo"

View File

@ -0,0 +1,5 @@
[source]
git = "https://gitlab.redox-os.org/redox-os/strace-redox.git"
[build]
template = "cargo"

View File

@ -0,0 +1,13 @@
[source]
git = "https://gitlab.redox-os.org/redox-os/userutils.git"
[build]
template = "custom"
script = """
cookbook_cargo
cp -rv "${COOKBOOK_SOURCE}/res" "${COOKBOOK_STAGE}/etc"
ln -s id "${COOKBOOK_STAGE}/bin/whoami"
chmod +s "${COOKBOOK_STAGE}/bin/passwd"
chmod +s "${COOKBOOK_STAGE}/bin/sudo"
chmod +s "${COOKBOOK_STAGE}/bin/su"
"""

View File

@ -0,0 +1,98 @@
[source]
git = "https://gitlab.redox-os.org/redox-os/uutils.git"
branch = "redox-unix"
[build]
template = "custom"
script = """
COOKBOOK_CARGO_FLAGS+=(
--no-default-features
--features redox
--bin uutils
)
cookbook_cargo
BINS=(
base32
base64
basename
cat
chmod
cksum
comm
cp
cut
date
dircolors
dirname
echo
env
expand
expr
factor
false
fmt
fold
hashsum
head
install
join
link
ln
ls
md5sum
mkdir
mktemp
more
mv
nl
od
paste
printenv
printf
ptx
pwd
readlink
realpath
relpath
rm
rmdir
seq
sha1sum
sha224sum
sha256sum
sha3-224sum
sha3-256sum
sha3-384sum
sha3-512sum
sha384sum
sha3sum
sha512sum
shake128sum
shake256sum
shred
shuf
sleep
sort
split
sum
tac
tail
tee
test
tr
true
truncate
tsort
uname
unexpand
uniq
wc
yes
)
for bin in "${BINS[@]}"
do
ln -sv uutils "${COOKBOOK_STAGE}/bin/$bin"
done
"""

31
recipes/xz/recipe.toml Normal file
View File

@ -0,0 +1,31 @@
[source]
tar = "https://codeload.github.com/xz-mirror/xz/tar.gz/v5.2.3"
patches = [
"01-no-poll.patch",
"02-o_noctty.patch",
"03-no-signals.patch"
]
script = """
./autogen.sh
chmod +w build-aux/config.sub
wget -O build-aux/config.sub http://git.savannah.gnu.org/cgit/config.git/plain/config.sub
"""
[build]
template = "custom"
script = """
export CFLAGS="-static"
COOKBOOK_CONFIGURE_FLAGS=(
--host="${TARGET}"
--prefix=""
--disable-lzmadec
--disable-lzmainfo
--disable-xz
--disable-xzdec
--enable-shared=no
--enable-static=yes
--enable-threads=no
--with-pic=no
)
cookbook_configure
"""

View File

@ -0,0 +1,5 @@
[source]
git = "https://gitlab.redox-os.org/redox-os/zerod.git"
[build]
template = "cargo"

15
recipes/zlib/recipe.toml Normal file
View File

@ -0,0 +1,15 @@
[source]
tar = "http://zlib.net/zlib-1.2.11.tar.gz"
blake3 = "20db628054c3c09edea193700ca39d3c033655529cbdc5d88f3c5da7514ad949"
[build]
template = "custom"
script = """
export LDFLAGS="--static"
# See https://stackoverflow.com/questions/21396988/zlib-build-not-configuring-properly-with-cross-compiler-ignores-ar.
CHOST="${TARGET}" "${COOKBOOK_CONFIGURE}" \
--prefix="" \
--static
"${COOKBOOK_MAKE}" -j "$(nproc)"
"${COOKBOOK_MAKE}" install DESTDIR="${COOKBOOK_STAGE}"
"""

14
repo.sh
View File

@ -22,9 +22,15 @@ fi
for recipe in $recipes
do
if [ -e "recipes/$recipe/recipe.toml" ]
then
target/release/cook "$recipe"
continue
fi
if [ ! -d "recipes/$recipe/source/" ]
then
echo -e "\033[01;38;5;215mrepo - fetching $recipe\033[0m" >&2
echo -e "\033[01;38;5;155mrepo - fetching $recipe\033[0m" >&2
./cook.sh "$recipe" fetch
fi
@ -32,6 +38,10 @@ do
then
echo -e "\033[01;38;5;155mrepo - preparing $recipe\033[0m" >&2
./cook.sh "$recipe" prepare
elif [ ! -d "recipes/$recipe/sysroot/" ]
then
echo -e "\033[01;38;5;155mrepo - repreparing $recipe\033[0m" >&2
./cook.sh "$recipe" unprepare prepare
else
TIME_SOURCE="$($FIND recipes/$recipe/source/ -type f -not -path '*/.git*' -printf "%Ts\n" | sort -nr | head -n 1)"
TIME_BUILD="$($FIND recipes/$recipe/build/ -type f -not -path '*/.git*' -printf "%Ts\n" | sort -nr | head -n 1)"
@ -74,6 +84,8 @@ do
fi
done
mkdir -p "$REPO"
for recipe in $recipes
do
if [ "recipes/$recipe/stage.tar.gz" -nt "$REPO/$recipe.tar.gz" ]

720
src/bin/cook.rs Normal file
View File

@ -0,0 +1,720 @@
use cookbook::blake3::blake3_progress;
use cookbook::recipe::{Recipe, SourceRecipe, BuildKind, BuildRecipe, PackageRecipe};
use cookbook::sha256::sha256_progress;
use std::{
env,
fs,
io::{self, Write},
path::{Path, PathBuf},
process::{self, Command, Stdio},
time::SystemTime,
};
use termion::{color, style};
use walkdir::WalkDir;
fn remove_all(path: &Path) -> Result<(), String> {
if path.is_dir() {
fs::remove_dir_all(path)
} else {
fs::remove_file(path)
}.map_err(|err| format!(
"failed to remove '{}': {}\n{:?}",
path.display(),
err,
err
))
}
fn create_dir(dir: &Path) -> Result<(), String> {
fs::create_dir(&dir).map_err(|err| format!(
"failed to create '{}': {}\n{:?}",
dir.display(),
err,
err
))
}
fn create_dir_clean(dir: &Path) -> Result<(), String> {
if dir.is_dir() {
remove_all(dir)?;
}
create_dir(dir)
}
fn modified(path: &Path) -> Result<SystemTime, String> {
let metadata = fs::metadata(path).map_err(|err| format!(
"failed to get metadata of '{}': {}\n{:#?}",
path.display(),
err,
err
))?;
metadata.modified().map_err(|err| format!(
"failed to get modified time of '{}': {}\n{:#?}",
path.display(),
err,
err
))
}
fn modified_dir(dir: &Path) -> Result<SystemTime, String> {
fn modified_dir_io(dir: &Path) -> io::Result<SystemTime> {
let mut newest = fs::metadata(dir)?.modified()?;
for entry_res in WalkDir::new(dir) {
let entry = entry_res?;
let modified = entry.metadata()?.modified()?;
if modified > newest {
newest = modified;
}
}
Ok(newest)
}
modified_dir_io(&dir).map_err(|err| format!(
"failed to get modified time of '{}': {}\n{:#?}",
dir.display(),
err,
err
))
}
fn rename(src: &Path, dst: &Path) -> Result<(), String> {
fs::rename(src, dst).map_err(|err| format!(
"failed to rename '{}' to '{}': {}\n{:?}",
src.display(),
dst.display(),
err,
err
))
}
fn run_command(mut command: process::Command) -> Result<(), String> {
let status = command.status().map_err(|err| format!(
"failed to run {:?}: {}\n{:#?}",
command,
err,
err
))?;
if ! status.success() {
return Err(format!(
"failed to run {:?}: exited with status {}",
command,
status
));
}
Ok(())
}
fn run_command_stdin(mut command: process::Command, stdin_data: &[u8]) -> Result<(), String> {
command.stdin(Stdio::piped());
let mut child = command.spawn().map_err(|err| format!(
"failed to spawn {:?}: {}\n{:#?}",
command,
err,
err
))?;
if let Some(ref mut stdin) = child.stdin {
stdin.write_all(stdin_data).map_err(|err| format!(
"failed to write stdin of {:?}: {}\n{:#?}",
command,
err,
err
))?;
} else {
return Err(format!(
"failed to find stdin of {:?}",
command
));
}
let status = child.wait().map_err(|err| format!(
"failed to run {:?}: {}\n{:#?}",
command,
err,
err
))?;
if ! status.success() {
return Err(format!(
"failed to run {:?}: exited with status {}",
command,
status
));
}
Ok(())
}
fn fetch(recipe_dir: &Path, source: &SourceRecipe) -> Result<PathBuf, String> {
let source_dir = recipe_dir.join("source");
match source {
SourceRecipe::Git { git, upstream, branch, rev } => {
//TODO: use libgit?
if ! source_dir.is_dir() {
// Create source.tmp
let source_dir_tmp = recipe_dir.join("source.tmp");
create_dir_clean(&source_dir_tmp)?;
// Clone the repository to source.tmp
let mut command = Command::new("git");
command.arg("clone").arg("--recursive").arg(&git);
if let Some(branch) = branch {
command.arg("--branch").arg(&branch);
}
command.arg(&source_dir_tmp);
run_command(command)?;
// Move source.tmp to source atomically
rename(&source_dir_tmp, &source_dir)?;
} else {
// Reset origin
let mut command = Command::new("git");
command.arg("-C").arg(&source_dir);
command.arg("remote").arg("set-url").arg("origin").arg(&git);
run_command(command)?;
// Fetch origin
let mut command = Command::new("git");
command.arg("-C").arg(&source_dir);
command.arg("fetch").arg("origin");
run_command(command)?;
}
if let Some(upstream) = upstream {
//TODO: set upstream URL
// git remote set-url upstream "$GIT_UPSTREAM" &> /dev/null ||
// git remote add upstream "$GIT_UPSTREAM"
// git fetch upstream
}
if let Some(rev) = rev {
// Check out specified revision
let mut command = Command::new("git");
command.arg("-C").arg(&source_dir);
command.arg("checkout").arg(&rev);
run_command(command)?;
} else {
//TODO: complicated stuff to check and reset branch to origin
// ORIGIN_BRANCH="$(git branch --remotes | grep '^ origin/HEAD -> ' | cut -d ' ' -f 5-)"
// if [ -n "$BRANCH" ]
// then
// ORIGIN_BRANCH="origin/$BRANCH"
// fi
//
// if [ "$(git rev-parse HEAD)" != "$(git rev-parse $ORIGIN_BRANCH)" ]
// then
// git checkout -B "$(echo "$ORIGIN_BRANCH" | cut -d / -f 2-)" "$ORIGIN_BRANCH"
// fi
}
// Sync submodules URL
let mut command = Command::new("git");
command.arg("-C").arg(&source_dir);
command.arg("submodule").arg("sync").arg("--recursive");
run_command(command)?;
// Update submodules
let mut command = Command::new("git");
command.arg("-C").arg(&source_dir);
command.arg("submodule").arg("update").arg("--init").arg("--recursive");
run_command(command)?;
},
SourceRecipe::Tar { tar, blake3, sha256, patches, script } => {
if ! source_dir.is_dir() {
// Download tar
//TODO: replace wget
let source_tar = recipe_dir.join("source.tar");
if ! source_tar.is_file() {
let source_tar_tmp = recipe_dir.join("source.tar.tmp");
let mut command = Command::new("wget");
command.arg(&tar);
command.arg("-O").arg(&source_tar_tmp);
run_command(command)?;
// Move source.tar.tmp to source.tar atomically
rename(&source_tar_tmp, &source_tar)?;
}
// Calculate blake3
let source_tar_blake3 = blake3_progress(&source_tar).map_err(|err| format!(
"failed to calculate blake3 of '{}': {}\n{:?}",
source_tar.display(),
err,
err
))?;
if let Some(blake3) = blake3 {
// Check if it matches recipe
if &source_tar_blake3 != blake3 {
return Err(format!(
"calculated blake3 '{}' does not match recipe blake3 '{}'",
source_tar_blake3,
blake3
));
}
} else {
//TODO: set blake3 hash on the recipe with something like "cook fix"
eprintln!(
"WARNING: set blake3 for '{}' to '{}'",
source_tar.display(),
source_tar_blake3
);
}
//TODO: if blake3 is set, remove sha256
if let Some(sha256) = sha256 {
// Calculate sha256
let source_tar_sha256 = sha256_progress(&source_tar).map_err(|err| format!(
"failed to calculate sha256 of '{}': {}\n{:?}",
source_tar.display(),
err,
err
))?;
// Check if it matches recipe
if &source_tar_sha256 != sha256 {
return Err(format!(
"calculated sha256 '{}' does not match recipe sha256 '{}'",
source_tar_sha256,
sha256
));
}
}
// Create source.tmp
let source_dir_tmp = recipe_dir.join("source.tmp");
create_dir_clean(&source_dir_tmp)?;
// Extract tar to source.tmp
//TODO: use tar crate (how to deal with compression?)
let mut command = Command::new("tar");
command.arg("--extract");
command.arg("--verbose");
command.arg("--file").arg(&source_tar);
command.arg("--directory").arg(&source_dir_tmp);
command.arg("--strip-components").arg("1");
run_command(command)?;
// Apply patches
for patch_name in patches {
let patch_file = recipe_dir.join(&patch_name);
if ! patch_file.is_file() {
return Err(format!(
"failed to find patch file '{}'",
patch_file.display()
));
}
let patch = fs::read_to_string(&patch_file).map_err(|err| format!(
"failed to read patch file '{}': {}\n{:#?}",
patch_file.display(),
err,
err
))?;
let mut command = Command::new("patch");
command.arg("--directory").arg(&source_dir_tmp);
command.arg("--strip=1");
run_command_stdin(command, patch.as_bytes())?;
}
// Run source script
if let Some(script) = script {
let mut command = Command::new("bash");
command.arg("-ex");
command.current_dir(&source_dir_tmp);
run_command_stdin(command, script.as_bytes())?;
}
// Move source.tmp to source atomically
rename(&source_dir_tmp, &source_dir)?;
}
}
}
Ok(source_dir)
}
fn build(recipe_dir: &Path, source_dir: &Path, build: &BuildRecipe) -> Result<PathBuf, String> {
let source_modified = modified_dir(&source_dir)?;
let sysroot_dir = recipe_dir.join("sysroot");
// Rebuild sysroot if source is newer
//TODO: rebuild on recipe changes
if sysroot_dir.is_dir() {
if modified_dir(&sysroot_dir)? < source_modified {
remove_all(&sysroot_dir)?;
}
}
if ! sysroot_dir.is_dir() {
// Create sysroot.tmp
let sysroot_dir_tmp = recipe_dir.join("sysroot.tmp");
create_dir_clean(&sysroot_dir_tmp)?;
// Make sure sysroot/include exists
create_dir(&sysroot_dir_tmp.join("include"))?;
// Make sure sysroot/lib exists
create_dir(&sysroot_dir_tmp.join("lib"))?;
for dependency in build.dependencies.iter() {
let public_path = "build/public.key";
//TODO: sanitize name
let archive_path = format!("recipes/{}/stage.pkgar", dependency);
pkgar::bin::extract(
public_path,
&archive_path,
sysroot_dir_tmp.to_str().unwrap()
).map_err(|err| format!(
"failed to install '{}' in '{}': {:?}",
archive_path,
sysroot_dir_tmp.display(),
err
))?;
}
// Move sysroot.tmp to sysroot atomically
rename(&sysroot_dir_tmp, &sysroot_dir)?;
}
let stage_dir = recipe_dir.join("stage");
// Rebuild stage if source is newer
//TODO: rebuild on recipe changes
if stage_dir.is_dir() {
if modified_dir(&stage_dir)? < source_modified {
remove_all(&stage_dir)?;
}
}
if ! stage_dir.is_dir() {
// Create stage.tmp
let stage_dir_tmp = recipe_dir.join("stage.tmp");
create_dir_clean(&stage_dir_tmp)?;
// Create build, if it does not exist
//TODO: flag for clean builds where build is wiped out
let build_dir = recipe_dir.join("build");
if ! build_dir.is_dir() {
create_dir_clean(&build_dir)?;
}
let pre_script = r#"# Common pre script
# Add cookbook bins to path
export PATH="${COOKBOOK_ROOT}/bin:${PATH}"
# This puts cargo build artifacts in the build directory
export CARGO_TARGET_DIR="${COOKBOOK_BUILD}/target"
# This adds the sysroot includes for most C compilation
#TODO: check paths for spaces!
export CFLAGS="-I${COOKBOOK_SYSROOT}/include"
export CPPFLAGS="-I${COOKBOOK_SYSROOT}/include"
# This adds the sysroot libraries and compiles binaries statically for most C compilation
#TODO: check paths for spaces!
export LDFLAGS="-L${COOKBOOK_SYSROOT}/lib --static"
# These ensure that pkg-config gets the right flags from the sysroot
export PKG_CONFIG_ALLOW_CROSS=1
export PKG_CONFIG_PATH=
export PKG_CONFIG_LIBDIR="${COOKBOOK_SYSROOT}/lib/pkgconfig"
export PKG_CONFIG_SYSROOT_DIR="${COOKBOOK_SYSROOT}"
# cargo template
COOKBOOK_CARGO="${COOKBOOK_REDOXER}"
COOKBOOK_CARGO_FLAGS=(
--path "${COOKBOOK_SOURCE}"
--root "${COOKBOOK_STAGE}"
)
function cookbook_cargo {
"${COOKBOOK_CARGO}" install "${COOKBOOK_CARGO_FLAGS[@]}"
}
# configure template
COOKBOOK_CONFIGURE="${COOKBOOK_SOURCE}/configure"
COOKBOOK_CONFIGURE_FLAGS=(
--host="${TARGET}"
--prefix=""
--disable-shared
--enable-static
)
COOKBOOK_MAKE="make"
function cookbook_configure {
"${COOKBOOK_CONFIGURE}" "${COOKBOOK_CONFIGURE_FLAGS[@]}"
"${COOKBOOK_MAKE}" -j "$(nproc)"
"${COOKBOOK_MAKE}" install DESTDIR="${COOKBOOK_STAGE}"
}
"#;
let post_script = r#"# Common post script
# Strip binaries
if [ -d "${COOKBOOK_STAGE}/bin" ]
then
find "${COOKBOOK_STAGE}/bin" -type f -exec "${TARGET}-strip" -v {} ';'
fi
# Remove libtool files
if [ -d "${COOKBOOK_STAGE}/lib" ]
then
find "${COOKBOOK_STAGE}/lib" -type f -name '*.la' -exec rm -fv {} ';'
fi
"#;
//TODO: better integration with redoxer (library instead of binary)
//TODO: configurable target
//TODO: Add more configurability, convert scripts to Rust?
let script = match &build.kind {
BuildKind::Cargo => "cookbook_cargo",
BuildKind::Configure => "cookbook_configure",
BuildKind::Custom { script } => script
};
let command = {
//TODO: remove unwraps
let cookbook_build = build_dir.canonicalize().unwrap();
let cookbook_recipe = recipe_dir.canonicalize().unwrap();
let cookbook_redoxer = Path::new("target/release/cookbook_redoxer").canonicalize().unwrap();
let cookbook_root = Path::new(".").canonicalize().unwrap();
let cookbook_stage = stage_dir_tmp.canonicalize().unwrap();
let cookbook_source = source_dir.canonicalize().unwrap();
let cookbook_sysroot = sysroot_dir.canonicalize().unwrap();
let mut command = Command::new(&cookbook_redoxer);
command.arg("env");
command.arg("bash").arg("-ex");
command.current_dir(&cookbook_build);
command.env("COOKBOOK_BUILD", &cookbook_build);
command.env("COOKBOOK_RECIPE", &cookbook_recipe);
command.env("COOKBOOK_REDOXER", &cookbook_redoxer);
command.env("COOKBOOK_ROOT", &cookbook_root);
command.env("COOKBOOK_STAGE", &cookbook_stage);
command.env("COOKBOOK_SOURCE", &cookbook_source);
command.env("COOKBOOK_SYSROOT", &cookbook_sysroot);
command
};
let full_script = format!("{}\n{}\n{}", pre_script, script, post_script);
run_command_stdin(command, full_script.as_bytes())?;
// Move stage.tmp to stage atomically
rename(&stage_dir_tmp, &stage_dir)?;
}
Ok(stage_dir)
}
fn package(recipe_dir: &Path, stage_dir: &Path, package: &PackageRecipe) -> Result<PathBuf, String> {
//TODO: metadata like dependencies, name, and version
let secret_path = "build/secret.key";
let public_path = "build/public.key";
if ! Path::new(secret_path).is_file() || ! Path::new(public_path).is_file() {
if ! Path::new("build").is_dir() {
create_dir(Path::new("build"))?;
}
pkgar::bin::keygen(secret_path, public_path).map_err(|err| format!(
"failed to generate pkgar keys: {:?}",
err
))?;
}
let package_file = recipe_dir.join("stage.pkgar");
// Rebuild package if stage is newer
//TODO: rebuild on recipe changes
if package_file.is_file() {
let stage_modified = modified_dir(&stage_dir)?;
if modified(&package_file)? < stage_modified {
remove_all(&package_file)?;
}
}
if ! package_file.is_file() {
pkgar::bin::create(
secret_path,
package_file.to_str().unwrap(),
stage_dir.to_str().unwrap()
).map_err(|err| format!(
"failed to create pkgar archive: {:?}",
err
))?;
}
Ok(package_file)
}
fn cook(recipe_dir: &Path, recipe: &Recipe) -> Result<(), String> {
let source_dir = fetch(&recipe_dir, &recipe.source).map_err(|err| format!(
"failed to fetch: {}",
err
))?;
let stage_dir = build(&recipe_dir, &source_dir, &recipe.build).map_err(|err| format!(
"failed to build: {}",
err
))?;
let package_file = package(&recipe_dir, &stage_dir, &recipe.package).map_err(|err| format!(
"failed to package: {}",
err
))?;
Ok(())
}
pub struct CookRecipe {
name: String,
dir: PathBuf,
recipe: Recipe,
}
impl CookRecipe {
pub fn new(name: String) -> Result<Self, String> {
//TODO: sanitize recipe name?
let dir = Path::new("recipes").join(&name);
if ! dir.is_dir() {
return Err(format!(
"failed to find recipe directory '{}'",
dir.display()
));
}
let file = dir.join("recipe.toml");
if ! file.is_file() {
return Err(format!(
"failed to find recipe file '{}'",
file.display()
));
}
let toml = fs::read_to_string(&file).map_err(|err| format!(
"failed to read recipe file '{}': {}\n{:#?}",
file.display(),
err,
err
))?;
let recipe: Recipe = toml::from_str(&toml).map_err(|err| format!(
"failed to parse recipe file '{}': {}\n{:#?}",
file.display(),
err,
err
))?;
Ok(Self {
name,
dir,
recipe
})
}
//TODO: make this more efficient, smarter, and not return duplicates
pub fn new_recursive(names: &[String], recursion: usize) -> Result<Vec<Self>, String> {
if recursion == 0 {
return Err(format!(
"recursion limit while processing build dependencies: {:#?}",
names
));
}
let mut recipes = Vec::new();
for name in names {
let recipe = Self::new(name.clone())?;
let dependencies = Self::new_recursive(
&recipe.recipe.build.dependencies,
recursion - 1
).map_err(|err| format!(
"{}: failed on loading build dependencies:\n{}",
name,
err
))?;
for dependency in dependencies {
recipes.push(dependency);
}
recipes.push(recipe);
}
Ok(recipes)
}
}
fn main() {
let mut matching = true;
let mut dry_run = false;
let mut quiet = false;
let mut recipe_names = Vec::new();
for arg in env::args().skip(1) {
match arg.as_str() {
"--" if matching => matching = false,
"-d" | "--dry-run" if matching => dry_run = true,
"-q" | "--quiet" if matching => quiet = true,
_ => recipe_names.push(arg),
}
}
let recipes = match CookRecipe::new_recursive(&recipe_names, 16) {
Ok(ok) => ok,
Err(err) => {
eprintln!(
"{}{}cook - error:{}{} {}",
style::Bold,
color::Fg(color::AnsiValue(196)),
color::Fg(color::Reset),
style::Reset,
err,
);
process::exit(1);
}
};
for recipe in recipes {
if ! quiet {
eprintln!(
"{}{}cook - {}{}{}",
style::Bold,
color::Fg(color::AnsiValue(215)),
recipe.name,
color::Fg(color::Reset),
style::Reset,
);
}
let res = if dry_run {
if ! quiet {
eprintln!("DRY RUN: {:#?}", recipe.recipe);
}
Ok(())
} else {
cook(&recipe.dir, &recipe.recipe)
};
match res {
Ok(()) => {
if ! quiet {
eprintln!(
"{}{}cook - {} - successful{}{}",
style::Bold,
color::Fg(color::AnsiValue(46)),
recipe.name,
color::Fg(color::Reset),
style::Reset,
);
}
},
Err(err) => {
eprintln!(
"{}{}cook - {} - error:{}{} {}",
style::Bold,
color::Fg(color::AnsiValue(196)),
recipe.name,
color::Fg(color::Reset),
style::Reset,
err,
);
process::exit(1);
}
}
}
}

View File

@ -0,0 +1,10 @@
use std::env;
fn main() {
let mut args: Vec<String> = env::args().collect();
// Ensure all flags go to cargo
if args.len() >= 2 {
args.insert(2, "--".to_string());
}
redoxer::main(&args);
}

46
src/blake3.rs Normal file
View File

@ -0,0 +1,46 @@
use blake3::Hasher;
use std::{
fs,
io::{Read, Result},
path::Path,
time::Duration,
};
use crate::progress_bar::{ProgressBar, ProgressBarRead};
pub fn blake3<R: Read>(r: &mut R) -> Result<String> {
let mut hasher = Hasher::new();
let mut data = vec![0; 4 * 1024 * 1024];
loop {
let count = r.read(&mut data)?;
if count == 0 {
break;
}
hasher.update(&data[..count]);
}
let hash = hasher.finalize();
Ok(format!("{}", hash.to_hex()))
}
pub fn blake3_progress<P: AsRef<Path>>(path: P) -> Result<String> {
let len = fs::metadata(&path)?.len();
let mut f = fs::File::open(&path)?;
let mut pb = ProgressBar::new(len);
pb.message("blake3: ");
pb.set_max_refresh_rate(Some(Duration::new(1, 0)));
pb.set_units(pbr::Units::Bytes);
let res = {
let mut pbr = ProgressBarRead::new(&mut pb, &mut f);
blake3(&mut pbr)
};
pb.finish_println("");
res
}

5
src/lib.rs Normal file
View File

@ -0,0 +1,5 @@
pub mod blake3;
pub mod recipe;
pub mod sha256;
mod progress_bar;

51
src/progress_bar.rs Normal file
View File

@ -0,0 +1,51 @@
pub use pbr::ProgressBar;
use std::io::{Read, Write, Result};
pub struct ProgressBarRead<'p, 'r, P: Write + 'p, R: Read + 'r> {
pb: &'p mut ProgressBar<P>,
r: &'r mut R,
}
impl<'p, 'r, P: Write, R: Read> ProgressBarRead<'p, 'r, P, R> {
pub fn new(pb: &'p mut ProgressBar<P>, r: &'r mut R) -> ProgressBarRead<'p, 'r, P, R> {
ProgressBarRead {
pb: pb,
r: r
}
}
}
impl<'p, 'r, P: Write, R: Read> Read for ProgressBarRead<'p, 'r, P, R> {
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
let count = self.r.read(buf)?;
self.pb.add(count as u64);
Ok(count)
}
}
pub struct ProgressBarWrite<'p, 'w, P: Write + 'p, W: Write + 'w> {
pb: &'p mut ProgressBar<P>,
w: &'w mut W,
}
impl<'p, 'w, P: Write, W: Write> ProgressBarWrite<'p, 'w, P, W> {
pub fn new(pb: &'p mut ProgressBar<P>, w: &'w mut W) -> ProgressBarWrite<'p, 'w, P, W> {
ProgressBarWrite {
pb: pb,
w: w
}
}
}
impl<'p, 'w, P: Write, W: Write> Write for ProgressBarWrite<'p, 'w, P, W> {
fn write(&mut self, buf: &[u8]) -> Result<usize> {
let count = self.w.write(buf)?;
self.pb.add(count as u64);
Ok(count)
}
fn flush(&mut self) -> Result<()> {
self.w.flush()
}
}

147
src/recipe.rs Normal file
View File

@ -0,0 +1,147 @@
use serde::{Deserialize, Serialize};
/// Specifies how to download the source for a recipe
#[derive(Debug, Deserialize, PartialEq, Serialize)]
#[serde(untagged)]
pub enum SourceRecipe {
/// A git repository source
Git {
/// The URL for the git repository, such as https://gitlab.redox-os.org/redox-os/ion.git
git: String,
/// The URL for an upstream repository
upstream: Option<String>,
/// The optional branch of the git repository to track, such as master. Please specify to
/// make updates to the rev easier
branch: Option<String>,
/// The optional revision of the git repository to use for builds. Please specify for
/// reproducible builds
rev: Option<String>,
},
/// A tar file source
Tar {
/// The URL of a tar source
tar: String,
/// The optional blake3 sum of the tar file. Please specify this to make reproducible
/// builds more reliable
blake3: Option<String>,
/// The optional sha256 sum of the tar file. This is a slower alternative to a blake3 sum
sha256: Option<String>,
/// A list of patch files to apply to the source
#[serde(default)]
patches: Vec<String>,
/// Optional script to run to prepare the source, such as ./autogen.sh
script: Option<String>,
},
}
/// Specifies how to build a recipe
#[derive(Debug, Deserialize, PartialEq, Serialize)]
#[serde(tag = "template")]
pub enum BuildKind {
/// Will build and install using cargo
#[serde(rename = "cargo")]
Cargo,
/// Will build and install using configure and make
#[serde(rename = "configure")]
Configure,
/// Will build and install using custom commands
#[serde(rename = "custom")]
Custom {
script: String,
},
}
#[derive(Debug, Deserialize, PartialEq, Serialize)]
pub struct BuildRecipe {
#[serde(flatten)]
pub kind: BuildKind,
#[serde(default)]
pub dependencies: Vec<String>,
}
#[derive(Debug, Default, Deserialize, PartialEq, Serialize)]
pub struct PackageRecipe {
#[serde(default)]
pub dependencies: Vec<String>,
}
/// Everything required to build a Redox package
#[derive(Debug, Deserialize, PartialEq, Serialize)]
pub struct Recipe {
/// Specifies how to donload the source for this recipe
pub source: SourceRecipe,
/// Specifies how to build this recipe
pub build: BuildRecipe,
/// Specifies how to package this recipe
#[serde(default)]
pub package: PackageRecipe,
}
#[cfg(test)]
mod tests {
#[test]
fn git_cargo_recipe() {
use crate::recipe::{Recipe, SourceRecipe, BuildKind, BuildRecipe, PackageRecipe};
let recipe: Recipe = toml::from_str(r#"
[source]
git = "https://gitlab.redox-os.org/redox-os/acid.git"
branch = "master"
rev = "06344744d3d55a5ac9a62a6059cb363d40699bbc"
[build]
template = "cargo"
"#).unwrap();
assert_eq!(recipe, Recipe {
source: SourceRecipe::Git {
git: "https://gitlab.redox-os.org/redox-os/acid.git".to_string(),
upstream: None,
branch: Some("master".to_string()),
rev: Some("06344744d3d55a5ac9a62a6059cb363d40699bbc".to_string()),
},
build: BuildRecipe {
kind: BuildKind::Cargo,
dependencies: Vec::new(),
},
package: PackageRecipe {
dependencies: Vec::new(),
},
});
}
#[test]
fn tar_custom_recipe() {
use crate::recipe::{Recipe, SourceRecipe, BuildKind, BuildRecipe, PackageRecipe};
let recipe: Recipe = toml::from_str(r#"
[source]
tar = "http://downloads.xiph.org/releases/ogg/libogg-1.3.3.tar.xz"
sha256 = "4f3fc6178a533d392064f14776b23c397ed4b9f48f5de297aba73b643f955c08"
[build]
template = "custom"
script = "make"
"#).unwrap();
assert_eq!(recipe, Recipe {
source: SourceRecipe::Tar {
tar: "http://downloads.xiph.org/releases/ogg/libogg-1.3.3.tar.xz".to_string(),
blake3: None,
sha256: Some("4f3fc6178a533d392064f14776b23c397ed4b9f48f5de297aba73b643f955c08".to_string()),
patches: Vec::new(),
script: None,
},
build: BuildRecipe {
kind: BuildKind::Custom {
script: "make".to_string()
},
dependencies: Vec::new(),
},
package: PackageRecipe {
dependencies: Vec::new(),
},
});
}
}

45
src/sha256.rs Normal file
View File

@ -0,0 +1,45 @@
use std::{
fs,
io::{Read, Result},
path::Path,
time::Duration,
};
use sha2::{Digest, Sha256};
use crate::progress_bar::{ProgressBar, ProgressBarRead};
pub fn sha256<R: Read>(r: &mut R) -> Result<String> {
let mut hasher = Sha256::default();
let mut data = vec![0; 4 * 1024 * 1024];
loop {
let count = r.read(&mut data)?;
if count == 0 {
break;
}
hasher.input(&data[..count]);
}
Ok(format!("{:x}", hasher.result()))
}
pub fn sha256_progress<P: AsRef<Path>>(path: P) -> Result<String> {
let len = fs::metadata(&path)?.len();
let mut f = fs::File::open(&path)?;
let mut pb = ProgressBar::new(len);
pb.message("sha256: ");
pb.set_max_refresh_rate(Some(Duration::new(1, 0)));
pb.set_units(pbr::Units::Bytes);
let res = {
let mut pbr = ProgressBarRead::new(&mut pb, &mut f);
sha256(&mut pbr)
};
pb.finish_println("");
res
}