wharfie: ./branches/ticket#1/wharfie/examples/common/files/wireless.conf
Bash
bash
(Bash)
brcmfmac
brcmutil
Last updated: 2017-10-22
wharfie: ./branches/ticket#1/wharfie/wharfie.py
Bash
bash
(Bash)
#!/usr/bin/python
#
# The file format and the principle are lent from Docker.
# It's just all a bit simpler, as we only create images
# and have no infrastructure to provide prebuilt images.
#
# What is more complex for embedded systems is the legal
# part. When s.o. is using docker to build a web service,
# he doesn't include the used open source software into
# a product, which he is commercially using, but he uses
# it himself to provide a web service to his customers.
#
# With most embedded systems, which Wharfie is focusing
# on, this is different. People are usually building
# products, including the open source software. So they
# need to respect the licenses of the software, which
# they are including.
#
# For this reason Wharfie only supports debian based
# systems, as the debian projects takes much care about
# respecting open source licenses, and makes it easy
# to get a list of all licenses used in a system.
#
# It makes it also easy to get the source packets, fitting
# to the installed binary version. Therefore, one can
# easily provide all sources of the open source software,
# included in his image to his customers.
#
# With this background, the supported commands of Wharfie
# are differing slightly from its big brother Docker.
#
# Commands:
# - FROM: Supports only a fix number of build rules.
# e.g.: debian_armhf_sid, debian_etch, ...
#
# - RUN: Execute a command inside the image
#
# - RUN HOST: Execute a command on the host system,
# But inside of the image root.
#
# - ADD: Add an archive or file to the root filesystem.
#
# - TO: name of the final archive
#
# - SOURCE: name of an archive, where the currently installed
# source packages are written to.
#
# - LICENSE: Extract a list of all licenses, of all currently
# installed packages.
#
# - TOOLCHAIN: Build a cross-toolchain for the currently
# installed root filesystem.
#
# Note: Technically everything can be done, using RUN
# and RUN HOST. Other commands, like ADD or TO
# are only supported for more convenience.
# So for example if you want to combine the
# resulting image with a special bootloader or
# something, it can be flexibly done with RUN HOST.
import os
import sys
import re
import binascii
import argparse
regexCommand = '^[ \t]*(RUN HOST|RUN|FROM|TOOLCHAIN|TO|ADD|SOURCE|LICENSE|ENV)([^\n]*)';
g_depend = '';
g_makeTargets = list();
g_environment = list();
g_archiveName = 'rootfs.tar';
g_finalTarget = list();
# We use templates, which are checking their execution context,
# to be sure, that target commands are really only executed
# in the change root of the image.
g_templateTrgCmd = "#!/bin/bash\n[ -f ../Wharfile ] && exit 2;\n%s\n"
g_templateHostCmd = "#!/bin/bash\n[ ! -f ../Wharfile ] && exit 2;\n%s"
#
# Read a Wharfile
#
def read_wharfile(filename):
global g_archiveName
content = open(filename, 'r').read()
content = content.replace('\\\n', '')
bld = ''
g_allDepends = '';
g_depend = '';
for cmd in re.findall(regexCommand, content, flags=re.MULTILINE):
# calculate current build target and dependency names
dep = list();
if bld != '':
dep.append(bld);
if g_depend != '':
dep.append(g_depend);
if cmd[0] not in ('FROM', 'TO', 'ENV'):
g_allDepends += str(cmd);
if g_allDepends != '':
bld = format(0xFFFFFFFF & binascii.crc32(g_allDepends), '02X') + ".piling.tar";
# FROM
if cmd[0] == 'FROM':
g_depend = cmd[1] + ".tar";
# ENV
elif cmd[0] == 'ENV':
g_environment.append(cmd[1]);
# RUN
elif cmd[0] == 'RUN':
makeTarget = {
'comment' : "%s %s" % (cmd[0], cmd[1]),
'name': bld,
'dep': dep,
'trgcmd': cmd[1]
};
g_makeTargets.append(makeTarget);
g_depend = '';
# RUN HOST
elif cmd[0] == 'RUN HOST':
g_allDepends += str(cmd);
makeTarget = {
'comment' : "%s %s" % (cmd[0], cmd[1]),
'name': bld,
'dep': dep,
'hostcmd': cmd[1]
};
g_makeTargets.append(makeTarget);
g_depend = '';
# ADD (single file)
elif cmd[0] == 'ADD':
g_allDepends += str(cmd);
src,dst = cmd[1].lstrip().split(" ")
dep.append(src)
myHostCmd = 'dest="$(pwd)"; cd ../; mkdir -p $(dirname "${dest}/%s"); cp -R --preserve=mode %s "${dest}/%s"' % (dst, src, dst)
makeTarget = {
'comment' : "%s %s" % (cmd[0], cmd[1]),
'name': bld,
'dep': dep,
'hostcmd': myHostCmd
};
g_makeTargets.append(makeTarget);
g_depend = '';
# TO
elif cmd[0] == 'TO':
g_archiveName = cmd[1].lstrip();
# SOURCE
elif cmd[0] == 'SOURCE':
myTrgCmd = 'mkdir /sources; cd /sources; [ ! -f .pkg.list ] && dpkg-query -f \'${binary:Package}\\n\' -W > .pkg.list; apt-get install -y dpkg-dev; cat .pkg.list | xargs -n 1 apt-get source'
myHostCmd = 'tar -cf ../' + cmd[1].lstrip() + ' sources;'
makeTarget = {
'comment' : "%s %s" % (cmd[0], cmd[1]),
'name': bld,
'dep': dep,
'trgcmd': myTrgCmd,
'hostcmd': myHostCmd,
'temporary': True
};
g_makeTargets.append(makeTarget);
g_depend = '';
# LICENSE
elif cmd[0] == 'LICENSE':
myTrgCmd = 'mkdir /licenses; for i in /usr/share/doc/*/; do [ -f $i/copyright ] && cp $i/copyright licenses/$(basename $i).txt || echo $(basename $i) >> licenses/___MISSING___.txt; done'
myHostCmd = 'tar -cf ../' + cmd[1].lstrip() + ' licenses;'
makeTarget = {
'comment' : "%s %s" % (cmd[0], cmd[1]),
'name': bld,
'dep': dep,
'trgcmd': myTrgCmd,
'hostcmd': myHostCmd,
'temporary': True
};
g_makeTargets.append(makeTarget);
g_depend = '';
# TOOLCHAIN
elif cmd[0] == 'TOOLCHAIN':
myTrgCmd = 'apt-get install -y libc6-dev; [ -d ./usr/lib/arm-linux-gnueabi*/ ] && (cd ./usr/lib/arm-linux-gnueabi*/; ln -s crt1.o crt0.o)'
myHostCmd = 'rm .hst.sh; mkdir target; mv ./* target; mkdir host; (cd host; tar -xf ../../debian_toolchain.tar); cp ../debian_toolchain_env.sh env.sh; tar -cf ../' + cmd[1].lstrip() + ' .;'
dep.append('debian_toolchain.tar')
dep.append('debian_toolchain_env.sh')
makeTarget = {
'comment' : "%s %s" % (cmd[0], cmd[1]),
'name': bld,
'dep': dep,
'trgcmd': myTrgCmd,
'hostcmd': myHostCmd,
'temporary': True
};
g_makeTargets.append(makeTarget);
g_depend = '';
else:
print ('unknown command: ' + cmd[0] + ' ' + cmd[1]);
g_finalTarget.append(bld);
#
# Write a Makefile
#
def write_makefile(filename, dry_run, installpath='.'):
f = open(filename, 'w');
# write header
f.write("ifneq (VERBOSE,y)\n")
f.write("Q=@\n")
f.write("endif\n")
f.write("\n")
f.write("OUTPUT_FILE=%s\n" % g_archiveName)
f.write("%s: %s\n" % (g_archiveName, "".join(g_finalTarget)));
f.write("\tcp $< $@\n");
f.write("\n");
# write all environment variables
for env in g_environment:
key,val = env.lstrip().split(" ")
f.write("export %s=%s\n" % (key, val));
# write all targets
for target in g_makeTargets:
if 'comment' in target:
f.write("# %s\n" % target['comment']);
f.write("%s: %s\n" % (target['name'], " ".join(target['dep'])));
f.write("\t${Q}-mkdir $$(basename $@ .tar)\n");
if 'trgcmd' in target:
cmd = g_templateTrgCmd % (target['trgcmd'].replace('$', '\\$$').replace('"', '\\"'));
f.write("\t${Q}echo '******************************'\n");
f.write("\t${Q}echo '%s'\n" % target['comment']);
f.write("\t${Q}echo '******************************'\n");
f.write("\t${Q}(echo -e \"%s\") | tee ./$$(basename $@ .tar)/.trg.sh\n" % cmd.replace('\\n', '\\\\\\n').replace('\n', '\\n').replace('!', '"\'!\'"'));
f.write("\t${Q}chmod a+x ./$$(basename $@ .tar)/.trg.sh\n");
if 'hostcmd' in target:
cmd = g_templateHostCmd % (target['hostcmd'].replace('$', '\\$$').replace('"', '\\"'));
f.write("\t${Q}echo '******************************'\n");
f.write("\t${Q}echo '%s'\n" % target['comment']);
f.write("\t${Q}echo '******************************'\n");
f.write("\t${Q}(echo -e \"%s\") | tee ./$$(basename $@ .tar)/.hst.sh\n" % cmd.replace('\\n', '\\\\\\\\n').replace('\n', '\\n').replace('!', '"\'!\'"'));
f.write("\t${Q}chmod a+x ./$$(basename $@ .tar)/.hst.sh\n");
# start command here ...
f.write("\t${Q}${SUDO} bash -c \"");
f.write("cd $$(basename $@ .tar); tar -xf ../$<; ");
if not dry_run:
f.write("[ -f .trg.sh ] && chroot . ./.trg.sh; rm -f ./.trg.sh; ");
f.write("[ -f .hst.sh ] && ./.hst.sh; rm -f ./.hst.sh; ");
if not 'temporary' in target or not target['temporary']:
f.write("tar -cf '../$@' .;");
f.write("\"\n");
# ... end command
if 'temporary' in target and target['temporary']:
f.write("\t${Q}cp $< $@\n");
f.write("\t${Q}-${SUDO} rm -Rf ./$$(basename $@ .tar)\n");
f.write("\n");
# write footer
f.write("include %s/wharfie.mk\n" % installpath);
if installpath != '.':
f.write("-include wharfie.mk\n");
f.write("\n");
#
# Main
#
def main():
parser = argparse.ArgumentParser()
parser.add_argument('--clean', action='store_true', help="Clear intermediate files" )
parser.add_argument('--info', action='store_true', help="Print info about already generated image" )
parser.add_argument('--gen-only', action='store_true', help="Generate makefile only, but don't build it" )
parser.add_argument('--dry-run', action='store_true', help="Generate makefile with disabled run actions and don't build it" )
parser.add_argument('wharfile', default='Wharfile', nargs='?', help="Filename of a 'Wharfile'. By default ./Wharfile is used." )
args = parser.parse_args()
# generate makefile
if os.path.isfile(args.wharfile):
read_wharfile(args.wharfile);
else:
print("error: Wharfile '%s' not found." % args.wharfile)
exit(1)
if os.path.isfile(os.path.abspath(os.path.dirname(sys.argv[0])) + "/wharfie.mk"):
write_makefile('Makefile', args.dry_run, os.path.dirname(sys.argv[0]));
else:
write_makefile('Makefile', args.dry_run, os.path.abspath(os.path.dirname(sys.argv[0])) + "/../share/wharfie");
# call make
if args.clean:
os.system("make clean")
elif args.info:
os.system("make info")
elif not args.gen_only and not args.dry_run:
os.system("make");
if __name__ == "__main__":
main()
Last updated: 2017-11-02
wharfie: ./branches/ticket#1/wharfie/wharfie.mk
Bash
bash
(Bash)
SHELL=/bin/bash
PATH := $(PATH):/sbin:/usr/sbin
SUDO=$(shell PATH=${PATH}:/sbin:/usr/sbin which sudo)
FAKEROOT=$(shell PATH=${PATH}:/sbin:/usr/sbin which fakeroot)
FAKECHROOT=$(shell PATH=${PATH}:/sbin:/usr/sbin which fakechroot)
DBOOTSTRAP=$(shell PATH=${PATH}:/sbin:/usr/sbin which qemu-debootstrap)
DBOOTSTRAP2=$(shell PATH=${PATH}:/sbin:/usr/sbin which debootstrap)
PACKAGES=locales systemd
MAKEFILE_PATH := $(abspath $(lastword $(MAKEFILE_LIST)))
CWD := $(dir $(MAKEFILE_PATH))
# extend path to sbin binaries
export PATH := /usr/sbin:${PATH}
ifeq (${SUDO},)
$(error sudo not found. On debian, you may install the package sudo first)
endif
#ifeq (${FAKEROOT},)
#$(error fakeroot not found. On debian, you may install the package fakeroot first)
#endif
#ifeq (${FAKECHROOT},)
#$(error fakechroot not found. On debian, you may install the package fakechroot first)
#endif
ifeq (${DBOOTSTRAP},)
$(error qemu-debootstrap not found. On debian, you may install the package qemu-user-static first)
endif
ifeq (${DBOOTSTRAP2},)
$(error debootstrap not found. On debian, you may install the package debootstrap first)
endif
.PHONY: test
test:
echo ${FAKEROOT}
#
# Debian / ARM Hardfloat
#
.PHONY: debian_armhf_%.tar
debian_armhf_%.tar:
-mkdir ./$$(basename $@ .tar)
${SUDO} ${DBOOTSTRAP} --arch=armhf --variant=minbase --include="${PACKAGES}" $* ./$$(basename $@ .tar) http://ftp.debian.org/debian/
(echo "deb http://ftp.debian.org/debian $* main"; \
echo "deb-src http://ftp.debian.org/debian $* main") | ${SUDO} tee ./$$(basename $@ .tar)/etc/apt/sources.list
cd $$(basename $@ .tar); ${SUDO} tar -cf "../$@" .
${SUDO} rm -R ./$$(basename $@ .tar)
echo DEBIAN_VERSION=$* > debian_version.mk
echo GCC_POSTFIX=-arm-none-eabi >> debian_version.mk
echo LIBC_POSTFIX=-armhf-cross >> debian_version.mk
#
# Debian / ARM EABI
#
.PHONY: debian_armel_%.tar
debian_armel_%.tar:
-mkdir ./$$(basename $@ .tar)
${SUDO} ${DBOOTSTRAP} --arch=armel --variant=minbase --include="${PACKAGES}" $* ./$$(basename $@ .tar) http://ftp.debian.org/debian/
(echo "deb http://ftp.debian.org/debian $* main"; \
echo "deb-src http://ftp.debian.org/debian $* main") | ${SUDO} tee ./$$(basename $@ .tar)/etc/apt/sources.list
cd $$(basename $@ .tar); ${SUDO} tar -cf "../$@" .
${SUDO} rm -R ./$$(basename $@ .tar)
echo DEBIAN_VERSION=$* > debian_version.mk
echo GCC_POSTFIX=-arm-none-eabi >> debian_version.mk
echo LIBC_POSTFIX=-armel-cross >> debian_version.mk
#
# Debian x86/amd64...
# extended for debian_{amd64,i386}_{deb_version}.tar
# or old format "debian_{deb_version}.tar"
.PHONY: debian_%.tar
debian_%.tar:
$(eval ARCH:=$(if $(word 3,$(subst _, ,$@)),$(word 2,$(subst _, ,$@)),"i386"))
$(eval VERSION:=$(if $(word 3,$(subst _, ,$@)),$(basename $(word 3,$(subst _, ,$@))),$(basename $(word 2,$(subst _, ,$@)))))
-mkdir ./$$(basename $@ .tar)
${SUDO} ${DBOOTSTRAP} --arch=${ARCH} --variant=minbase --include="${PACKAGES}" ${VERSION} ./$$(basename $@ .tar) http://ftp.debian.org/debian/
(echo "deb http://ftp.debian.org/debian ${VERSION} main"; \
echo "deb-src http://ftp.debian.org/debian ${VERSION} main") | ${SUDO} tee ./$$(basename $@ .tar)/etc/apt/sources.list
cd $$(basename $@ .tar); ${SUDO} tar -cf "../$@" .
${SUDO} rm -R ./$$(basename $@ .tar)
echo DEBIAN_VERSION=${VERSION} > debian_version.mk
echo GCC_POSTFIX= >> debian_version.mk
echo LIBC_POSTFIX= >> debian_version.mk
-include debian_version.mk
#
# Debian Cross-Toolchain
#
debian_toolchain.tar:
-mkdir ./$$(basename $@ .tar)
${SUDO} ${DBOOTSTRAP} --arch=i386 --variant=minbase --include="gcc${GCC_POSTFIX} libstdc++-6-dev${LIBC_POSTFIX} libc6-dev${LIBC_POSTFIX}" ${DEBIAN_VERSION} ./$$(basename $@ .tar) http://ftp.debian.org/debian/
cd $$(basename $@ .tar); ${SUDO} tar -cf "../$@" .
${SUDO} rm -R ./$$(basename $@ .tar)
#
# Export environment shell script for the toolchain
#
define ENV_SH
TC_PATH=$$(dirname $$_)
SYSROOT=$${TC_PATH}/target
INCLUDEDIR=$${TC_PATH}/host/usr/arm-linux-gnueabihf/include/
LIBRARYDIR=$${TC_PATH}/target/usr/lib/arm-linux-gnueabihf/
COMPILE_PREFIX=$${TC_PATH}/host/usr/bin/arm-none-eabi-
PLUGINDIR=$$(dirname $$(readlink -f $${TC_PATH}/host/usr/lib/gcc/arm-none-eabi/*/liblto_plugin.so))
HOSTLIBDIR=$${TC_PATH}/host/usr/lib/i386-linux-gnu/:$${TC_PATH}/host/usr/lib/:$${TC_PATH}/host/lib
LD_LIBRARY_PATH=$${HOSTLIBDIR}
CC=$${COMPILE_PREFIX}gcc
CXX=$${COMPILE_PREFIX}cpp
LD=$${COMPILE_PREFIX}ld
AS=$${COMPILE_PREFIX}as
AR=$${COMPILE_PREFIX}ar
NM=$${COMPILE_PREFIX}nm
GCOV=$${COMPILE_PREFIX}gcov
OBJDUMP=$${COMPILE_PREFIX}objdump
CFLAGS=
LDFLAGS=
# common C/LD Flags
CFLAGS="$${CFLAGS} --sysroot=$${SYSROOT}"
CFLAGS="$${CFLAGS} -B$${PLUGINDIR} -mfloat-abi=hard"
LDFLAGS="$${CFLAGS}"
# CFLAGS
CFLAGS="$${CFLAGS} --sysroot=$${SYSROOT}"
CFLAGS="-I$${INCLUDEDIR}"
# LDFLAGS
LDFALGS="-L$${LIBRARYDIR}"
LDFLAGS="$${LDFLAGS} -L$${LIBRARYDIR}"
LDFLAGS="$${LDFLAGS} -B$${LIBRARYDIR}"
LDFLAGS="$${LDFLAGS} -lc"
export CC
export CXX
export LD
export AS
export AR
export NM
export GCOV
export OBJDUMP
export CFLAGS
export LDFLAGS
export LD_LIBRARY_PATH
endef
export ENV_SH
debian_toolchain_env.sh:
@echo "$${ENV_SH}" > $@
# output some info about the locally generated filesystem
info:
@[ -f ${OUTPUT_FILE} ] || (echo "The image is not build, yet."; false)
@targethostname="$$(tar -O -xf ${OUTPUT_FILE} ./etc/hostname)"; \
printf "Hostname: %s\n" $${targethostname}; \
printf "IP: %s (if target is running)\n" $$(ping -c 1 "${targethostname}" 2>&1 | sed -n '/bytes from/ s,.*(\([^)]*\)).*,\1, p')
clean:
rm -f *.piling.tar
for i in ???????.piling/proc; do sudo rm -Rf "./$$(dirname $$i)"; done
Last updated: 2017-11-02
wharfie: ./trunk/wharfie/examples/CODESYS/Wharfile
Bash
bash
(Bash)
#
# This is an example of a Wharfie image
# with CODESYS.
#
FROM debian_armel_stretch
TO raspberrypi.tar
#
# Base System
#
# Update the system and install desired tools
RUN apt-get update; \
apt-get install -y --no-install-recommends systemd-sysv openssh-server net-tools wireless-tools kmod wpasupplicant dhcpcd5
# Add user 'wharfie' with password 'wharfie' for interactive login
RUN useradd -ms /bin/bash wharfie; \
echo "wharfie:wharfie" | chpasswd; \
echo "root:root" | chpasswd;
# Add fstab
ADD ../common/files/fstab /etc/fstab
# Change Hostname
RUN HOST [ -f /usr/share/dict/words ] && printf "Wharfie-%s" $(grep '^[A-Z]' /usr/share/dict/words | sed -n "$(expr ${RANDOM} % $(grep '^[A-Z]' /usr/share/dict/words | wc -l))p" | sed "s,'.*,,") > etc/hostname
#
# Wireless + SSH
#
# Add files for wireless network configuration
ADD ../common/files/wpa_supplicant.conf /etc/wpa_supplicant/wpa_supplicant-wlan0.conf
ADD ../common/files/wireless.conf /etc/modules-load.d/wireless.conf
RUN sed -i 's,^Requires,#Requires,' /lib/systemd/system/wpa_supplicant@.service; \
systemctl enable wpa_supplicant@wlan0.service
#
# Add CODESYS package
#
# download package and extract it
RUN HOST \
[ ! -f ../../common/files/codesys.package ] && wget --output-document=../../common/files/codesys.package 'https://store.codesys.com/ftp_download/3S/RaspberryPI_SL/603001/3.5.11.20/CODESYS%20Control%20for%20Raspberry%20PI%203.5.11.20.package' || true; \
[ ! -f ../../common/files/codesys.deb ] && unzip -p ../../common/files/codesys.package '*.deb' > ../../common/files/codesys.deb || true; \
cp ../../common/files/codesys.deb tmp/codesys.deb
# install
RUN dpkg -i /tmp/codesys.deb
# workaround for using binaries, built for Raspbian on an a plain Debian
RUN HOST \
[ ! -f ../../common/files/rasbpian_libc6.deb ] && wget --output-document=../../common/files/rasbpian_libc6.deb 'https://archive.raspbian.org/raspbian/pool/main/g/glibc/libc6_2.19-18%2bdeb8u10_armhf.deb' || true; \
[ ! -f ../../common/files/rasbpian_libgcc.deb ] && wget --output-document=../../common/files/rasbpian_libgcc.deb 'https://archive.raspbian.org/raspbian/pool/main/g/gcc-6/libgcc1_6.3.0-18%2brpi1_armhf.deb' || true; \
ar p ../../common/files/rasbpian_libc6.deb data.tar.gz | (cd opt/codesys/; tar -xzf - ./lib/arm-linux-gnueabihf/); \
ar p ../../common/files/rasbpian_libgcc.deb data.tar.xz | (cd opt/codesys/; tar -xJf - ./lib/arm-linux-gnueabihf/); \
mv opt/codesys/lib/arm-linux-gnueabihf/* opt/codesys/lib/; \
patchelf --set-interpreter /opt/codesys/lib/ld-linux-armhf.so.3 opt/codesys/bin/codesyscontrol.bin;
#
# Legal stuff
#
# Opational packages, which are containing
# legal stuff and a toolchain to do cross builds.
#SOURCE sources.tar
#LICENSE license.tar
#TOOLCHAIN toolchain.tar
#
# Bootstrategy: Raspberry PI
#
RUN HOST \
../../bootstrategy/raspberrypi.sh rpi.img
Last updated: 2018-01-10
wharfie: ./trunk/wharfie/examples/RaspiRT/Wharfile
Bash
bash
(Bash)
#
# This is an example of a Wharfie image
# with CODESYS.
#
FROM debian_armhf_stretch
#
# Base System
#
# Update the system and install desired tools
RUN apt-get update; \
apt-get install -y --no-install-recommends systemd-sysv openssh-server net-tools wireless-tools kmod wpasupplicant dhcpcd5 git build-essential bison flex bc libssl-dev ca-certificates wget quilt
# Add user 'wharfie' with password 'wharfie' for interactive login
RUN useradd -ms /bin/bash wharfie; \
echo "wharfie:wharfie" | chpasswd; \
echo "root:root" | chpasswd;
# Add fstab
ADD ../common/files/fstab /etc/fstab
# Change Hostname
RUN HOST [ -f /usr/share/dict/words ] && printf "Wharfie-%s" $(grep '^[A-Z]' /usr/share/dict/words | sed -n "$(expr ${RANDOM} % $(grep '^[A-Z]' /usr/share/dict/words | wc -l))p" | sed "s,'.*,,") > etc/hostname
#
# Compile an RT-Preempt Kernel
#
RUN wget --output-document=/usr/src/osadl.sh https://www.osadl.org/monitoring/showpatchscript.php?veryshorthost=r7s3s; \
cd /usr/src; \
chmod 755 osadl.sh; \
./osadl.sh;
RUN cd /usr/src/linux-*-rt*; \
export KERNEL=kernel7; \
yes | make oldconfig; \
make -j 9 && \
make -j 9 modules && \
make modules_install && \
make -j 9 zImage && \
RUN cd /usr/src/linux-*-rt*; \
export KERNEL=kernel7; \
release=$(cut -d" " -f3 include/generated/utsrelease.h | tr -d '"') && \
mkdir -p /boot-rt/ && \
cp arch/arm/boot/zImage /boot-rt/zImage-$release && \
cp arch/arm/boot/zImage /boot-rt/$KERNEL.img && \
cp arch/arm/boot/dts/bcm*.dtb /boot-rt && \
du -shx /usr/src && \
cd .. && \
tar -czf linux-rt-sources.tar.gz linux-*-rt* && \
rm -rf linux-*-rt* && \
du -shx /usr/src
RUN apt-get install -y --no-install-recommends unzip
RUN [ ! -f boot.zip ] && wget --output-document=boot.zip 'https://github.com/raspberrypi/firmware/archive/master.zip' || true; \
unzip boot.zip && \
rm -Rf boot/* && \
mv firmware-master/boot/* boot/ && \
mv /boot-rt/* /boot/ && \
rmdir /boot-rt && \
rm -rf firmware-master;
ADD config.txt /boot/config.txt
ADD cmdline.txt /boot/cmdline.txt
#
# Legal stuff
#
# Opational packages, which are containing
# legal stuff and a toolchain to do cross builds.
SOURCE sources.tar
LICENSE license.tar
TOOLCHAIN toolchain.tar
#
# Bootstrategy: Raspberry PI
#
RUN HOST \
../../bootstrategy/raspberrypi.sh rpi.img
Last updated: 2020-01-16
wharfie: ./trunk/wharfie/examples/PyLoad/Wharfile
Bash
bash
(Bash)
#
# This is an example of a Wharfie image
# with pyload. It is derived from the
# docker container writl/pyload
#
FROM debian_armel_stretch
TO raspberrypi.tar
RUN sed -i 's,main,main non-free,' /etc/apt/sources.list
RUN apt-get update && apt-get install -y --no-install-recommends \
systemd-sysv \
dhcpcd5 \
wpasupplicant \
kmod \
wireless-tools \
net-tools \
openssh-server \
python \
locales \
python-setuptools \
python-requests \
python-pycurl \
python-crypto \
python-imaging \
python-pyxmpp \
python-jinja2 \
python-thrift \
python-feedparser \
python-beautifulsoup \
python-pip \
tesseract-ocr \
python-beaker \
unrar \
gocr \
python-django \
git \
rhino \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* \
&& pip install Send2Trash
# Set the locale
RUN locale-gen en_US.UTF-8
RUN git clone https://github.com/pyload/pyload.git /opt/pyload \
&& cd /opt/pyload \
&& git checkout stable \
&& echo "/opt/pyload/pyload-config" > /opt/pyload/module/config/configdir
ADD pyload-config/ /opt/pyload/pyload-config
ADD ../common/files/pyload.service /etc/systemd/system/pyload.service
# Add user 'wharfie' with password 'wharfie' for interactive login
RUN useradd -ms /bin/bash wharfie; echo "wharfie:wharfie" | chpasswd; echo "root:root" | chpasswd;
# Add fstab
ADD ../common/files/fstab /etc/fstab
# Change Hostname
RUN HOST [ -f /usr/share/dict/words ] && printf "Wharfie-%s" $(grep '^[A-Z]' /usr/share/dict/words | sed -n "$(expr ${RANDOM} % $(grep '^[A-Z]' /usr/share/dict/words | wc -l))p" | sed "s,'.*,,") > etc/hostname
#
# Wireless
#
# Add files for wireless network configuration
ADD ../common/files/wpa_supplicant.conf /etc/wpa_supplicant/wpa_supplicant-wlan0.conf
ADD ../common/files/wireless.conf /etc/modules-load.d/wireless.conf
RUN sed -i 's,^Requires,#Requires,' /lib/systemd/system/wpa_supplicant@.service; \
systemctl enable wpa_supplicant@wlan0.service; \
systemctl enable pyload.service;
#
# Bootstrategy: Raspberry PI
#
RUN HOST \
../../bootstrategy/raspberrypi.sh rpi.img
Last updated: 2017-10-22
wharfie: ./trunk/wharfie/examples/RaspiRT/config.txt
Bash
bash
(Bash)
# For more options and information see
# http://rpf.io/configtxt
# Some settings may impact device functionality. See link above for details
# uncomment if you get no picture on HDMI for a default "safe" mode
#hdmi_safe=1
# uncomment this if your display has a black border of unused pixels visible
# and your display can output without overscan
#disable_overscan=1
# uncomment the following to adjust overscan. Use positive numbers if console
# goes off screen, and negative if there is too much border
#overscan_left=16
#overscan_right=16
#overscan_top=16
#overscan_bottom=16
# uncomment to force a console size. By default it will be display's size minus
# overscan.
#framebuffer_width=1280
#framebuffer_height=720
# uncomment if hdmi display is not detected and composite is being output
#hdmi_force_hotplug=1
# uncomment to force a specific HDMI mode (this will force VGA)
#hdmi_group=1
#hdmi_mode=1
# uncomment to force a HDMI mode rather than DVI. This can make audio work in
# DMT (computer monitor) modes
#hdmi_drive=2
# uncomment to increase signal to HDMI, if you have interference, blanking, or
# no display
#config_hdmi_boost=4
# uncomment for composite PAL
#sdtv_mode=2
#uncomment to overclock the arm. 700 MHz is the default.
#arm_freq=800
# Uncomment some or all of these to enable the optional hardware interfaces
dtparam=i2c_arm=on
#dtparam=i2s=on
dtparam=spi=on
# Uncomment this to enable the lirc-rpi module
#dtoverlay=lirc-rpi
# Additional overlays and parameters are documented /boot/overlays/README
# Enable audio (loads snd_bcm2835)
dtparam=audio=on
Last updated: 2020-01-16
wharfie: ./trunk/wharfie/examples/Raspi64/Wharfile
Bash
bash
(Bash)
#
# This is an example of a Wharfie image
# with CODESYS.
#
FROM debian_arm64_stretch
#
# Base System
#
# Update the system and install desired tools
RUN apt-get update; \
apt-get install -y --no-install-recommends systemd-sysv openssh-server net-tools kmod dhcpcd5
# Add user 'wharfie' with password 'wharfie' for interactive login
RUN useradd -ms /bin/bash wharfie; \
echo "wharfie:wharfie" | chpasswd; \
echo "root:root" | chpasswd;
# Add fstab
ADD ../common/files/fstab /etc/fstab
# Change Hostname
RUN HOST [ -f /usr/share/dict/words ] && printf "Wharfie-%s" $(grep '^[A-Z]' /usr/share/dict/words | sed -n "$(expr ${RANDOM} % $(grep '^[A-Z]' /usr/share/dict/words | wc -l))p" | sed "s,'.*,,") > etc/hostname
#
# Legal stuff
#
# Opational packages, which are containing
# legal stuff and a toolchain to do cross builds.
SOURCE sources.tar
LICENSE license.tar
TOOLCHAIN toolchain.tar
#
# Bootstrategy: Raspberry PI
#
#RUN HOST \
# ../../bootstrategy/raspberrypi64.sh rpi.img
Last updated: 2018-09-03
wharfie: ./trunk/wharfie/examples/RaspiRT/cmdline.txt
Bash
bash
(Bash)
dwc_otg.lpm_enable=0 console=serial0,115200 console=tty1 root=PARTUUID=ee25660b-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait
Last updated: 2020-01-16
wharfie: ./branches/ticket#1/wharfie/install.sh
Bash
bash
(Bash)
#!/bin/sh
PREFIX=/usr/local/
cp wharfie.py ${PREFIX}/bin/wharfie
mkdir -p ${PREFIX}/share/wharfie/
cp wharfie.mk ${PREFIX}/share/wharfie/wharfie.mk
Last updated: 2017-10-22
wharfie: ./trunk/wharfie/examples/bootstrategy/raspberrypi.sh
Bash
bash
(Bash)
#!/bin/bash
#
# Copy root filesystem into an existing raspberry pi image.
# We take over the kernel modules and firmware files from
# the existing image, as those are tightly belonging to
# the kernel of this image.
#
# Note1: that we also change the uuids of the disks during this step.
#
# Note2: This way the bootloader and kernel from the existing
# image is used.
#
# Note3: We intentionally don't use the result of mktemp
# directly to reduce the risk of damaging the host filesystem.
#
set -xv
output="$1"
[ "x${output}" == "x" ] && output="raspbian.img"
# download image
[ ! -f ../raspbian.zip ] && (wget --output-document=../raspbian.zip 'https://downloads.raspberrypi.org/raspbian_lite_latest') || true
unzip -p ../raspbian.zip > ../${output}
# copy filesystem and change uuids
d=$(basename $(mktemp -d));
f=$(basename $(mktemp /tmp/XXXXXXXXXX.tar));
l=$(sudo /sbin/kpartx -l ../${output} | sed -n '/loop/ s,.*/dev/\(loop[0-9]\+\).*,\1, p;q;');
echo "tmpdir: ${d}"
echo "loopbackdevice: ${l}"
[ "x${d}" != "x" ] &&
sudo /sbin/kpartx -a ../${output} &&
sleep 2 &&
ls /dev/mapper &&
sudo mount /dev/mapper/${l}p2 "/tmp/${d}" &&
sed -i "s,PARTUUID=[^ ]*\(.*vfat\),PARTUUID=$(sudo /sbin/blkid /dev/mapper/${l}p1 -s PARTUUID -o value)\1," etc/fstab &&
sed -i "s,PARTUUID=[^ ]*\(.*ext4\),PARTUUID=$(sudo /sbin/blkid /dev/mapper/${l}p2 -s PARTUUID -o value)\1," etc/fstab &&
(cd "/tmp/${d}"; sudo tar -cf "/tmp/${f}" {lib/firmware,lib/modules,dev}) &&
sudo rm -Rf "/tmp/${d}/*" &&
sudo tar -cf - . | (cd "/tmp/${d}/"; sudo tar -xf -) &&
(cd "/tmp/${d}"; sudo tar -xf "/tmp/${f}") &&
sudo umount "/tmp/${d}" &&
sudo /sbin/kpartx -d ../${output} &&
rmdir "/tmp/${d}";
rm "/tmp/${f}"
# modify command line in boot partition, and mv boot files
d=$(basename $(mktemp -d));
l=$(sudo /sbin/kpartx -l ../${output} | sed -n '/loop/ s,.*/dev/\(loop[0-9]\+\).*,\1, p;q;');
[ "x${d}" != "x" ] &&
sudo /sbin/kpartx -a ../${output} &&
sleep 2 &&
sudo mount /dev/mapper/${l}p1 "/tmp/${d}" &&
[ -f boot/kernel7.img ] && (
rm -rf "/tmp/${d}/*";
(cd boot; sudo tar -cf - .) | (cd "/tmp/${d}/"; sudo tar -xf -)
) || true &&
sed -i 's| init=/usr/lib/raspi-config/init_resize.sh||' "/tmp/${d}/cmdline.txt" &&
sed -i 's| quiet||' "/tmp/${d}/cmdline.txt" &&
sed -i "s|PARTUUID=[^ ]*|PARTUUID=$(sudo /sbin/blkid /dev/mapper/${l}p2 -s PARTUUID -o value)|" "/tmp/${d}/cmdline.txt" &&
sed -i 's|#\(dtparam=spi\)|\1|' "/tmp/${d}/config.txt" &&
sed -i 's|#\(dtparam=i2c\)|\1|' "/tmp/${d}/config.txt" &&
sudo umount "/tmp/${d}" &&
sudo /sbin/kpartx -d ../${output} &&
rmdir "/tmp/${d}"
Last updated: 2018-12-26
wharfie: ./trunk/wharfie/examples/bootstrategy/raspberrypi64.sh
Bash
bash
(Bash)
#!/bin/bash
#
# Copy root filesystem into an existing raspberry pi image.
# We take over the kernel modules and firmware files from
# the existing image, as those are tightly belonging to
# the kernel of this image.
#
# Note1: that we also change the uuids of the disks during this step.
#
# Note2: This way the bootloader and kernel from the existing
# image is used.
#
# Note3: We intentionally don't use the result of mktemp
# directly to reduce the risk of damaging the host filesystem.
#
set -xv
output="$1"
[ "x${output}" == "x" ] && output="raspbian.img"
# download image
[ ! -f ../${output} ] && (wget --output-document=../raspbian.img.xz 'http://www.tom-yam.or.jp/rpi3/rpi3-arm64-debian-20160414.img.xz' && xzcat ../raspbian.img.xz > ../${output}) || true
# copy filesystem and change uuids
d=$(basename $(mktemp -d));
f=$(basename $(mktemp /tmp/XXXXXXXXXX.tar));
l=$(sudo /sbin/kpartx -l ../${output} | sed -n '/loop/ s,.*/dev/\(loop[0-9]\+\).*,\1, p;q;');
echo "tmpdir: ${d}"
echo "loopbackdevice: ${l}"
[ "x${d}" != "x" ] &&
sudo /sbin/kpartx -a ../${output} &&
sleep 2 &&
ls /dev/mapper &&
sudo mount /dev/mapper/${l}p2 /tmp/${d} &&
sed -i "s,PARTUUID=[^ ]*\(.*vfat\),PARTUUID=$(sudo /sbin/blkid /dev/mapper/${l}p1 -s PARTUUID -o value)\1," etc/fstab &&
sed -i "s,PARTUUID=[^ ]*\(.*ext4\),PARTUUID=$(sudo /sbin/blkid /dev/mapper/${l}p2 -s PARTUUID -o value)\1," etc/fstab &&
(cd /tmp/${d}; sudo tar -cf /tmp/${f} {lib/modules,dev}) &&
sudo rm -Rf /tmp/${d}/* &&
sudo tar -cf - . | (cd /tmp/${d}/; sudo tar -xf -) &&
(cd /tmp/${d}; sudo tar -xf /tmp/${f}) &&
sudo umount /tmp/${d} &&
sudo /sbin/kpartx -d ../${output} &&
rmdir /tmp/${d};
rm /tmp/${f}
# modify command line in boot partition
d=$(basename $(mktemp -d));
l=$(sudo /sbin/kpartx -l ../${output} | sed -n '/loop/ s,.*/dev/\(loop[0-9]\+\).*,\1, p;q;');
[ "x${d}" != "x" ] &&
sudo /sbin/kpartx -a ../${output} &&
sleep 2 &&
sudo mount /dev/mapper/${l}p1 /tmp/${d} &&
#sed -i 's| init=/usr/lib/raspi-config/init_resize.sh||' /tmp/${d}/cmdline.txt &&
#sed -i 's| quiet||' /tmp/${d}/cmdline.txt &&
#sed -i 's|#\(dtparam=spi\)|\1|' /tmp/${d}/config.txt &&
#sed -i 's|#\(dtparam=i2c\)|\1|' /tmp/${d}/config.txt &&
sudo umount /tmp/${d} &&
sudo /sbin/kpartx -d ../${output} &&
rmdir /tmp/${d}
Last updated: 2018-09-03
wharfie: ./trunk/wharfie/examples/Tutorial/Wharfile
Bash
bash
(Bash)
FROM debian_armel_stretch
TO rpi.tar
RUN apt-get update && apt-get install -y -no-install-recommends systemd-sysv dhcpcd5 wpa_supplicant openssh
ADD ../common/files/fstab /etc/fstab
RUN useradd -ms /bin/bash wharfie; echo "wharfie:wharfie" | chpasswd; echo "root:root" | chpasswd;
ADD ../common/files/wpa_supplicant.conf /etc/wpa_supplicant/wpa_supplicant-wlan0.conf
ADD ../common/files/wireless.conf /etc/modules-load.d/wireless.conf
RUN sed -i 's,^Requires,#Requires,' /lib/systemd/system/wpa_supplicant@.service; \
systemctl enable wpa_supplicant@wlan0.service;
RUN HOST \
../../bootstrategy/raspberrypi.sh rpi.img
Last updated: 2017-10-22
wharfie: ./trunk/wharfie/examples/tests_add/Wharfile
Bash
bash
(Bash)
FROM test.tar
# Implicite Makerules
#
# They need to be overloaded
# Touch the c-file to make sure, that a rebuild will be tried
#
RUN HOST touch ../files/cfile.c
ADD files/cfile /cfile
# Directories
ADD files/dir /
# Tar archive
RUN HOST rm -f ../test
ADD files/test.tar /tar/
ADD files/test.tar.gz /tar/
ADD files/test.tar.bz2 /tar/
ADD https://www.google.de/?gfe_rd=cr&dcr=0&ei=1 /
RUN HOST touch ../test
TO output.tar
# Execute tests
RUN HOST tar -tf ../output.tar | grep cfile
RUN HOST tar -tf ../output.tar | grep dircontent
RUN HOST tar -tf ../output.tar | grep tar/tarcontent
RUN HOST tar -tf ../output.tar | grep tar/bz2content
RUN HOST tar -tf ../output.tar | grep tar/gzcontent
Last updated: 2017-11-21
wharfie: ./trunk/wharfie/examples/common/files/wpa_supplicant.conf.example
Bash
bash
(Bash)
# Datei wpa_supplicant.conf in der Boot-Partition
network={
ssid="<id>"
psk="<password>"
key_mgmt=WPA-PSK
}
Last updated: 2017-10-27
wharfie: ./trunk/wharfie/examples/tests_modules/Wharfile
Bash
bash
(Bash)
FROM debian_stretch
ENTRYPOINT ['/test1']
ENTRYPOINT ['/test2', 'arg2.1']
ENTRYPOINT ['/test3', 'arg3.1', 'arg3.2']
ENTRYPOINT ['/test4', 'I\'m brave']
ENTRYPOINT ['/test5', 'I say "escape"']
TO output.tar
Last updated: 2018-08-31
wharfie: ./trunk/wharfie/examples/common/files/pyload.service
Bash
bash
(Bash)
[Unit]
Description=pyload
[Service]
Type=simple
ExecStart=/opt/pyload/pyLoadCore.py
[Install]
WantedBy=multi-user.target
Last updated: 2017-10-22
wharfie: ./trunk/wharfie/examples/common/files/fstab
Bash
bash
(Bash)
proc /proc proc defaults 0 0
#PARTUUID=11eccc69-01 /boot vfat defaults 0 2
PARTUUID=11eccc69-02 / ext4 defaults,noatime 0 1
Last updated: 2017-10-22
wharfie: ./trunk/wharfie/examples/common/files/wireless.conf
Bash
bash
(Bash)
brcmfmac
brcmutil
Last updated: 2017-10-22
wharfie: ./trunk/wharfie/lib/files.py
Bash
bash
(Bash)
#!/usr/bin/python
#
# Copyright 2017 Ingo Hornberger <ingo_@gmx.net>
#
# This software is licensed under the MIT License
#
# Permission is hereby granted, free of charge, to any person obtaining a copy of this
# software and associated documentation files (the "Software"), to deal in the Software
# without restriction, including without limitation the rights to use, copy, modify,
# merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to the following
# conditions:
#
# The above copyright notice and this permission notice shall be included in all copies
# or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
# INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
# PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
# OR OTHER DEALINGS IN THE SOFTWARE.
#
################################################################################
#
# We want to allow the same features in most every actions. Like download
# links for input files in FROM, ADD, COPY, ...
# If an archive is found, which contains only one file, it will be recursively
# extracted.
#
# Or support several archive formats, like *.img, *.a, *.tar, *.tar.gz
#
# This library is implementing those generic access functions.
#
# Note that we are trying to be as compatible as necessary (not as possible ;) )
# to the Dockerfile format. But we will try to avoid the faults, docker did.
#
# So this is a list of planned deviations from Dockerfile:
#
# Issue 1)
# - ADD supports URLs and archives. But docker doesn't support these two in
# combination. We will do.
#
# - ADD is able to extract an archive. But you can't just extract a part of
# it.
#
# => These two limitations are leading people to not use ADD, but use curl + tar
# + s.th. else inside of the docker container instead. Which is bad
# practice.
#
# Solution 1)
#
# - Archive extract and URLs can be combined
# - Every URL can have "options", which are seperated by a pipe. These options
# are containing the files, partitions, etc. which the user want's to extract.
# e.g.:
# ADD http://mypage.com/files/myrootfs.tar|tar=./etc/fstab|tar=./etc/passwd /
#
# It's keen to want everything to use the same infrastructure and therefore
# support the same features. But anyway we have to maintain the following
# differences between API functions...
#
# Issue 2)
# - FROM extracts everything, except tar* archives
# - ADD extracts everything, except tar* archives (as tar archives are extracted
# while handling the output, not while handling the input)
# - COPY extracts nothing
# - Anyway, all of them support downloads
#
# Solution 2)
# - we add a parameter to input_file, which specifies an optional parameter to
# enable extracting of everything supported, except tar archives.
# Note, that we can only support extraction of archives, that contain only one
# file (at least after applying its options). Otherwhise we don't get a simple
# data flow.
#
# Issue 3)
# - Whe extracting over a few indirections, we can't predict which format will
# come out in the end. So it is nearly impossible to define a good name for
# the build target. But, as the name of the build target also has to contain
# the exact file format, we will have to specify the output format in such
# cases.
#
# Solution 3)
# - The output format is one of the options, which has to be passed to the
# command when we want to trigger the whole extraction chain.
# e.g.:
# FROM https://downloads.raspberrypi.org/raspbian_lite_latest|img=p1|format=tar
#
# In this example, the exact chain is:
# raspbian_lite_latest -> *.zip -> *.img -> *.tar
#
# The image rule has the effect, that partition 1 is packed into a tar archive.
# This is always the rule, to "extract" an image. If you want, you can then
# continue extracting this to other formats.
#
################################################################################
import os
import urllib
import binascii
from lib import makefile as make
archive_formats = ["zip", "a", "img"]
def split_escape(string, delimiter):
if len(delimiter) != 1:
raise ValueError('Invalid delimiter: ' + delimiter)
ln = len(string)
i = 0
j = 0
while j < ln:
if string[j] == '\\':
if j + 1 >= ln:
yield string[i:j]
return
j += 1
elif string[j] == delimiter:
yield string[i:j]
i = j + 1
j += 1
yield string[i:j]
def execute(command):
process = Popen(
args=command,
stdout=PIPE,
shell=True
)
return process.communicate()[0]
def download(url):
# check redirection to get the correct file extension
fileh = urllib.urlopen(url)
redir = fileh.geturl()
if redir != '':
url = redir
name, ext = os.path.splitext(url)
name = format(0xFFFFFFFF & binascii.crc32(url), '02X') + ext
cmd = "wget --continue --output-document=$@ '%s'" % (url)
makeTarget = {
'comment' : "download %s" % (url),
'name': name,
'dep': '',
'simplecmd': cmd
};
make.makeTargets.append(makeTarget);
#os.system(cmd)
return name
def extract(url, options):
if "format" not in options:
print ("error: format not specified for url, which should be extracted")
print ("url: %s" % url)
return url
ext = options["format"]
name = format(0xFFFFFFFF & binascii.crc32(url), '02X') + "." + ext
o_zip = ""
o_a = ""
o_img = ""
if "zip" in options:
o_zip = options["zip"]
if "a" in options:
o_a = options["a"]
if "img" in options:
o_img = options["img"]
cmd='''filename="$<"; \\
format="tar"; \\
output="$@"; \\
while true; do \\
extension="$${filename##*.}"; \\
if [ "x$${extension}" = "x$${format}" ]; then \\
echo "info: extraction chain successful, output format found."; \\
mv $${filename} $${output}; \\
break; \\
fi; \\
case $${extension} in \\
zip) \\
options="%s"; \\
n=$$(zipinfo -1 $${filename} $${options}| wc -l); \\
if [ "$${n}" = "1" ]; then \\
f=$$(zipinfo -1 $${options} $${filename}); \\
unzip -p $${filename} $${options} > $${f}; \\
filename=$${f}; \\
fi; \\
;; \\
a) \\
options="%s"; \\
n=$$(ar t $${filename} $${options}| wc -l); \\
if [ "$${n}" = "1" ]; then \\
f=$(ar t $${filename} $${options}); \\
ar x $${filename} $${options}; \\
filename=$${f}; \\
fi; \\
;; \\
img) \\
options="%s"; \\
d=$$(basename $$(mktemp -d)); \\
l=$$(sudo kpartx -l $${filename} | sed -n '/loop/ s,.*/dev/\\(loop[0-9]\\+\\).*,\\1, p;q;'); \\
echo sed -n '/loop/ s,.*/dev/\\\\(loop[0-9]\\\\+\\\\).*,\\\\1, pq;'; \\
if [ "x$${d}" != "x" -a "x$${l}" != "x" ]; then \\
f="$${filename}.tar"; \\
sudo kpartx -as $${filename}; \\
sudo mount /dev/mapper/$${l}$${options} /tmp/$${d}; \\
(cd /tmp/$${d}; sudo tar -cf - .) > $${f}; \\
sudo umount /tmp/$${d}; \\
sudo kpartx -d $${filename}; \\
rmdir /tmp/$${d}; \\
filename=$${f}; \\
else \\
echo "internal error: kpartx returned false or problem with tempdir occured"; \\
break; \\
fi; \\
;; \\
*) \\
echo "error: stopping extracting on $${filename} with ext $${extension}"; \\
break; \\
;; \\
esac; \\
done''' % (o_zip, o_a, o_img)
makeTarget = {
'comment' : "extract %s (options: %s)" % (url, options),
'name': name,
'dep': [url],
'simplecmd': cmd
};
make.makeTargets.append(makeTarget);
return name
def input_file(url):
parts = list(split_escape(url, "|"))
url = parts[0].lstrip()
options = dict()
if len(parts) > 1:
for p in parts[1:]:
o = p.split("=")
key = o[0]
o = "=".join(o[1:])
if key in options:
options[key] += " " + o
else:
options[key] = o
# need to download?
if url.startswith("http://") or url.startswith("https://") or url.startswith("ftp://"):
name = download(url)
else:
name = url
# Extract files if it is an archive.
parts = os.path.splitext(name)
ext = parts[1][1:]
if ext in archive_formats:
name = extract(name, options)
return name
Last updated: 2017-11-19
wharfie: ./trunk/wharfie/lib/makefile.py
Bash
bash
(Bash)
#!/usr/bin/python
#
# Copyright 2017 Ingo Hornberger <ingo_@gmx.net>
#
# This software is licensed under the MIT License
#
# Permission is hereby granted, free of charge, to any person obtaining a copy of this
# software and associated documentation files (the "Software"), to deal in the Software
# without restriction, including without limitation the rights to use, copy, modify,
# merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to the following
# conditions:
#
# The above copyright notice and this permission notice shall be included in all copies
# or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
# INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
# PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
# OR OTHER DEALINGS IN THE SOFTWARE.
#
################################################################################
# We use templates, which are checking their execution context,
# to be sure, that target commands are really only executed
# in the change root of the image.
#
# We use snar files to create incremental archives. Those files are targeted
# to incremental backups, where the filestructure stays roughly the same. So
# beside the name and timestamps of the files, it also relies on inodes.
#
# As we are packing and extracting the images for every step, the inodes are
# constantly changing. As tar doesn't support to ignore inodes on incremental
# backups, we are refreshing the backups in every step.
#
# input snar output snar output tar
# level 0: <none> l0.snar l0.tar
# level 1: l0.snar l1.snar l1.tar
# level 2: l1.snar l2.snar l2.tar
#
# When we prepare the rootfs for level 2, we have to do the following:
#
# - tar -xf l0.tar -g l0.snar
#
# - tar -xf l1.tar -g l1.snar
# - cp l0.snar l1.snar
# - tar -cf /dev/zero -g l1.snar .
#
# - tar -xf l2.tar -g l2.snar
# - cp l1.snar l2.snar
# - tar -cf /dev/zero -g l2.snar .
#
#################################################################################
templateTrgCmd = "#!/bin/bash\n[ -f ../Wharfile ] && exit 2;\n%s\nexit \$$?\n"
templateHostCmd = "#!/bin/bash\n[ ! -f ../Wharfile ] && exit 2;\n%s\nexit \$$?\n"
makeTargets = list();
environment = list();
finalTarget = list();
#
# Write a Makefile
#
def write_makefile(filename, dry_run, installpath='.', incremental=False, proc=True):
backup_levels=list()
f = open(filename, 'w');
# write header
f.write("ifneq (${VERBOSE},y)\n")
f.write("Q=@\n")
f.write("endif\n")
f.write("\n")
f.write("OUTPUT_FILE=%s\n" % (finalTarget[0]))
f.write("\n")
f.write("all: %s\n\n" % (finalTarget[0]));
# write all environment variables
for env in environment:
l = env.lstrip().split(" ")
f.write("export %s=%s\n" % (l[0], " ".join(l[1:])));
# write all targets
for target in makeTargets:
postpath = ''
if 'comment' in target:
f.write("# %s\n" % target['comment']);
if 'trgcmd' in target or 'hostcmd' in target or 'temporary' in target:
# independent of if the command was successful or not, we cleanup the directory
# - killall processes running inside
# - umount proc, if necessary
# - delete the directory
cleanup_commands="${SUDO} fuser -k ./rootfs.piling;" \
"[ -d ./rootfs.piling/proc ] && ${SUDO} umount ./rootfs.piling/proc;" \
"${SUDO} rm -Rf ./rootfs.piling";
f.write("%s: %s\n" % (target['name'], " ".join(target['dep'])));
f.write("\t${Q}-mkdir rootfs.piling\n");
f.write("\t${Q}${MAKE} %s_sub || (%s; false)\n" % (target['name'], cleanup_commands));
f.write("\t${Q}-%s\n" % cleanup_commands);
# don't add any dependencies to a subtarget. Resolving them in the sub-process would lead
# to really unexpected effects. The sub-target is just called, that we can tidy things up
# well in the main build target.
f.write("\n");
f.write(".PHONY: %s_sub\n" % (target['name']));
f.write("%s_sub:\n" % (target['name']));
# target and host commands have to extract and repack always.
# simple commands don't do that.
f.write("\t${Q}${SUDO} rm -f .trg.sh .hst.sh\n");
if 'trgcmd' in target:
cmd = templateTrgCmd % (target['trgcmd'].replace('$', '\\$$').replace('"', '\\"'));
f.write("\t${Q}echo '******************************'\n");
f.write("\t${Q}echo '%s: %s'\n" % (target['name'], target['comment']));
f.write("\t${Q}echo '******************************'\n");
f.write("\t${Q}(echo -e \"%s\") | ${SUDO} tee .trg.sh\n" % cmd.replace('\\n', '\\\\\\n').replace('\n', '\\n').replace('!', '"\'!\'"'));
f.write("\t${Q}${SUDO} chmod a+x .trg.sh\n");
if 'trgcmdpost' in target:
cmd = templateTrgCmd % (target['trgcmdpost'].replace('$', '\\$$').replace('"', '\\"'));
f.write("\t${Q}echo '******************************'\n");
f.write("\t${Q}echo '%s: %s'\n" % (target['name'], target['comment']));
f.write("\t${Q}echo '******************************'\n");
f.write("\t${Q}(echo -e \"%s\") | ${SUDO} tee .trg-post.sh\n" % cmd.replace('\\n', '\\\\\\n').replace('\n', '\\n').replace('!', '"\'!\'"'));
f.write("\t${Q}${SUDO} chmod a+x .trg-post.sh\n");
if 'trgcmdpostpath' in target:
postpath = target['trgcmdpostpath']
if 'hostcmd' in target:
cmd = templateHostCmd % (target['hostcmd'].replace('$', '\\$$').replace('"', '\\"'));
f.write("\t${Q}echo '******************************'\n");
f.write("\t${Q}echo '%s: %s'\n" % (target['name'], target['comment']));
f.write("\t${Q}echo '******************************'\n");
f.write("\t${Q}(echo -e \"%s\") | ${SUDO} tee .hst.sh\n" % cmd.replace('\\n', '\\\\\\\\n').replace('\n', '\\n').replace('!', '"\'!\'"'));
f.write("\t${Q}${SUDO} chmod a+x .hst.sh\n");
if 'hostcmdpost' in target:
cmd = templateHostCmd % (target['hostcmdpost'].replace('$', '\\$$').replace('"', '\\"'));
f.write("\t${Q}echo '******************************'\n");
f.write("\t${Q}echo '%s: %s'\n" % (target['name'], target['comment']));
f.write("\t${Q}echo '******************************'\n");
f.write("\t${Q}(echo -e \"%s\") | ${SUDO} tee .hst-post.sh\n" % cmd.replace('\\n', '\\\\\\\\n').replace('\n', '\\n').replace('!', '"\'!\'"'));
f.write("\t${Q}${SUDO} chmod a+x .hst-post.sh\n");
# start command here ...
f.write("\t${Q}${SUDO} bash -c \"");
# extracting from multiple backup levels
backup_levels.append(target["dep"][0])
f.write("cd rootfs.piling;")
lastincrement = None
for increment in backup_levels[-1:]:
if lastincrement == None:
# level-0 backup
f.write("[ -f ../%s.snar ]" % increment);
f.write(" && tar -g ../%s.snar -xf ../%s" % (increment, increment));
f.write(" || tar -xf ../%s;" % increment);
else:
# level-x backup, update snar after extract
f.write("tar -g ../%s.snar -xf ../%s;" % (increment, increment));
lastincrement = increment
if not dry_run:
# mount proc here if such a folder exists. it is umounted after this command or
# in the cleanup actions
# - target
if proc:
f.write("if [ -d proc ]; then mount -t proc proc proc; fi;");
f.write("if [ -f ../.trg.sh ]; then mv ../.trg.sh .; chroot . ./.trg.sh || exit 1; fi; rm -f ./.trg.sh;");
if proc:
f.write("if [ -d proc ]; then umount proc || umount -l proc; fi;");
# - host
f.write("if [ -f ../.hst.sh ]; then ../.hst.sh || exit 1; fi; rm -f ../.hst.sh;");
# - target post
if proc:
f.write("if [ -d proc ]; then mount -t proc proc proc; fi;");
f.write("if [ -f ../.trg-post.sh ]; then mv ../.trg-post.sh ./%s; chroot ./%s ./.trg-post.sh || exit 1; fi; rm -f ./.trg-post.sh;" % (postpath, postpath));
if proc:
f.write("if [ -d proc ]; then umount proc || umount -l proc; fi;");
# - host post
f.write("if [ -f ../.hst-post.sh ]; then ../.hst-post.sh || exit 1; fi; rm -f ../.hst-post.sh;");
# pack result
if not 'temporary' in target or not target['temporary']:
# copy over snar file from previous level and add changes to the new one
f.write("[ ! -f ../%s.snar ] || cp ../%s.snar ../%s.snar;" % (target['dep'][0], target['dep'][0], target['name']));
if incremental:
f.write("tar -g ../%s.snar -cf '../%s' .;" % (target['name'], target['name']));
else:
if not 'temporary' in target or not target['temporary']:
f.write("tar -cf '../%s' .;" % target['name']);
f.write("\"\n");
# ... end command
if 'temporary' in target and target['temporary']:
f.write("\t[ ! -f %s ] || cp %s %s;" % (target['dep'][0], target['dep'][0], target['name']));
f.write("\t[ ! -f %s.snar ] || cp %s.snar %s.snar;\n" % (target['dep'][0], target['dep'][0], target['name']));
#
# end of target/host commands.
# we keep it open that those command types can still be combined
# with a simple command.
#
if 'simplecmd' in target:
f.write("%s: %s\n" % (target['name'], " ".join(target['dep'])));
# note, that a simple command has full control
# over make. it can contain references to the maketarget
# and to make variables. Therefore we don't replace anything
# in those commands (contrary to target-/host commands).
# Also verbose mode can't be supported, because we want to
# support multiline commands
for line in iter(target['simplecmd'].splitlines()):
f.write("\t%s\n" % line)
f.write("\n");
# write footer
f.write("WHARFIE_MK ?= %s/wharfie.mk\n" % installpath);
f.write("include ${WHARFIE_MK}\n");
f.write("\n");
Last updated: 2020-08-04
wharfie: ./trunk/wharfie/lib/actions.py
Bash
bash
(Bash)
#!/usr/bin/python
#
# Copyright 2017 Ingo Hornberger <ingo_@gmx.net>
#
# This software is licensed under the MIT License
#
# Permission is hereby granted, free of charge, to any person obtaining a copy of this
# software and associated documentation files (the "Software"), to deal in the Software
# without restriction, including without limitation the rights to use, copy, modify,
# merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to the following
# conditions:
#
# The above copyright notice and this permission notice shall be included in all copies
# or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
# INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
# PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
# OR OTHER DEALINGS IN THE SOFTWARE.
#
################################################################################
import re
from lib import makefile as make
from lib import files
g_cmdUnitCount = 0
g_workingDir = "/"
def run(name, dep, cmd):
makeTarget = {
'comment' : "%s %s" % (cmd[0], cmd[1]),
'name': name,
'dep': dep,
'trgcmd': cmd[1]
};
return makeTarget;
def run_host(name, dep, cmd):
makeTarget = {
'comment' : "%s %s" % (cmd[0], cmd[1]),
'name': name,
'dep': dep,
'hostcmd': cmd[1]
};
return makeTarget;
def copy(name, dep, cmd):
if " " not in cmd[1].lstrip():
print ("parse error: COPY needs two arguments. (%s)" % cmd[1].lstrip())
exit(1)
src,dst = cmd[1].lstrip().split(" ")
isUrl = src.startswith("http://") or src.startswith("https://") or src.startswith("ftp://")
src = files.input_file(src)
# Overwrite potential implicite make rules for file
if not isUrl:
make.makeTargets.append({'name': src, 'dep': '', 'simplecmd': 'touch $@'});
dep.append(src)
myHostCmd = '''
destdir="$(pwd)";
src="%s";
dst="%s";
cd ../;
case "${dst}" in
*/)
mkdir -p "${destdir}/${dst}";
;;
*)
mkdir -p $(dirname "${destdir}/${dst}");
;;
esac;
cp -R --preserve=mode ${src} "${destdir}/${dst}";
''' % (src, dst)
makeTarget = {
'comment' : "%s %s" % (cmd[0], cmd[1]),
'name': name,
'dep': dep,
'hostcmd': myHostCmd
};
return makeTarget;
def add(name, dep, cmd):
if " " not in cmd[1].lstrip():
print ("parse error: ADD needs two arguments. (%s)" % cmd[1].lstrip())
exit(1)
src,dst = cmd[1].lstrip().split(" ")
isUrl = src.startswith("http://") or src.startswith("https://") or src.startswith("ftp://")
src = files.input_file(src)
# Overwrite potential implicite make rules for file
if not isUrl:
make.makeTargets.append({'name': src, 'dep': '', 'simplecmd': 'touch $@'});
dep.append(src)
myHostCmd = '''
destdir="$(pwd)";
src="%s";
dst="%s";
cd ../;
case "${dst}" in
*/)
mkdir -p "${destdir}/${dst}";
;;
*)
mkdir -p $(dirname "${destdir}/${dst}");
;;
esac;
case "${src}" in
*.tar)
cat ${src} | (cd ${destdir}/${dst}; tar -xf -);
;;
*.tar.gz)
cat ${src} | (cd ${destdir}/${dst}; tar -xzf -);
;;
*.tar.bz2)
cat ${src} | (cd ${destdir}/${dst}; tar -xjf -);
;;
*)
cp -R --preserve=mode ${src} "${destdir}/${dst}";
;;
esac;
''' % (src, dst)
makeTarget = {
'comment' : "%s %s" % (cmd[0], cmd[1]),
'name': name,
'dep': dep,
'hostcmd': myHostCmd
};
return makeTarget;
def workingdir(name, dep, cmd):
global g_workingDir;
g_workingDir = cmd[1]
def entrypoint(name, dep, cmd):
global g_cmdUnitCount;
global g_workingDir;
args = eval(cmd[1])
unitCmd = "%s %s" % (cmd[0], " ".join(args).replace("'", "'\"'\"'"))
unitName = "wharfie%u.service" % g_cmdUnitCount
myTrgCmd = '''
echo '[Unit]\nDescription=Wharfie Unit\n\n[Service]\nType=simple\nWorkingDirectory=%s\nExecStart=%s\n\n[Install]\nWantedBy=multi-user.target\n' > /etc/systemd/system/%s;
systemctl enable %s;
''' % (g_workingDir, unitCmd, unitName, unitName)
makeTarget = {
'comment' : "%s %s" % (cmd[0], cmd[1]),
'name': name,
'dep': dep,
'trgcmd': myTrgCmd
};
g_cmdUnitCount = g_cmdUnitCount + 1;
return makeTarget;
def source(name, dep, cmd):
myTrgCmd = '''
mkdir /sources;
cd /sources;
apt-get update;
[ ! -f .pkg.list ] &&
dpkg-query -f \'${binary:Package}\\n\' -W > .pkg.list;
apt-get install -y dpkg-dev;
cat .pkg.list | xargs -n 1 apt-get source'''
myHostCmd = 'tar -cf ../' + cmd[1].lstrip() + ' sources;'
makeTarget = {
'comment' : "%s %s" % (cmd[0], cmd[1]),
'name': name,
'dep': dep,
'trgcmd': myTrgCmd,
'hostcmd': myHostCmd,
'temporary': True
};
return makeTarget;
def license(name, dep, cmd):
myTrgCmd = '''
mkdir /licenses;
for i in /usr/share/doc/*/;
do [ -f $i/copyright ] &&
cp $i/copyright licenses/$(basename $i).txt ||
echo $(basename $i) >> licenses/___MISSING___.txt;
done'''
myHostCmd = 'tar -cf ../' + cmd[1].lstrip() + ' licenses;'
makeTarget = {
'comment' : "%s %s" % (cmd[0], cmd[1]),
'name': name,
'dep': dep,
'trgcmd': myTrgCmd,
'hostcmd': myHostCmd,
'temporary': True
};
return makeTarget;
def toolchain(name, dep, cmd):
myTrgCmd = '''
(apt-get update; apt-get install -y libc6-dev;
[ -d ./usr/lib/arm-linux-gnueabi*/ ] &&
(cd ./usr/lib/arm-linux-gnueabi*/; ln -s crt1.o crt0.o) || true);'''
myTrgCmdPost = ''
myHostCmd = ''
myHostCmdPost = ''
if " " in cmd[1].lstrip():
params = re.findall('^([^ ]+)[ \t]([^\n]*)', cmd[1].lstrip(), flags=re.MULTILINE)
if len(params) > 0:
myTrgCmdPost = params[0][1]
myHostCmd = 'files=$(ls -1); mkdir target; mv ${files} target; mkdir host; (cd host; tar -xf ../../debian_toolchain.tar); cp ../debian_toolchain_env.sh env.sh;'
myHostCmdPost = 'tar -cf ../' + params[0][0] + ' .;'
else:
myHostCmd = 'files=$(ls -1); mkdir target; mv ${files} target; mkdir host; (cd host; tar -xf ../../debian_toolchain.tar); cp ../debian_toolchain_env.sh env.sh;'
myHostCmdPost = 'tar -cf ../' + cmd[1].lstrip() + ' .;'
dep.append('debian_toolchain.tar')
dep.append('debian_toolchain_env.sh')
makeTarget = {
'comment' : "%s %s" % (cmd[0], cmd[1]),
'name': name,
'dep': dep,
'trgcmd': myTrgCmd,
'trgcmdpost': myTrgCmdPost,
'trgcmdpostpath': 'host',
'hostcmd': myHostCmd,
'hostcmdpost': myHostCmdPost,
'temporary': True
};
return makeTarget;
def to(name, dep, cmd):
makeTarget = {
'comment' : "%s %s" % (cmd[0], cmd[1]),
'name': cmd[1].lstrip(),
'dep': dep,
'temporary': True
};
return makeTarget;
Last updated: 2020-08-04
wharfie: ./trunk/wharfie/qemu/Wharfile
Bash
bash
(Bash)
# Copyright 2018 Ingo Hornberger <ingo_@gmx.net>
#
# This software is licensed under the MIT License
#
# Permission is hereby granted, free of charge, to any person obtaining a copy of this
# software and associated documentation files (the "Software"), to deal in the Software
# without restriction, including without limitation the rights to use, copy, modify,
# merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to the following
# conditions:
#
# The above copyright notice and this permission notice shall be included in all copies
# or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
# INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
# PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
# OR OTHER DEALINGS IN THE SOFTWARE.
#
################################################################################
#
# This Wharfile builds a Qemu image which is able to build any Wharfile w/o
# special dependencies on the host. The goal is, that we can build on linux
# as an ordinary user (w/o root priviledges) and that we are at all able to
# build on windows.
#
# Why should one build an embedded root filesystem under windows?
#
# You should ask this question half of the Raspberry Pi users. They all want
# to build special images (With Game Emulators, as a NAS, as a media server, ...),
# but only few of them have a linux system at home to do this. So they are
# usually configuring everything live on their Pi. Which is fun, but:
# - messy
# - not reproducable
# - critical in legal terms
# - an anoying task when parts of the system need to be updated
#
################################################################################
FROM debian_amd64_jessie
RUN apt-get install -y sudo make binfmt-support qemu-user-static debootstrap kpartx tar bzip2 systemd-sysv net-tools isc-dhcp-client linux-image-amd64 wamerican psmisc
# Add user 'wharfie' with password 'wharfie' for interactive login
RUN useradd -ms /bin/bash wharfie; \
echo "wharfie:wharfie" | chpasswd; \
echo "root:root" | chpasswd;
ADD files/wharfie.service /etc/systemd/system/wharfie.service
ADD files/qemu_autorun.sh /usr/local/wharfie/qemu_autorun.sh
RUN systemctl enable wharfie.service; \
systemctl set-default multi-user.target;
RUN HOST cp -pR boot ../
RUN HOST ../qcow.sh ../qwharfie.qcow
Last updated: 2018-03-09
wharfie: ./trunk/wharfie/qemu/files/qemu_autorun.sh
Bash
bash
(Bash)
#!/bin/bash
#
# We are running inside of Qemu and use the block devices to
# exchange large amounts of files. Our build jobs are long-term
# jobs, so we just copy the whole data forth and back. While we
# are keeping timestamps and we keep old files inside of a cache
# partition.
#
# We expect the following layout of our block devices, as they
# are passed to Qemu at the command line:
#
# - sda: This is the root partition of the system (read-only for us)
# - sdb: This is also a real partition, which is used for caching
# - sdc: This is our input tar archive (no real partition, so it can't be mounted)
# - sdd: This is our output tar archive. Itself it might contain multiple archives.
#
# Note the drawback of this solution is, that we have maximum limits
# for input and output packets. But those limits can be fully influenced
# by the caller, why it seems acceptable anyway.
#
echo "#########################################################"
echo "# Wharfie started"
echo "#########################################################"
sleep 10;
echo "#########################################################"
# setup network
dhclient eth0
echo "#########################################################"
# enable binfmt for all supported architectures
update-binfmts --enable qemu-arm
update-binfmts --enable qemu-armeb
update-binfmts --enable qemu-ppc
echo "#########################################################"
# mount the cache folder to /build and change into it
[ ! -d /build ] && mkdir /build
mount /dev/sdb1 /build &&
cd /build &&
# untar the input into the build folder
tar -xpf /dev/sdc &&
# run make in the build folder
make WHARFIE_MK=wharfie.mk &&
# pack everything, except some fix excludes to output
tar --exclude='*.piling.tar' --exclude='debian_version.mk' --exclude='debian_toolchain.tar' --exclude='debian_toolchain_env.sh' -cf /dev/sdd .
# shut the VM down
sync
shutdown -P now
Last updated: 2018-03-09
wharfie: ./trunk/wharfie/package/DEBIAN/control
Bash
bash
(Bash)
Package: wharfie
Version: 0.1
Section: base
Maintainer: wharfie.debian@googlemail.com
Architecture: all
Multi-Arch: foreign
Depends: qemu-user-static, python3, debootstrap, kpartx
Description: Wharfie is a modern build system for
embedded devices. The concept is very similar to
"docker". Describe and build embedded Linux image,
based on Debian.
Last updated: 2020-02-07